仙乃日 发表于 2010-8-22 11:28:45

hook CopyFile 不成功[已解决]

本帖最后由 仙乃日 于 2010-8-22 19:08 编辑

学习了P版的HookMsgBox.au3,想照着样子写个hook CopyFile结果却失败了。请各位大大帮忙看一下。Const $hKernelDll = DllOpen("Kernel32.dll")

Global $hMyfilecopy, $pMyfilecopy, $bfilecopyEntryhook

$hMyfilecopy = DllCallbackRegister("_Myfilecopy", "BOOL", "str;str;bool");创建一个用户自定义回调函数.DllCallbackRegister ( "函数名", "返回类型", "参数" )
$pMyfilecopy = DllCallbackGetPtr($hMyfilecopy) ;返回一个回调函数的指针,可以用于传递给一个 Win32 API.
$bfilecopyEntryhook = _NtHookProcedure("Kernel32.dll", "CopyFile", $pMyfilecopy)

DllCall("Kernel32.dll", "BOOL", "CopyFile","str", @WindowsDir & "\NOTEPAD.EXE","str", @ScriptDir & "\记事本.exe", "BOOL", 1)
;FileCopy(@WindowsDir & "\NOTEPAD.EXE",@ScriptDir & "\记事本.exe")
; 卸载HOOK。
_NtUnhookProcedure("Kernel32.dll", "CopyFile", $bfilecopyEntryhook)
DllCallbackFree($hMyfilecopy);清空先前由 DllCallbackRegister 创建的句柄.
DllClose("$hKernelDll")
Func _Myfilecopy($sourcefile, $destfile,$Flags)
      _NtUnHookProcedure("Kernel32.dll", "CopyFile", $bfilecopyEntryhook)
                MsgBox(0,$sourcefile,$destfile)
      FileCopy($sourcefile,@ScriptDir & "\hook_记事本.exe")
      $bfilecopyEntryhook = _NtHookProcedure("Kernel32.dll", "CopyFile", $pMyfilecopy)
EndFunc      ;==>_Myfilecopy

Func _NtAllocateVirtualMemory(ByRef $pBaseAddr, $hProcess, $iSize, $iAllocType, $iProtect = 4)
      Local $iResult
      $iResult = DllCall($hKernelDll, "ptr", "VirtualAllocEx", "hWnd", $hProcess, _ ; 函数的作用是在指定进程的虚拟空间保留或提交内存区域,除非指定MEM_RESET参数,否则将该内存区域置0。
                        "ptr", $pBaseAddr, "dword", $iSize, "dword", $iAllocType, "dword", $iProtect)
      $pBaseAddr = $iResult
      Return SetError(_NtLastError(), 0, Number($pBaseAddr) <> 0)
EndFunc      ;==>_NtAllocateVirtualMemory

Func _NtHookProcedure($sModule, $sProcedure, $pRedirectCall) ; _NtUnHookProcedure("Kernel32.dll", "CopyFile", $bfilecopyEntryhook)
      Local $bRedirect, $hModule, $pProcedure, $tEntryPoint, $bEntryPoint, $iProtection

      For $i = 3 To 9 Step 2
                $bRedirect = StringMid($pRedirectCall, $i, 2) & $bRedirect
      Next
      $bRedirect = Binary("0xB8" & $bRedirect & "FFE000") ;返回一个表达式的二进制值

      $hModule = _GetModuleHandle($sModule)
      $pProcedure = _GetProcAddress($hModule, $sProcedure)

      _NtProtectVirtualMemory(-1, $pProcedure, 8, 4)
      $iProtection = @extended
      $tEntryPoint = DllStructCreate("ubyte EntryPoint", $pProcedure) ;创建一个 C/C++ 样式的数据结构供 DllCall 使用.
      $bEntryPoint = DllStructGetData($tEntryPoint, "EntryPoint") ;返回数据结构(struct)元素的数据.
      DllStructSetData($tEntryPoint, "EntryPoint", $bRedirect) ;设置数据结构(struct)中部分元素的数据.

      _NtProtectVirtualMemory(-1, $pProcedure, 8, $iProtection)
      Return $bEntryPoint
EndFunc      ;==>_NtHookProcedure

Func _NtUnhookProcedure($sModule, $sProcedure, $bEntryPoint)
      Local $hModule, $pProcedure, $pVirtState, $tVirtState
      Local $iProtection, $tEntryPoint

      $hModule = _GetModuleHandle($sModule)
      $pProcedure = _GetProcAddress($hModule, $sProcedure)

      _NtProtectVirtualMemory(-1, $pProcedure, 8, 4)
      $iProtection = @extended
      $tEntryPoint = DllStructCreate("ubyte EntryPoint", $pProcedure)
      DllStructSetData($tEntryPoint, "EntryPoint", $bEntryPoint)
      _NtProtectVirtualMemory(-1, $pProcedure, 8, $iProtection)
EndFunc      ;==>_NtUnhookProcedure

Func _GetModuleHandle($sModule)
      Local $iResult
      $iResult = DllCall($hKernelDll, "long", "GetModuleHandle", "str", $sModule) ;获取一个应用程序或动态链接库的模块句柄lpModuleName 模块名称
      Return ($iResult)
EndFunc      ;==>_NtGetModuleHandle

Func _GetProcAddress($hModule, $sProcedure) ;DLL模块句柄函数名
      Local $iResult
      $iResult = DllCall($hKernelDll, "ptr", "GetProcAddress", "hWnd", $hModule, "str", $sProcedure) ;GetProcAddress函数检索指定的动态链接库(DLL)中的输出库函数地址。
      Return ($iResult)
EndFunc      ;==>_NtGetProcAddress

Func _NtProtectVirtualMemory($hProcess, $pBaseAddr, $iSize, $iNewProtect)
      Local $iResult

      If ($hProcess = -1) Then $hProcess = _NtCurrentProcess()
      $iResult = DllCall($hKernelDll, "int", "VirtualProtectEx", "hWnd", $hProcess, _   ; 这个函数可以改变在特定进程中内存区域的保护属性。 HANDLE hProcess, // 要修改内存的进程句柄 LPVOID lpAddress, // 要修改内存的起始地址// 修改内存的字节  DWORD flNewProtect, // 修改后的内存属性 PDWORD lpflOldProtect // 修改前的内存属性的地址
                        "ptr", $pBaseAddr, "dword", $iSize, "dword", $iNewProtect, "dword*", 0)
      Return SetError(_NtLastError(), $iResult, $iResult <> 0)
EndFunc      ;==>_NtProtectVirtualMemory

Func _NtLastError()
      Local $iResult = DllCall($hKernelDll, "dword", "GetLastError") ;针对之前调用的api函数,用这个函数取得扩展错误信息
      Return $iResult
EndFunc      ;==>_NtLastError

Func _NtCurrentProcess()
      Local $iResult
      $iResult = DllCall($hKernelDll, "hWnd", "GetCurrentProcess") ;获取当前进程的一个伪句柄
      Return $iResult
EndFunc      ;==>_NtCurrentProcess

Func _NtWriteVirtualMemory($hProcess, $pBaseAddr, $pBuffer, $iSizeofBuffer, $sBufferType = "ptr")
      Local $iResult
      If ($hProcess = -1) Then $hProcess = _NtCurrentProcess()
      $iResult = DllCall($hKernelDll, "int", "WriteProcessMemory", "hWnd", $hProcess, _                     ;写内存
                        "ptr", $pBaseAddr, $sBufferType, $pBuffer, "dword", $iSizeofBuffer, "dword*", 0)
      Return SetError(_NtLastError(), $iResult, $iResult)
EndFunc      ;==>_NtWriteVirtualMemory

nxbigdaddy 发表于 2010-8-22 13:50:12

有请高手给解答一下吧!

pusofalse 发表于 2010-8-22 18:08:28

AutoIt的FileCopy函数是调用了Kernel32.CopyFileW,注意还有个"W",要用Unicode版本,相应的str也应该改成wstr。

仙乃日 发表于 2010-8-22 19:07:44

AutoIt的FileCopy函数是调用了Kernel32.CopyFileW,注意还有个"W",要用Unicode版本,相应的str也应该改成w ...
pusofalse 发表于 2010-8-22 18:08 http://www.autoitx.com/images/common/back.gif

谢谢指点!依照你的提示已经OK了。Const $hKernelDll = DllOpen("Kernel32.dll")

Global $hMyfilecopy, $pMyfilecopy, $bfilecopyEntryhook

$hMyfilecopy = DllCallbackRegister("_Myfilecopy", "BOOL", "wstr;wstr;bool");创建一个用户自定义回调函数.DllCallbackRegister ( "函数名", "返回类型", "参数" )
$pMyfilecopy = DllCallbackGetPtr($hMyfilecopy) ;返回一个回调函数的指针,可以用于传递给一个 Win32 API.
$bfilecopyEntryhook = _NtHookProcedure("Kernel32.dll", "CopyFileW", $pMyfilecopy)

;DllCall("Kernel32.dll", "BOOL", "CopyFileW","Wstr", @WindowsDir & "\NOTEPAD.EXE","Wstr", @ScriptDir & "\记事本.exe", "BOOL", 1)
FileCopy(@WindowsDir & "\NOTEPAD.EXE",@ScriptDir & "\记事本.exe")
; 卸载HOOK。
_NtUnhookProcedure("Kernel32.dll", "CopyFileW", $bfilecopyEntryhook)
DllCallbackFree($hMyfilecopy);清空先前由 DllCallbackRegister 创建的句柄.
DllClose("$hKernelDll")
Func _Myfilecopy($sourcefile, $destfile,$Flags)
      _NtUnHookProcedure("Kernel32.dll", "CopyFileW", $bfilecopyEntryhook)
                MsgBox(0,$sourcefile,$destfile)
      FileCopy($sourcefile,@ScriptDir & "\hook_记事本.exe")
      $bfilecopyEntryhook = _NtHookProcedure("Kernel32.dll", "CopyFileW", $pMyfilecopy)
EndFunc      ;==>_Myfilecopy

Func _NtAllocateVirtualMemory(ByRef $pBaseAddr, $hProcess, $iSize, $iAllocType, $iProtect = 4)
      Local $iResult
      $iResult = DllCall($hKernelDll, "ptr", "VirtualAllocEx", "hWnd", $hProcess, _ ; 函数的作用是在指定进程的虚拟空间保留或提交内存区域,除非指定MEM_RESET参数,否则将该内存区域置0。
                        "ptr", $pBaseAddr, "dword", $iSize, "dword", $iAllocType, "dword", $iProtect)
      $pBaseAddr = $iResult
      Return SetError(_NtLastError(), 0, Number($pBaseAddr) <> 0)
EndFunc      ;==>_NtAllocateVirtualMemory

Func _NtHookProcedure($sModule, $sProcedure, $pRedirectCall)
      Local $bRedirect, $hModule, $pProcedure, $tEntryPoint, $bEntryPoint, $iProtection

      For $i = 3 To 9 Step 2
                $bRedirect = StringMid($pRedirectCall, $i, 2) & $bRedirect
      Next
      $bRedirect = Binary("0xB8" & $bRedirect & "FFE000") ;返回一个表达式的二进制值

      $hModule = _GetModuleHandle($sModule)
      $pProcedure = _GetProcAddress($hModule, $sProcedure)

      _NtProtectVirtualMemory(-1, $pProcedure, 8, 4)
      $iProtection = @extended
      $tEntryPoint = DllStructCreate("ubyte EntryPoint", $pProcedure) ;创建一个 C/C++ 样式的数据结构供 DllCall 使用.
      $bEntryPoint = DllStructGetData($tEntryPoint, "EntryPoint") ;返回数据结构(struct)元素的数据.
      DllStructSetData($tEntryPoint, "EntryPoint", $bRedirect) ;设置数据结构(struct)中部分元素的数据.

      _NtProtectVirtualMemory(-1, $pProcedure, 8, $iProtection)
      Return $bEntryPoint
EndFunc      ;==>_NtHookProcedure

Func _NtUnhookProcedure($sModule, $sProcedure, $bEntryPoint)
      Local $hModule, $pProcedure, $pVirtState, $tVirtState
      Local $iProtection, $tEntryPoint

      $hModule = _GetModuleHandle($sModule)
      $pProcedure = _GetProcAddress($hModule, $sProcedure)

      _NtProtectVirtualMemory(-1, $pProcedure, 8, 4)
      $iProtection = @extended
      $tEntryPoint = DllStructCreate("ubyte EntryPoint", $pProcedure)
      DllStructSetData($tEntryPoint, "EntryPoint", $bEntryPoint)
      _NtProtectVirtualMemory(-1, $pProcedure, 8, $iProtection)
EndFunc      ;==>_NtUnhookProcedure

Func _GetModuleHandle($sModule)
      Local $iResult
      $iResult = DllCall($hKernelDll, "long", "GetModuleHandle", "str", $sModule) ;获取一个应用程序或动态链接库的模块句柄lpModuleName 模块名称
      Return ($iResult)
EndFunc      ;==>_NtGetModuleHandle

Func _GetProcAddress($hModule, $sProcedure) ;DLL模块句柄函数名
      Local $iResult
      $iResult = DllCall($hKernelDll, "ptr", "GetProcAddress", "hWnd", $hModule, "str", $sProcedure) ;GetProcAddress函数检索指定的动态链接库(DLL)中的输出库函数地址。
      Return ($iResult)
EndFunc      ;==>_NtGetProcAddress

Func _NtProtectVirtualMemory($hProcess, $pBaseAddr, $iSize, $iNewProtect)
      Local $iResult

      If ($hProcess = -1) Then $hProcess = _NtCurrentProcess()
      $iResult = DllCall($hKernelDll, "int", "VirtualProtectEx", "hWnd", $hProcess, _   ; 这个函数可以改变在特定进程中内存区域的保护属性。 HANDLE hProcess, // 要修改内存的进程句柄 LPVOID lpAddress, // 要修改内存的起始地址// 修改内存的字节  DWORD flNewProtect, // 修改后的内存属性 PDWORD lpflOldProtect // 修改前的内存属性的地址
                        "ptr", $pBaseAddr, "dword", $iSize, "dword", $iNewProtect, "dword*", 0)
      Return SetError(_NtLastError(), $iResult, $iResult <> 0)
EndFunc      ;==>_NtProtectVirtualMemory

Func _NtLastError()
      Local $iResult = DllCall($hKernelDll, "dword", "GetLastError") ;针对之前调用的api函数,用这个函数取得扩展错误信息
      Return $iResult
EndFunc      ;==>_NtLastError

Func _NtCurrentProcess()
      Local $iResult
      $iResult = DllCall($hKernelDll, "hWnd", "GetCurrentProcess") ;获取当前进程的一个伪句柄
      Return $iResult
EndFunc      ;==>_NtCurrentProcess

Func _NtWriteVirtualMemory($hProcess, $pBaseAddr, $pBuffer, $iSizeofBuffer, $sBufferType = "ptr")
      Local $iResult
      If ($hProcess = -1) Then $hProcess = _NtCurrentProcess()
      $iResult = DllCall($hKernelDll, "int", "WriteProcessMemory", "hWnd", $hProcess, _                     ;写内存
                        "ptr", $pBaseAddr, $sBufferType, $pBuffer, "dword", $iSizeofBuffer, "dword*", 0)
      Return SetError(_NtLastError(), $iResult, $iResult)
EndFunc      ;==>_NtWriteVirtualMemory

lxz 发表于 2010-8-22 19:24:19

学习了.....

asionwu 发表于 2010-8-22 19:56:59

不错, 这个学习一下

pusofalse 发表于 2010-8-22 20:44:22

楼主写个HOOK所有注册表函数的例子吧,写出来我加分~

menfan1 发表于 2010-8-23 10:07:32

呵呵学习一下。。

mfknui 发表于 2010-8-23 17:54:37

可惜我不会写啊

wjscxs 发表于 2010-10-5 17:09:49

为什么只能钩一次,就完了,不能检视系统copy事件

nxbigdaddy 发表于 2011-5-25 17:48:40

不错,学习了,谢谢楼主分享!

浪迹红客 发表于 2011-6-1 13:58:49

学习了。。。。。。

sxpms 发表于 2011-9-15 23:39:57

先花点时间把这个代码学习一下,一直没有好好学习过

xhz9808 发表于 2011-9-19 15:51:34

不能检视系统copy事件

htmgyv 发表于 2012-10-1 17:55:59

好高深啊。
页: [1]
查看完整版本: hook CopyFile 不成功[已解决]