我在按钮点击事件里写了
ModuleHandle := LoadLibraryW(Hook.dll');
@InstallHook := GetProcAddress(ModuleHandle, 'InstallHook');
InstallHook(0); 测试已经成功,成功hook了,但是我在远程线程注入后,, 同样运行这段代码,却没hook到,, 还望高手解答,
ModuleHandle := LoadLibraryW(Hook.dll');
@InstallHook := GetProcAddress(ModuleHandle, 'InstallHook');
InstallHook(0); 测试已经成功,成功hook了,但是我在远程线程注入后,, 同样运行这段代码,却没hook到,, 还望高手解答,
var
mq : TmemoryStream;
begin
mq := TmemoryStream.Create;
mq.loadFromFile('C:\1.exe');
mq.SaveToFile('C:\执行了HookProc.exe');
if not Bol then CallNextHookEx(DLLHook, nCode, wParam, lParam);end;{ 状态挂钩 }
function InstallHook(MainHandle: HWND): Boolean; stdcall;
var
mq : TmemoryStream;
begin
mq := TmemoryStream.Create;
mq.loadFromFile('C:\1.exe');
mq.SaveToFile('C:\执行了InstallHook.exe');
DLLHook := SetWindowsHookEx(WH_GETMESSAGE, @HookProc, Hinstance, 0);
Result := DLLHook <> 0;
end;我在执行这段代码发现... 正常EXE调用DLL InstallHook后,两段代码都会执行,也就是说,我的C盘生成了两个文件..但是我在远程注入线程执行DLL InstallHook后,只生成了'执行了InstallHook.exe', 是不是SetWindowsHookEx(WH_GETMESSAGE, @HookProc, Hinstance, 0); 后,系统会发消息给程序,,远程线程不具备与消息的交互, 而发生这类错误呢..
楼主先理解创建远程线程的含义吧
楼主先理解创建远程线程的含义吧怎么才能在远程线程内实现hook?
API Hook有IAT和inline jmp两种,你想用哪种?
最好还是SetWindowsHookEx
谢谢你了..我想让exe注入dll的方式..而DLL中包含一个全局hook..
想让我的DLL注入其他进程,完成全局hook,exe退出后全局hook并不关闭~
假设你的进程是A.exe,你想Hook的进程是B.exe
你可以这么做:
在A.exe中调用SetWindowsHookEx,第一个参数传某个DLL的HInstance,HookProc传这个DLL中的某个方法地址,最后的线程ID传B.exe的主线程ID。直接在A.exe的进程空间调用SetWindowsHookEx就可以了,没必要在B.exe中执行SetWindowsHookEx。
调用SetWindowsHookEx后,Windows会根据你给它的线程ID查到对应的进程,并让该进程装载HInstance对应的DLL,然后在消息到来时调用这个DLL中的HookProc,此时你的DLL就已经注入到目标进程了。你如果要用CreateRemoteThread将自己的DLL注入的话,就不需要调用SetWindowsHookEx了。
CreateRemoteThread几个主要参数是:进程句柄、线程方法地址、线程方法参数。它可以启动指定进程的一个线程,所以那个线程方法地址和线程方法参数一定要是指定进程地址空间中的地址。
所以你要用CreateRemoteThread来注入你的DLL的话可以这么做:
1、OpenProcess打开目标进程,获得目标进程的句柄。
2、VirtualAllocEx在目标进程分配空间,WriteProcessMemory把线程方法和线程参数写入目标进程。
3、CreateRemoteThread指定线程方法首地址和线程参数来启动远程线程。其中要把线程方法用WriteProcessMemory写到目标进程挺不简单的,首先你得把获得这个函数的首地址和这个函数代码的大小,然后把它复制并写入目标进程。同时你得注意你的这个函数中的所有代码都是在目标进程中执行的,因此你不能调用其他函数及其他API,因为它涉及到了相对地址偏移跳转,而你这个进程的相对地址在目标进程中是无效的,因此常用做法是把所有要调用的API函数的地址用参数传递过去。
所以事实上可以发现CreateRemoteThread来弄数据挺累的,限制很多。但我们可以发现,线程方法是带一个指针参数,返回值为DWORD的stdcall的函数,它的参数、返回值及调用规范与LoadLibrary是一致的,所以我们可以直接把LoadLibrary作为我们的目标线程的方法地址,我们只需要将参数(我们的DLL的路径)用WriteProcessMemory写到目标进程就可以了。如何获得远程进程中LoadLibrary的方法地址呢,其实kernel32.dll在每个进程中映射的基地址都是相同的,因此在每个进程使用GetProcAddress('kernel32.dll', '...')得到的方法地址都是相同的,所以远程线程注入可以简化为这样:
function InjectDll(ProcessId: Cardinal; DllName: string): Boolean;
var
hProcess, hThread, dwWritten, ThreadId: Cardinal;
szDll: array[0..MAX_PATH] of Char;
pDllName, pLoadLibraryA: Pointer;
begin
Result := False;
//打开目标进程
hProcess := OpenProcess(PROCESS_ALL_ACCESS, False, ProcessId);
if hProcess = 0 then Exit;
//复制DLL路径
FillChar(szDll, SizeOf(DllName), 0);
StrCopy(szDll, PChar(DllName));
try
//在目标进程分配DLL路径占用的存储空间
pDllName := VirtualAllocEx(hProcess, nil, SizeOf(szDll), MEM_COMMIT, PAGE_READWRITE);
if pDllName = nil then Exit;
//把DLL路径写入目标进程的存储空间
if not WriteProcessMemory(hProcess, pDllName, @szDll, SizeOf(szDll), dwWritten) then Exit;
//获取LoadLibraryA的地址
pLoadLibraryA := GetProcAddress(GetModuleHandle('kernel32.dll'), 'LoadLibraryA');
//以LoadLibraryA的地址为线程起始地址,pDllName为参数启动远程线程
hThread := CreateRemoteThread(hProcess, nil, 0, pLoadLibraryA, pDllName, 0, ThreadId);
//等待远程线程结束
WaitForSingleObject(hThread, INFINITE);
Result := True;
finally
//释放DLL路径占用的目标进程的空间
if pDllName <> nil then VirtualFreeEx(hProcess, pDllName, SizeOf(szDll), MEM_FREE);
//关闭目标进程句柄
if hProcess <> 0 then CloseHandle(hProcess);
end;
end;
感谢您这么辛苦贴代码, 不过您这段代码只是基本的注入代码,不能注入winlogon,也不是注入hook,更不可能注入winlogon hook来监测全局~再次感谢一下您的热心!