本帖最后由 爱飞的猫 于 2024-7-27 06:47 编辑
长跳 E9 需要五个字节,将 Hook 点往前挪到 00FF 763C 会好一些。
- VirtualAlloc 申请内存,记为
地址
- 将原本需要 Hook 的地址改成
jmp 地址 ,即 E9 xx xx xx xx 其中 后面四个 xx 为地址偏移。
- 例如在
00FF 763C 跳到 00AA 0000 ,就是 00AA 0000 - (00FF 763C + 5) = 0xffaa89bf ,小端序所以组合起来是 E9 BF 89 AA FF
- 将原始的字节拷贝到
地址 处
- 在地址 + 原始字节后面写出你的 ShellCode,例如
CALL xxxx 字节码是 E8 xx xx xx xx ,一样的算法。
- CALL 之后跳回你的修改点,例如
jmp yyyyyyyy ,一样的算法。
VirtualAlloc 申请的内存写的指令统称为 ShellCode。两边的指令大概是这样:
00FF763F:
jmp 00AA0000
00AA0000:
; 备份的原始指令
add esp, 0x18 ; 这句话其实可以省略
mov esp, ebp
call 00BBCCDD ; 你的函数
; 结束,再跳回去
jmp 0x00ff7641
尝试了下重现你的问题里的流程:
- 启动
目标程序.exe ,然后启动注入器.exe (或注入器源码)
- 透过 VirtualAllocEx 跨进程申请内存 => 用来写出 ShellCode
- ShellCode 放啥都行,别破坏堆栈 / 原始程序需要的寄存器即可
- 执行完指定函数后,想办法回来(
pop ecx; 原始指令; jmp ecx )
- 如果有需要备份的寄存器,应当在一开始就入栈备份,执行完自己的代码后还原。
- 在指定位置写出 CALL (偷懒了,其实 JMP 效果更好,生成 ShellCode 时要多一个步骤)
目标程序.exe 代码执行流程:
- 按下按钮
- 正常执行
- CALL 写出的 ShellCode
- 执行完毕后,回到 CALL 后面的地址
- 继续执行
测试程序+注入代码: https://pan.baidu.com/s/1P7WKZ6H723FH-yzwNcGypw?pwd=g5dn
如果你只是希望能够快速测试你写的 Hook 且找不到好利用的空间,推荐使用 Cheat Engine 的 Auto Assembler 功能,可以一键开关魔改的代码(申请内存、写出代码、改 JMP 三步一气呵成)。
如果你的目标是固定的程序,你可以提前找好一个空间(或你已知程序不会利用的可执行代码空间),然后利用 Multiline Ultimate Assembler 插件(支持 OD、x64dbg)在需要的时候一键全部写出。
|