raw input(WM_INPUT)消息如何模拟

不填海的精卫 2018-03-23 09:28:18
目前有一个应用是用rawinput处理鼠标键盘的,我想模拟WM_INPUT发送鼠标消息,但是一点反应都没有,请问是不是这个不支持跨进程发送,如果注入到目标进程呢?
...全文
1883 19 打赏 收藏 转发到动态 举报
写回复
用AI写文章
19 条回复
切换为时间正序
请发表友善的回复…
发表回复
赵4老师 2018-09-03
  • 打赏
  • 举报
回复
还是驱动一个机械手去按键盘和鼠标的按键并移动鼠标最靠谱。
yjryym 2018-09-01
  • 打赏
  • 举报
回复
WM_INPUT内部是通过 GetRawInputData 函数来读取的输入事件,所以你光靠 SendMessage 是没有任何卵用的。
yjryym 2018-09-01
  • 打赏
  • 举报
回复
同属user32.dll下的 mouse_event、keybd_event、SendInput,这三个API函数可以对RawInput和DirectInput进行模拟输入,但是是整个系统全局的,并不能对后台对某个窗口单独模拟。除非你注入dll到目标进程,HOOK掉 GetRawInputData 函数,这样目标进程才可以后台读取到假的数据。
schlafenhamster 2018-03-28
  • 打赏
  • 举报
回复
参考 VirtualFreeEx
schlafenhamster 2018-03-27
  • 打赏
  • 举报
回复
变量的 地址 不能 传到 另一个目标程序,所以 要 在 另一个目标程序 中 申请 一块 内存 即 (HRAWINPUT)lParam,把 内容 再 复制到 另一个目标程序 , 再 SendMessage
不填海的精卫 2018-03-27
  • 打赏
  • 举报
回复
引用 9 楼 schlafenhamster 的回复:
“直接SendMessage给另一个目标程序” 必须 在 另一个目标程序 中· 模拟一个 (HRAWINPUT)lParam
是这样的老哥, 另一个程序是兄弟公司用u3d做的三维场景,我们要对他做自动化测试, 通过注入挂钩得知,他内部对鼠标的处理是用raw input得到鼠标消息的,所以我们用SendMessage啥的是没有效果, 老哥我没太懂您的意思
schlafenhamster 2018-03-27
  • 打赏
  • 举报
回复
“直接SendMessage给另一个目标程序” 必须 在 另一个目标程序 中· 模拟一个 (HRAWINPUT)lParam
不填海的精卫 2018-03-27
  • 打赏
  • 举报
回复
引用 6 楼 schlafenhamster 的回复:
"我试过用这个构造的消息 给目标应用SendMessage不好用啊" 看看你的 代码
我的做法是 创意个对话框程序,然后自己注册了WM_INPUT,然后收到了消息后,直接SendMessage给另一个目标程序
不填海的精卫 2018-03-27
  • 打赏
  • 举报
回复
引用 13 楼 schlafenhamster 的回复:
参考

void CRemoteListCtrlDlg::RemoteHeaderItem(HWND hWnd)
{	
// GetItemCount
	int nHeaderCount=::SendMessage(hWnd,HDM_GETITEMCOUNT,0,0);
// Get hProcess
	DWORD pid;
	GetWindowThreadProcessId(hWnd,&pid);
	HANDLE hProcess=OpenProcess(PROCESS_ALL_ACCESS,FALSE,pid);
//
	HDITEM *pHeaderItem = (HDITEM*)VirtualAllocEx(hProcess, NULL, sizeof(HDITEM), MEM_COMMIT, PAGE_READWRITE);
	char   *pItem = (char*)VirtualAllocEx(hProcess, NULL, 80, MEM_COMMIT, PAGE_READWRITE);
	if ((!pHeaderItem) || (!pItem))
	{
		::MessageBox(NULL, "无法分配内存!", "错误!", NULL);
		CloseHandle(hProcess);
		return;
	}
//
	HDITEM HeaderItem;
	HeaderItem.cchTextMax = 80;
	HeaderItem.mask = HDI_TEXT;
	HeaderItem.pszText = pItem;
//
	char ItemBuf[80];
	for(int i=0; i<nHeaderCount; i++)
	{
		HeaderItem.iOrder=i;
		WriteProcessMemory(hProcess, pHeaderItem, &HeaderItem, sizeof(HDITEM), NULL);
		::SendMessage(hWnd, HDM_GETITEM, i, (LPARAM)pHeaderItem);
		ReadProcessMemory(hProcess, pItem, ItemBuf, 80, NULL);
//		afxDump << ItemBuf << "\n";
	}
//释放内存
	CloseHandle(hProcess);
	VirtualFreeEx(hProcess, pHeaderItem, 0, MEM_RELEASE);
	VirtualFreeEx(hProcess, pItem, 0, MEM_RELEASE);
}
使用 VirtualAllocEx 远程分配一个 (HRAWINPUT)lParam
我看一般对WM_INPUT处理的时候,在消息毁掉函数会直接释放掉内存,这个没影响把
schlafenhamster 2018-03-27
  • 打赏
  • 举报
回复
参考

void CRemoteListCtrlDlg::RemoteHeaderItem(HWND hWnd)
{	
// GetItemCount
	int nHeaderCount=::SendMessage(hWnd,HDM_GETITEMCOUNT,0,0);
// Get hProcess
	DWORD pid;
	GetWindowThreadProcessId(hWnd,&pid);
	HANDLE hProcess=OpenProcess(PROCESS_ALL_ACCESS,FALSE,pid);
//
	HDITEM *pHeaderItem = (HDITEM*)VirtualAllocEx(hProcess, NULL, sizeof(HDITEM), MEM_COMMIT, PAGE_READWRITE);
	char   *pItem = (char*)VirtualAllocEx(hProcess, NULL, 80, MEM_COMMIT, PAGE_READWRITE);
	if ((!pHeaderItem) || (!pItem))
	{
		::MessageBox(NULL, "无法分配内存!", "错误!", NULL);
		CloseHandle(hProcess);
		return;
	}
//
	HDITEM HeaderItem;
	HeaderItem.cchTextMax = 80;
	HeaderItem.mask = HDI_TEXT;
	HeaderItem.pszText = pItem;
//
	char ItemBuf[80];
	for(int i=0; i<nHeaderCount; i++)
	{
		HeaderItem.iOrder=i;
		WriteProcessMemory(hProcess, pHeaderItem, &HeaderItem, sizeof(HDITEM), NULL);
		::SendMessage(hWnd, HDM_GETITEM, i, (LPARAM)pHeaderItem);
		ReadProcessMemory(hProcess, pItem, ItemBuf, 80, NULL);
//		afxDump << ItemBuf << "\n";
	}
//释放内存
	CloseHandle(hProcess);
	VirtualFreeEx(hProcess, pHeaderItem, 0, MEM_RELEASE);
	VirtualFreeEx(hProcess, pItem, 0, MEM_RELEASE);
}
使用 VirtualAllocEx 远程分配一个 (HRAWINPUT)lParam
不填海的精卫 2018-03-27
  • 打赏
  • 举报
回复
引用 11 楼 schlafenhamster 的回复:
变量的 地址 不能 传到 另一个目标程序,所以 要 在 另一个目标程序 中 申请 一块 内存 即 (HRAWINPUT)lParam,把 内容 再 复制到 另一个目标程序 , 再 SendMessage
https://stackoverflow.com/questions/12590145/how-to-simulate-raw-input-send-a-wm-input-message-to-an-application-the-right 这个方法? 还是说我注入目标进程后,在他内部构造一个, 然后SendMessage
schlafenhamster 2018-03-26
  • 打赏
  • 举报
回复
可能 “模拟一个 (HRAWINPUT)lParam“ 不在 同一 地址 空间
schlafenhamster 2018-03-26
  • 打赏
  • 举报
回复
"我试过用这个构造的消息 给目标应用SendMessage不好用啊" 看看你的 代码
不填海的精卫 2018-03-26
  • 打赏
  • 举报
回复
引用 3 楼 schlafenhamster 的回复:
WM_INPUT 的 响应 如下:模拟一个 (HRAWINPUT)lParam
case WM_INPUT: 
		{
			UINT dwSize;
			GetRawInputData((HRAWINPUT)lParam, RID_INPUT,NULL,&dwSize,sizeof(RAWINPUTHEADER));
			LPBYTE lpb = new BYTE[dwSize];
			if (lpb == NULL) 
			{
				return 0;
			} 
			
			if (GetRawInputData((HRAWINPUT)lParam,RID_INPUT,lpb,&dwSize,sizeof(RAWINPUTHEADER)) !=
				dwSize)
				OutputDebugString (TEXT("GetRawInputData doesn't return correct size !\n")); 
			
			RAWINPUT* raw = (RAWINPUT*)lpb;
			
			if (raw->header.dwType == RIM_TYPEKEYBOARD) 
			{
				if ( raw->data.keyboard.Message == WM_KEYDOWN)
				{
					if (!IsInKeys(raw->data.keyboard.VKey))
					{
						char keytext[10] = {0};
						BYTE state[256] = {0};
						
						//通过虚拟键盘码得到名字
						ToAscii(raw->data.keyboard.VKey,raw->data.keyboard.MakeCode,state,(LPWORD)keytext ,0);
						char buf[10] = {0};
						string s = "键盘按下 虚键码:"+ string(keytext);
						MessageBoxA(NULL,s.c_str(),"键盘",MB_OK); 
					}
				}
				
				if( raw->data.keyboard.Message == WM_KEYUP)
				{
					erasekey(raw->data.keyboard.VKey);
				}
			}
			delete[] lpb; 
			return 0;
		}// end case WM_INPUT
https://msdn.microsoft.com/en-us/library/ms645590(VS.85).aspx
这只是处理自己的WM_INPUT 我试过用这个构造的消息 给目标应用SendMessage不好用啊
不填海的精卫 2018-03-26
  • 打赏
  • 举报
回复
引用 2 楼 schlafenhamster 的回复:
你的 代码 ?
就是单纯的SendMessage
schlafenhamster 2018-03-25
  • 打赏
  • 举报
回复
WM_INPUT 的 响应 如下:模拟一个 (HRAWINPUT)lParam
case WM_INPUT: 
{
UINT dwSize;
GetRawInputData((HRAWINPUT)lParam, RID_INPUT,NULL,&dwSize,sizeof(RAWINPUTHEADER));
LPBYTE lpb = new BYTE[dwSize];
if (lpb == NULL)
{
return 0;
}

if (GetRawInputData((HRAWINPUT)lParam,RID_INPUT,lpb,&dwSize,sizeof(RAWINPUTHEADER)) !=
dwSize)
OutputDebugString (TEXT("GetRawInputData doesn't return correct size !\n"));

RAWINPUT* raw = (RAWINPUT*)lpb;

if (raw->header.dwType == RIM_TYPEKEYBOARD)
{
if ( raw->data.keyboard.Message == WM_KEYDOWN)
{
if (!IsInKeys(raw->data.keyboard.VKey))
{
char keytext[10] = {0};
BYTE state[256] = {0};

//通过虚拟键盘码得到名字
ToAscii(raw->data.keyboard.VKey,raw->data.keyboard.MakeCode,state,(LPWORD)keytext ,0);
char buf[10] = {0};
string s = "键盘按下 虚键码:"+ string(keytext);
MessageBoxA(NULL,s.c_str(),"键盘",MB_OK);
}
}

if( raw->data.keyboard.Message == WM_KEYUP)
{
erasekey(raw->data.keyboard.VKey);
}
}
delete[] lpb;
return 0;
}// end case WM_INPUT
https://msdn.microsoft.com/en-us/library/ms645590(VS.85).aspx
schlafenhamster 2018-03-24
  • 打赏
  • 举报
回复
你的 代码 ?
摩登码农 2018-03-23
  • 打赏
  • 举报
回复
https://www.cnblogs.com/songr/p/5467007.html

15,979

社区成员

发帖
与我相关
我的任务
社区描述
VC/MFC 界面
社区管理员
  • 界面
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧