背景
之前分析windows异常捕获时接触到一个hook api 重定向了SetUnhandledExceptionFilter函数,当时并不熟悉,现在刚好抽点时间可以研究下,并自己手动实现了一个远程dll注入,并修改指定exe函数的实现。
效果
- hooktest.exe 里面的某个函数被修改为其他函数实现,如下是hooktest的源码
1 | void testOutPut() |
当输入键盘任意按钮时,输出”hook test”,但是当我注入dll后,按下按键输出”dealHookFunc succ”,效果如下1
2
3
4
5
6
7
8a
hook test
hook in
a
dealHookFunc succ
hook out
a
hook test
过程
因为是远程注入,需要一个load.exe(loaddll.exe) 、一个 hook.dll(xxxx.dll)、一个被注入程序hooktest.exe
三个项目的源码如下
loaddll.exe
该程序主要功能主要是注入xxxx.dll 到指定目标中
找到指定exe的pid
判断是否有重复注入
打开目标进程
获取LoadLibrary地址
CreateRemoteThread 动态加载xxxx.dll
xxxx.dll
触发dllmain DLL_PROCESS_ATTACH 时,修改进程的内存机器码
DLL_PROCESS_DETACH 时,还原进程的机器码
testOutPut 函数地址
- 通过 ida 工具分析hooktest.exe 的信息,很容易找到testOutPut 函数的偏移地址为 0x80
修改汇编代码
1 | hooktest!testOutPut: |
因为是无条件跳转,所以只要把 00cf1080 开始之后的地址修改为1
2jmp 目标地址 // 5个字节
rent // 1个字节
1 | BYTE hookCode[32] = { 0 }; |
修改后的汇编代码
1 | hooktest!testOutPut: |
跳转地址
jmp指令所指向的地址是个相对地址,所以真实的目标地址为1
hook函数的地址 - 被hook函数的地址 - 5 ; // 5是指指令(jmp 0x12345678)的长度
被hook函数地址
1 | 模块基础地址 + virtual address + 偏移地址 |
修改内存内容
1 | DWORD baseAddress = (DWORD)GetModuleHandle(NULL); |
总结
这个程序只是简单的说明,希望对你有帮助。