陷阱式API HOOK后如何恢复原函数入口 ( 积分: 30 )

  • 主题发起人 主题发起人 sy0116
  • 开始时间 开始时间
S

sy0116

Unregistered / Unconfirmed
GUEST, unregistred user!
我用以下代码HOOK&nbsp;CreateProcessA函数,但是发现HOOK过后我也不能用CreateProcess了,请问如何才能正确恢复原函数的入口<br><br>unit&nbsp;APIhook;<br><br>interface<br>uses<br>&nbsp;&nbsp;Windows;<br><br>type<br>&nbsp;&nbsp;MyCreateProcessA=function(lpApplicationName:&nbsp;PChar;&nbsp;lpCommandLine:&nbsp;PChar;<br>&nbsp;&nbsp;lpProcessAttributes,&nbsp;lpThreadAttributes:&nbsp;PSecurityAttributes;<br>&nbsp;&nbsp;bInheritHandles:&nbsp;BOOL;&nbsp;dwCreationFlags:&nbsp;DWORD;&nbsp;lpEnvironment:&nbsp;Pointer;<br>&nbsp;&nbsp;lpCurrentDirectory:&nbsp;PChar;&nbsp;const&nbsp;lpStartupInfo:&nbsp;TStartupInfo;<br>&nbsp;&nbsp;var&nbsp;lpProcessInformation:&nbsp;TProcessInformation):&nbsp;BOOL;&nbsp;stdcall;<br><br>&nbsp;&nbsp;TJump=packed&nbsp;record<br>&nbsp;&nbsp;&nbsp;&nbsp;MovEAX:Byte;<br>&nbsp;&nbsp;&nbsp;&nbsp;Addr:MyCreateProcessA;<br>&nbsp;&nbsp;&nbsp;&nbsp;JmpEAX:Word;<br>&nbsp;&nbsp;&nbsp;&nbsp;resvered:Byte;<br>&nbsp;&nbsp;end;<br><br>var<br>&nbsp;&nbsp;OldJmp:TJump;<br>&nbsp;&nbsp;hDll:THandle;<br>&nbsp;&nbsp;pOldCreateProcess:Pointer;<br>&nbsp;&nbsp;OriCreateProcess:MyCreateProcessA;<br>&nbsp;&nbsp;crd:Cardinal;<br>procedure&nbsp;HookCreateProcess;<br><br>implementation<br><br>function&nbsp;SyCreateProcessA(lpApplicationName:&nbsp;PChar;&nbsp;lpCommandLine:&nbsp;PChar;<br>&nbsp;&nbsp;lpProcessAttributes,&nbsp;lpThreadAttributes:&nbsp;PSecurityAttributes;<br>&nbsp;&nbsp;bInheritHandles:&nbsp;BOOL;&nbsp;dwCreationFlags:&nbsp;DWORD;&nbsp;lpEnvironment:&nbsp;Pointer;<br>&nbsp;&nbsp;lpCurrentDirectory:&nbsp;PChar;&nbsp;const&nbsp;lpStartupInfo:&nbsp;TStartupInfo;<br>&nbsp;&nbsp;var&nbsp;lpProcessInformation:&nbsp;TProcessInformation):&nbsp;BOOL;&nbsp;stdcall;<br>begin<br>&nbsp;&nbsp;SetWindowText(FindWindow('tform1','form1'),lpCommandLine);<br>&nbsp;&nbsp;WriteProcessMemory(GetCurrentProcess,pOldCreateProcess,@OldJmp,8,crd);//回复原函数前八个字节,但没成功<br>&nbsp;&nbsp;Result:=CreateProcess(lpApplicationName,lpCommandLine,lpProcessAttributes,lpThreadAttributes,<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;bInheritHandles,dwCreationFlags,lpEnvironment,lpCurrentDirectory,<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;lpStartupInfo,lpProcessInformation);<br>end;<br>procedure&nbsp;HookCreateProcess;<br>var<br>&nbsp;&nbsp;DrComJmp:TJump;<br>begin<br>&nbsp;&nbsp;DrComJmp.MovEAX:=$B8;<br>&nbsp;&nbsp;DrComJmp.JmpEAX:=$E0FF;<br>&nbsp;&nbsp;DrComJmp.Addr:=@SyCreateProcessA;<br>&nbsp;&nbsp;hDll:=GetModuleHandle(kernel32);<br>&nbsp;&nbsp;pOldCreateProcess:=GetProcAddress(hDll,'CreateProcessA');<br>&nbsp;&nbsp;@OriCreateProcess:=pOldCreateProcess;<br>&nbsp;&nbsp;ReadProcessMemory(GetCurrentProcess,pOldCreateProcess,@OldJmp,8,crd);//在此处记下原函数的入口前八个字节<br>&nbsp;&nbsp;WriteProcessMemory(GetCurrentProcess,pOldCreateProcess,@DrComJmp,8,crd);<br>end;<br>end.
 
试试afxcodehook.pas中的unhookcode是否能还原,不过这个单元在挂钩在XP下面会报错,是什么内存不为read
 
这些hook的代码都有不同程度的问题。
 
我不想用afxcodehook.pas<br>我有更好的办法,还可以避免重入,但是我现在就想知道为什么这样不行
 
你想知道的话用&nbsp;ctrl+alt+c&nbsp;然后按&nbsp;步进就知道了。
 
ctrl+alt+c一点反应也没有啊
 
呵呵,sy0116的問題和我一樣,白河愁給我的最后回覆是:<br>写回的时候地址被破坏了,API一般都是&nbsp;0x7xxxxxxx&nbsp;,&nbsp;2cacb54&nbsp;是堆栈地址,看看什么地方破坏了。&nbsp;&nbsp;<br>而我再問如何把函數地址(0x7xxxxxxx)以string形式顯示出來<br>BaseAddress:&nbsp;array&nbsp;[0..2]&nbsp;of&nbsp;Pointer;&nbsp;&nbsp;//BaseAddress如何轉換成string?<br>OldProc:&nbsp;array&nbsp;[0..2]&nbsp;of&nbsp;array&nbsp;[0..7]&nbsp;of&nbsp;Byte;&nbsp;&nbsp;//OldProc如何轉換成string?&nbsp;&nbsp;<br>因為我不知道如何查在什麼地方破壞了原函數地址,所以想通過顯示為string觀察該地址是在哪裡被修改了.
 
&quot;我不想用afxcodehook.pas<br>我有更好的办法,还可以避免重入,但是我现在就想知道为什么这样不行&nbsp;&nbsp;&quot;<br><br>能否提供一些你的代码给我,我也不想用Afxcodehook的,可没有办法,研究了好多天自己写的还不如afxcodehook的好用,所以只好作罢,主要是挂钩Createprocess这个函数时打开外部程序会报错:什么指令引用的内存不为read,你可以看看这个代码,我改了一<br>下:http://www.delphibbs.com/delphibbs/DispQ.asp?LID=3707408报的错少了,但一些程序比如打开winrar&nbsp;&nbsp;mmc第一次运行都会报错,不知道为什么本人不懂汇编,所调试了半天也是一头污水,我的邮箱:xawangting@126.com
 
to&nbsp;takdick:<br>&nbsp;&nbsp;如果要看,那在运行中按&nbsp;ctrl+Alt+c&nbsp;直接看内存就是了。
 
我的代码在http://www.delphibbs.com/delphibbs/dispq.asp?lid=3671817的最下面<br>Hook的是MessageBoxA,改成CreateProcess也简单,最好把里面所有的CreateFileMapping换成VirtualAlloc,CopyMemory换成WriteProcessMemory,否则在部分电脑上会出莫名其妙的问题。这段代码是可以Hook&nbsp;CreateProcessW的,我有一个程序就是用的这样的办法,但是那个里面别的代码太多了单独把API&nbsp;HOOK分出来不太方便所以你就先看看这个吧
 
终于找到问题出在哪里了:<br>做API&nbsp;Hook首先要把DLL注入到别的进程中去我用的办法是用WH_SHELL钩子钩HSHELL_WINDOWCREATED来实现注入,但是一个程序窗口打开时会钩到多个HSHELL_WINDOWCREATED,所以当钩到第一个HSHELL_WINDOWCREATED时保存下来的原函数入口的8个字节是正确的,但第二次钩到HSHELL_WINDOWCREATED时保存下来的原函数入口8字节就是前一次API&nbsp;Hook修改过的东西了,因此保存下的OldJmp是错误的,因此应该这样修改:<br>procedure&nbsp;HookCreateProcess;<br>var<br>&nbsp;&nbsp;DrComJmp:TJump;<br>begin<br>&nbsp;&nbsp;DrComJmp.MovEAX:=$B8;<br>&nbsp;&nbsp;DrComJmp.JmpEAX:=$E0FF;<br>&nbsp;&nbsp;DrComJmp.Addr:=@SyCreateProcessA;<br>&nbsp;&nbsp;hDll:=GetModuleHandle(kernel32);<br>&nbsp;&nbsp;pOldCreateProcess:=GetProcAddress(hDll,'CreateProcessA');<br>&nbsp;&nbsp;@OriCreateProcess:=pOldCreateProcess;<br>&nbsp;&nbsp;if&nbsp;Hooked=False&nbsp;then<br>&nbsp;&nbsp;begin<br>&nbsp;&nbsp;&nbsp;&nbsp;Hooked:=True;//Hooked是一全局变量<br>&nbsp;&nbsp;&nbsp;&nbsp;ReadProcessMemory(GetCurrentProcess,pOldCreateProcess,@OldJmp,8,crd);<br>&nbsp;&nbsp;end;<br>&nbsp;&nbsp;WriteProcessMemory(GetCurrentProcess,pOldCreateProcess,@DrComJmp,8,crd);<br>end;<br>end.
 
用这种代码Hook&nbsp;多个&nbsp;API&nbsp;看起来就是恶梦。
 
或许做成一个类会好一点吧,Hook多了确实有点恼火
 
原來我出現的問題和sy0116有點不同,我在Hook&nbsp;CreateProcessW之後,去開啟其他程序(多次)都能被我的程序攔截到並正常運行,只是當我執行UnHook退出程序後,再去開啟其他程序時就會提示&quot;0x02cacb54&quot;指令參考的&quot;0x02cacb54&quot;記憶體.該記憶體不能為&quot;read&quot;<br>我的自定義函數和你的有點不同:<br>function&nbsp;MyCreatePW(lpApplicationName:&nbsp;PWideChar;&nbsp;lpCommandLine:&nbsp;PWideChar;&nbsp;//自定義函數<br>&nbsp;&nbsp;&nbsp;&nbsp;lpProcessAttributes,&nbsp;lpThreadAttributes:&nbsp;PSecurityAttributes;<br>&nbsp;&nbsp;&nbsp;&nbsp;bInheritHandles:&nbsp;BOOL;&nbsp;dwCreationFlags:&nbsp;DWORD;&nbsp;lpEnvironment:&nbsp;Pointer;<br>&nbsp;&nbsp;&nbsp;&nbsp;lpCurrentDirectory:&nbsp;PWideChar;&nbsp;const&nbsp;lpStartupInfo:&nbsp;TStartupInfo;<br>&nbsp;&nbsp;&nbsp;&nbsp;var&nbsp;lpProcessInformation:&nbsp;TProcessInformation):&nbsp;BOOL;&nbsp;stdcall;<br>var<br>&nbsp;&nbsp;nSize:&nbsp;Cardinal;<br>begin<br>&nbsp;&nbsp;MessageBoxW(0,&nbsp;lpCommandLine&nbsp;,lpApplicationName&nbsp;,&nbsp;0);//显示執行程序的命令行和文件名<br>&nbsp;&nbsp;WriteProcessMemory(ProcessHandle,&nbsp;BaseAddress[0],&nbsp;@OldProc[0],&nbsp;8,&nbsp;nSize);//這一句是修改成原來函數的地址,讓程序能正常執行<br>&nbsp;&nbsp;Result&nbsp;:=&nbsp;CreateProcessW(lpApplicationName,&nbsp;lpCommandLine,&nbsp;lpProcessAttributes,<br>&nbsp;&nbsp;&nbsp;lpThreadAttributes,&nbsp;bInheritHandles,&nbsp;dwCreationFlags,&nbsp;lpEnvironment,<br>&nbsp;&nbsp;&nbsp;lpCurrentDirectory,&nbsp;lpStartupInfo,&nbsp;lpProcessInformation);<br>&nbsp;&nbsp;WriteProcessMemory(ProcessHandle,&nbsp;BaseAddress[0],&nbsp;@NewPorc[0],&nbsp;8,&nbsp;nSize);//在程序正常打開後再修改成自定義函數的地址,使程序在下次打開時還能被攔截到<br>end;<br>我試用了你的方法,還新增了一地址專門儲存原函數地址,只在UnHook時調用回復,但還是沒用.
 
你确定每个被你HOOK的程序都执行了UnHook么?
 
我也不知,帮你顶顶
 
多人接受答案了。
 
后退
顶部