C++ 在c++';s SetWindowsHookEx函数
我是韩国学生。 这是我报名后的第一个问题C++ 在c++';s SetWindowsHookEx函数,c++,winapi,C++,Winapi,我是韩国学生。 这是我报名后的第一个问题 DWORD getProcessId() { PROCESSENTRY32 process_infor; process_infor.dwSize = sizeof(PROCESSENTRY32); HANDLE snap_handle = CreateToolhelp32Snapshot( TH32CS_SNAPALL, //스냅 단계 NULL //스냅할 pid ); if
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;
}
DWORD getProcessId(){
PROCESSENTRY32过程信息;
process_infor.dwSize=sizeof(PROCESSENTRY32);
HANDLE snap\u HANDLE=CreateToolhelp32Snapshot(
TH32CS_SNAPALL//스냅 단계
空的//스냅할 pid
);
if(捕捉句柄!=无效的句柄值){
Process32First(捕捉句柄和进程信息);
做{
wchar_t*temp=process_infor.szExeFile;
wstring-ws(温度);
字符串名称(ws.begin(),ws.end());
如果(名称==“notepad.exe”){
cout根据以下结果:
dwThreadId
包含lpfn参数指向的钩子过程的DLL句柄。如果dwThreadId参数指定由当前进程创建的线程,并且钩子过程在与当前进程关联的代码中,则必须将hMod参数设置为NULL
因此,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;
}
int main()
{
inject();
MSG msg;
while (GetMessageW(&msg, NULL, 0, 0))
{
TranslateMessage(&msg);
DispatchMessageW(&msg);
}
}
if ((0x80000000 & lParam) == 0)//This means that when the key is pressed
{
MessageBox(NULL, L"Success (dll injection)", L"Window", MB_OK);
}
按下按钮时,将弹出消息框:
因为每次按键和释放都有两条消息,func每次触发两次。如果您只想在每次按下按钮时触发,可以修改以下代码:
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;
}
int main()
{
inject();
MSG msg;
while (GetMessageW(&msg, NULL, 0, 0))
{
TranslateMessage(&msg);
DispatchMessageW(&msg);
}
}
if ((0x80000000 & lParam) == 0)//This means that when the key is pressed
{
MessageBox(NULL, L"Success (dll injection)", L"Window", MB_OK);
}
您可以参考以查看LPRAM中每个值的消息。欢迎使用堆栈溢出;我建议检查GetProcAddress
的结果,以确保您确实找到了函数:如果它为NULL怎么办?此外,建议您在调用SetWindowHookEx
后立即捕获最后一个错误号,因为t调用-可能执行I/O-可能会覆盖上一个错误并混淆报告。在设置窗口挂钩后立即执行const DWORD err=GetLastError()
会捕获此错误。为getProcessId
发布的代码没有进程名称(“notepad.exe”),但我认为这是粘贴示例时的一个输入错误。我建议您检查是否确实找到了一个有效的线程ID,并检查它:只有在得到非零响应时才调用SetWindowsHookEx
。哦,我认为是“notepad.exe”是getProcessId中的一个输入错误。使用真实代码编写得很好。请编辑示例代码,使其能够编译;很明显,getProcessId
希望获得字符串参数(process\u name
)。然后我们可以更仔细地查看它。抱歉;;它已更改。GetProcAddress函数似乎工作正常。当我手动运行线程_func()时像这样的功能,消息框通常会出现在窗口中。嗯!非常感谢。这工作正常,现在我没有收到任何错误。但它运行正常,没有错误,但dll没有运行。为什么会这样?当使用名为Process Explorer的应用程序搜索时,dll不在记事本中。原因可能是Process Explorer无法运行检测链接的dll。您可以参考。如果此原始答案确实对您有帮助,请随时标记它以帮助有相同问题的人,并让我知道您是否有任何问题。谢谢。因此…Process Explore无法检测dll文件?没有其他问题,没有错误,并且似乎工作正常,但结果似乎无法运行.那么….在将dll插入记事本后,无法运行它?只要通过loadlibrary函数在main中加载dll,上述修改就会运行。非常感谢。感谢您,几乎所有操作都已成功^^^。但是,在上面的视频和我的代码中,我遇到了一个问题,即窗口出现两次,并且没有其他ac执行injectSuccess函数的输入或输出。我如何解决此问题?完成后,我接受您的帖子并结束此问题!