T
takdick
Unregistered / Unconfirmed
GUEST, unregistred user!
我在論壇搜索到Hook Api的代碼如下,編譯後程序是可以Hook到CreateProcess函數,但在程序退出時調用UnHook,發現並無法恢復原來的Api,在開啟程序時會提示:<br>'"0x02cacb54"指令參考的"0x02cacb54"記憶體.該記憶體不能為"read" <br>按[確定]終止程序<br>按[取消]進行程序偵錯<br>請問如何解決?謝謝.<br>http://www.delphibbs.com/delphibbs/dispq.asp?lid=3319981<br>{-------------------Hook.dpr----------------------}<br>{ 这个是DLL }<br>library Hook;<br><br>uses<br> SysUtils,<br> windows,<br> Messages,<br> APIHook in 'APIHook.pas';<br><br>var<br> DllHook: HHOOK;<br><br>procedure HookProc(nCode, wParam, lParam: LongWORD);stdcall;<br>begin<br> CallNextHookEx(DllHook, nCode, wParam, lParam);<br>end;<br><br>{ 状态挂钩 }<br>function InstallHook: Boolean; stdcall;<br>begin<br> DllHook := SetWindowsHookEx(WH_GETMESSAGE, @HookProc, Hinstance, 0);<br> Result := DllHook > 0;<br>end;<br><br>{ 卸载挂钩 }<br>procedure UnHook; stdcall;<br>begin<br> UnHookAPI;<br> UnhookWindowsHookEx(DllHook);<br>end;<br><br>procedure MyDLLHandler(Reason: Integer);<br>begin <br> case Reason of<br> DLL_PROCESS_ATTACH: HookAPI;<br> DLL_PROCESS_DETACH: UnHook;<br> end; <br>end; <br><br>exports <br> InstallHook,UnHook;<br><br>begin <br> DLLProc := @MyDLLHandler;<br> MyDLLhandler(DLL_PROCESS_ATTACH);<br>end.<br><br>{------------------APIHook.pas---------------------}<br><br>unit APIHook;<br><br>interface <br><br>uses <br> SysUtils, Windows, WinSock, Dialogs;<br><br>type <br> { 要HOOK的API函数定义 }<br> TCreatePA = function (lpApplicationName: PAnsiChar; lpCommandLine: PAnsiChar;<br> lpProcessAttributes, lpThreadAttributes: PSecurityAttributes;<br> bInheritHandles: BOOL; dwCreationFlags: DWORD; lpEnvironment: Pointer;<br> lpCurrentDirectory: PAnsiChar; const lpStartupInfo: TStartupInfo;<br> var lpProcessInformation: TProcessInformation): BOOL; stdcall;<br><br> TCreatePW = function (lpApplicationName: PWideChar; lpCommandLine: PWideChar;<br> lpProcessAttributes, lpThreadAttributes: PSecurityAttributes;<br> bInheritHandles: BOOL; dwCreationFlags: DWORD; lpEnvironment: Pointer;<br> lpCurrentDirectory: PWideChar; const lpStartupInfo: TStartupInfo;<br> var lpProcessInformation: TProcessInformation): BOOL; stdcall;<br><br> <br> procedure HookAPI; <br> procedure UnHookAPI;<br><br>var<br> ProcessHandle: HWND;<br> BaseAddress: array [0..2] of Pointer;<br> OldProc: array [0..2] of array [0..7] of Byte;<br> NewPorc: array [0..2] of array [0..7] of Byte;<br><br>implementation<br><br>{ 自定义的函数,用于覆盖系统的CreateProcessA函数 }<br>function MyCreatePA(lpApplicationName: PAnsiChar; lpCommandLine: PAnsiChar;<br> lpProcessAttributes, lpThreadAttributes: PSecurityAttributes;<br> bInheritHandles: BOOL; dwCreationFlags: DWORD; lpEnvironment: Pointer;<br> lpCurrentDirectory: PAnsiChar; const lpStartupInfo: TStartupInfo;<br> var lpProcessInformation: TProcessInformation): BOOL; stdcall;<br>var<br> nSize: Cardinal;<br>begin<br> { 显示打开程序的文件名(这个有问题,文件名为空)和所在文件夹 }<br> MessageBoxA(0, lpApplicationName, lpCurrentDirectory, 0);<br> WriteProcessMemory(ProcessHandle, BaseAddress[0], @OldProc[0], 8, nSize);<br> Result := CreateProcessA(lpApplicationName, lpCommandLine, lpProcessAttributes,<br> lpThreadAttributes, bInheritHandles, dwCreationFlags, lpEnvironment,<br> lpCurrentDirectory, lpStartupInfo, lpProcessInformation);<br> WriteProcessMemory(ProcessHandle, BaseAddress[0], @NewPorc[0], 8, nSize);<br>end;<br><br>{ 同上 }<br>function MyCreatePW(lpApplicationName: PWideChar; lpCommandLine: PWideChar;<br> lpProcessAttributes, lpThreadAttributes: PSecurityAttributes;<br> bInheritHandles: BOOL; dwCreationFlags: DWORD; lpEnvironment: Pointer;<br> lpCurrentDirectory: PWideChar; const lpStartupInfo: TStartupInfo;<br> var lpProcessInformation: TProcessInformation): BOOL; stdcall;<br>var<br> nSize: Cardinal;<br>begin<br> { 显示打开程序的命令行和文件名(这个有问题,文件名为空,其他都有值) }<br> MessageBoxW(0, lpCommandLine ,lpApplicationName , 0);<br> WriteProcessMemory(ProcessHandle, BaseAddress[1], @OldProc[1], 8, nSize);<br> Result := CreateProcessW(lpApplicationName, lpCommandLine, lpProcessAttributes,<br> lpThreadAttributes, bInheritHandles, dwCreationFlags, lpEnvironment,<br> lpCurrentDirectory, lpStartupInfo, lpProcessInformation);<br> WriteProcessMemory(ProcessHandle, BaseAddress[1], @NewPorc[1], 8, nSize);<br>end;<br><br>procedure HookAPI;<br>var<br> DLLModule: THandle;<br> nSize: Cardinal;<br> Dat: DWORD;<br> Tmp : array [0..3] of Byte;<br>begin<br> ProcessHandle := DWORD(-1);<br> DLLModule := LoadLibrary('kernel32.dll');<br> { 系统函数入口点地址 }<br> BaseAddress[0] := GetProcAddress(DLLModule, 'CreateProcessA');<br> Dat := DWORD(@MyCreatePA);<br> Move(Dat, Tmp, 4);<br> NewPorc[0][0] := $B8; { 汇编跳转指令 }<br> NewPorc[0][1] := Tmp[0]; { 跳转到自身的函数 }<br> NewPorc[0][2] := Tmp[1];<br> NewPorc[0][3] := Tmp[2];<br> NewPorc[0][4] := Tmp[3];<br> NewPorc[0][5] := $FF;<br> NewPorc[0][6] := $E0;<br> NewPorc[0][7] := 0;<br> { 读取系统函数内存地址 }<br> ReadProcessMemory(ProcessHandle, BaseAddress[0], @OldProc[0], 8, nSize);<br> { 用自己的函数地址覆盖系统的函数地址 }<br> WriteProcessMemory(ProcessHandle, BaseAddress[0], @NewPorc[0], 8, nSize);<br><br> { 同上 }<br> BaseAddress[1] := GetProcAddress(DLLModule, 'CreateProcessW');<br> Dat := DWORD(@MyCreatePW);<br> Move(Dat, Tmp, 4);<br> NewPorc[1][0] := $B8;<br> NewPorc[1][1] := Tmp[0];<br> NewPorc[1][2] := Tmp[1];<br> NewPorc[1][3] := Tmp[2];<br> NewPorc[1][4] := Tmp[3];<br> NewPorc[1][5] := $FF;<br> NewPorc[1][6] := $E0;<br> NewPorc[1][7] := 0;<br> ReadProcessMemory(ProcessHandle, BaseAddress[1], @OldProc[1], 8, nSize);<br> WriteProcessMemory(ProcessHandle, BaseAddress[1], @NewPorc[1], 8, nSize);<br>end;<br><br>procedure UnHookAPI;<br>var<br> nSize: Cardinal;<br>begin<br> { 恢复所修改的地址 }<br> WriteProcessMemory(ProcessHandle, BaseAddress[0], @OldProc[0], 8, nSize);<br> WriteProcessMemory(ProcessHandle, BaseAddress[1], @OldProc[1], 8, nSize);<br>end;<br><br>end.