gpt4 book ai didi

c++ - 在 c++ 的 SetWindowsHookEx 函数中

转载 作者:行者123 更新时间:2023-12-03 06:54:25 26 4
gpt4 key购买 nike

我是韩国学生。这是我注册后的第一个问题。

DWORD getProcessId() {
PROCESSENTRY32 process_infor;
process_infor.dwSize = sizeof(PROCESSENTRY32);

HANDLE snap_handle = CreateToolhelp32Snapshot(
TH32CS_SNAPALL, //스냅 단계
NULL //스냅할 pid
);

if (snap_handle != INVALID_HANDLE_VALUE) {
Process32First(snap_handle, &process_infor);

do {
wchar_t* temp = process_infor.szExeFile;
wstring ws(temp);
string name(ws.begin(), ws.end());

if (name == "notepad.exe") {
cout << name << " : " << process_infor.th32ProcessID << endl;
return process_infor.th32ProcessID;
}

} while (Process32Next(snap_handle, &process_infor));
}

CloseHandle(snap_handle);
return FALSE;
}

BOOL inject() {
HMODULE dll_handle;
HOOKPROC func;
HHOOK process_hook;

dll_handle = LoadLibrary(L"hello.dll");
func = (HOOKPROC) GetProcAddress(dll_handle, "injectSuccess");

cout << "handle : " << dll_handle << endl;
cout << "pid : " << getProcessId() << endl;

process_hook = SetWindowsHookEx(
WH_KEYBOARD,
func,
dll_handle,
getProcessId()
);

cout << "pook : " << process_hook << endl;
cout << "err : " << GetLastError() << endl;
FreeLibrary(dll_handle);

return FALSE;
}

在这种情况下,注入(inject)函数的 SetWindowsHookEx 似乎有问题。 dll文件加载的很好,里面的injectSuccess函数也很好获取。 (我试过运行它,但它成功了)并且怀疑是不是SetWindowsHookEx的参数值输入错误,于是不断对比,不断检查,也没有发现有什么不同。因此,我尝试使用 GetLastError() 和下面 SetWindowsHookEx 的返回值,但返回值为 0,错误代码为 87(“参数不正确”)。

所以我搜索了一下,但我英语说得不好,而且我是初学者,所以我不确定。

最佳答案

根据SetWindowsHookExW :

dwThreadId

A handle to the DLL containing the hook procedure pointed to by the lpfn parameter. The hMod parameter must be set to NULL if the dwThreadId parameter specifies a thread created by the current process and if the hook procedure is within the code associated with the current process.

所以SetWindowsHookExW需要的是线程ID,而你传入的是notepad.exe的进程ID,所以参数不对。

我创建了一个示例并测试了以下代码:

BOOL inject() {
HMODULE dll_handle;
HOOKPROC func;
HHOOK process_hook;

dll_handle = LoadLibrary(L"hello.dll");
if (dll_handle) func = (HOOKPROC)GetProcAddress(dll_handle, "injectSuccess");
else return FALSE;
cout << "handle : " << dll_handle << endl;
cout << "pid : " << getProcessId() << endl;
HWND h = FindWindow(L"notepad", NULL);
DWORD pid;
threadID = GetWindowThreadProcessId(h, NULL);
cout << "threadID = " << threadID << endl;
process_hook = SetWindowsHookEx(
WH_KEYBOARD,
func,
dll_handle,
threadID
);

cout << "pook : " << process_hook << endl;
cout << "err : " << GetLastError() << endl;
if(dll_handle) FreeLibrary(dll_handle);
return FALSE;
}

这个例子对我有用,你可以看到 pid 和 threadID 之间的区别:

enter image description here

编辑

根据document :

An application installs the hook procedure by specifying theWH_KEYBOARD hook type and a pointer to the hook procedure in a call tothe SetWindowsHookEx function. This hook may be called in the contextof the thread that installed it. The call is made by sending a messageto the thread that installed the hook. Therefore, the thread thatinstalled the hook must have a message loop. So if you want to runthis func, you need to add a message loop.

可以引用下面的代码:

int main()
{
inject();
MSG msg;
while (GetMessageW(&msg, NULL, 0, 0))
{
TranslateMessage(&msg);
DispatchMessageW(&msg);
}
}

当你按下按钮时,会弹出消息框:

enter image description here

因为每次按键按下和松开都有两条消息,所以func每次都会触发两次。如果只想在每次按键按下时触发,可以修改如下代码:

if ((0x80000000 & lParam) == 0)//This means that when the key is pressed
{
MessageBox(NULL, L"Success (dll injection)", L"Window", MB_OK);
}

可以引用KeyboardProc查看 lParam 中每个值的消息。

关于c++ - 在 c++ 的 SetWindowsHookEx 函数中,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/64492788/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com