找回密码
 加入
搜索
查看: 5781|回复: 14

[AU3基础] hook CopyFile 不成功[已解决]

 火.. [复制链接]
发表于 2010-8-22 11:28:45 | 显示全部楼层 |阅读模式
本帖最后由 仙乃日 于 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[0]
        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[8]", $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[8]", $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[0])
EndFunc        ;==>_NtGetModuleHandle

Func _GetProcAddress($hModule, $sProcedure) ;DLL模块句柄  函数名 
        Local $iResult
        $iResult = DllCall($hKernelDll, "ptr", "GetProcAddress", "hWnd", $hModule, "str", $sProcedure) ;GetProcAddress函数检索指定的动态链接库(DLL)中的输出库函数地址。
        Return ($iResult[0])
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[5], $iResult[0] <> 0)
EndFunc        ;==>_NtProtectVirtualMemory

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

Func _NtCurrentProcess()
        Local $iResult
        $iResult = DllCall($hKernelDll, "hWnd", "GetCurrentProcess") ;获取当前进程的一个伪句柄 
        Return $iResult[0]
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[5], $iResult[0])
EndFunc        ;==>_NtWriteVirtualMemory

评分

参与人数 1金钱 +10 收起 理由
afan + 10 感谢主动将修改帖子分类为[已解决],请继续 ...

查看全部评分

发表于 2010-8-22 13:50:12 | 显示全部楼层
有请高手给解答一下吧!
发表于 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


谢谢指点!依照你的提示已经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[0]
        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[8]", $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[8]", $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[0])
EndFunc        ;==>_NtGetModuleHandle

Func _GetProcAddress($hModule, $sProcedure) ;DLL模块句柄  函数名 
        Local $iResult
        $iResult = DllCall($hKernelDll, "ptr", "GetProcAddress", "hWnd", $hModule, "str", $sProcedure) ;GetProcAddress函数检索指定的动态链接库(DLL)中的输出库函数地址。
        Return ($iResult[0])
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[5], $iResult[0] <> 0)
EndFunc        ;==>_NtProtectVirtualMemory

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

Func _NtCurrentProcess()
        Local $iResult
        $iResult = DllCall($hKernelDll, "hWnd", "GetCurrentProcess") ;获取当前进程的一个伪句柄 
        Return $iResult[0]
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[5], $iResult[0])
EndFunc        ;==>_NtWriteVirtualMemory

评分

参与人数 2金钱 +25 贡献 +2 收起 理由
afan + 2
pusofalse + 25

查看全部评分

发表于 2010-8-22 19:24:19 | 显示全部楼层
学习了.....
发表于 2010-8-22 19:56:59 | 显示全部楼层
不错, 这个学习一下
发表于 2010-8-22 20:44:22 | 显示全部楼层
楼主写个HOOK所有注册表函数的例子吧,写出来我加分~
发表于 2010-8-23 10:07:32 | 显示全部楼层
呵呵学习一下。。
发表于 2010-8-23 17:54:37 | 显示全部楼层
可惜我不会写啊
发表于 2010-10-5 17:09:49 | 显示全部楼层
为什么只能钩一次,就完了,不能检视系统copy事件
发表于 2011-5-25 17:48:40 | 显示全部楼层
不错,学习了,谢谢楼主分享!
发表于 2011-6-1 13:58:49 | 显示全部楼层
学习了。。。。。。
发表于 2011-9-15 23:39:57 | 显示全部楼层
先花点时间把这个代码学习一下,一直没有好好学习过
发表于 2011-9-19 15:51:34 | 显示全部楼层
不能检视系统copy事件
发表于 2012-10-1 17:55:59 | 显示全部楼层
好高深啊。
您需要登录后才可以回帖 登录 | 加入

本版积分规则

QQ|手机版|小黑屋|AUTOIT CN ( 鲁ICP备19019924号-1 )谷歌 百度

GMT+8, 2024-6-11 09:43 , Processed in 0.085078 second(s), 25 queries .

Powered by Discuz! X3.5 Licensed

© 2001-2024 Discuz! Team.

快速回复 返回顶部 返回列表