小甲鱼 OllyDbg 视频教程:https://www.bilibili.com/video/av6889190?p=19
程序下载地址:https://pan.baidu.com/s/1u6SWgx83VWDwitNzxT2OXg 提取码:if41
PEiD 查壳工具:https://pan.baidu.com/s/1iNS4UlBvmXCxaj5a-AFupw 提取码:79z5
前言
inline patch “内嵌补丁” 指在程序文件中把补丁代码写入文件里面达到 PJ 的目的。
例:
原程序: mov eax, dword ptr [ebp+8] 3个字节
想改为: mov eax, 4 5个字节
若如此修改,会产生溢出,覆盖了下面的指令
所以要采用内嵌补丁的方式:
1. 找程序的空白区间,写入自己需要的指令(mov eax, 4),以及会被覆盖的指令
2.将原来的指令(mov eax, dword ptr [ebp+8])改为 jmp XXXXXX(补丁的地址)(这个操作也会覆盖后面的内容)
3.在补丁最后加上 jmp XXXXXXX(原程序后面的内容的地址),跳出补丁,返回主程序
开始
首先用 PEiD 查看,可以看到是 VC6.0 写的程序:
然后用 OD 载入程序,按 F9 运行,程序运行,然后随便输入注册:
发现程序界面没什么反应,现在输入注册码,不要点击 OK。打开 OD ,按下 Ctrl + n ,输入 killtimer,查找 KillTimer
,右键 -》 在每个参考上设置断点
为什么要在 KillTimer 上设置断点呢?通过观察发现了,KillTimer 实现了类似C语言的 switch case 的效果
点击 cmp eax, 3 ,在数据窗口可以看到 是从哪个位置跳转过过来的,然后右键 转到 上级调用地址,按这种方法直到回溯到程序的开头
回溯到 程序头,即switch case ,然后加上断点
在向上看程序,函数的开头加个断点:
重新载入程序,让程序在函数开头的位置断下来,按 F8 单步调试,观察 eax 的值的变化:
解释:
所以就需要用到 内嵌补丁 来进行修补。什么是内嵌补丁,就是在程序中没用的内存空间写入补丁。因为程序在内存中都是需要内存对齐的,所以有些没用的空间都是用 0 来填充进行对齐,可以在这些地方写入补丁(这里写入地址为 5E47D0):
快速定位技巧:设置书签
记住位置或者设置书签,复制被覆盖的汇编代码:
原来位置的修改:
跳转到要写入内嵌补丁的位置,开始写入补丁:
粘贴被覆盖的代码,然后再跳转到原来的位置:
保存修改,然后运行程序,发现程序一直死循环。说明程序还有问题,冲洗载入程序,单步调试,当程序运行到 cmp eax,4 时,更改 ZF 标志位,让程序跳转实现,然后继续调试,发现当程序 执行 cmd eax,0B 时,程序正常。所以修改补丁位置 mov eax,4 位 mov eax, 0B
保存程序,然后运行程序,发现程序正常。
说明:当程序 mov eax,4 时,验证成功,但是验证成功后还的 mov eax,0B 跳出循环,所以当 mov eax,4 时,虽然验证成功,但是没有跳出循环,所以一直跳出窗口。