2.7实战“打补丁”更改程序内容
”打补丁“的方法可以修复程序bug,给程序添加新功能,“打补丁”的对象可以是文件、内存、数据、代码......
下面开始讲解如何“打补丁”,首先我们用各种方法,查找main函数,查找到了以后,我们可以看看main函数附近写了些什么
图2-32 push
push,可以理解为“放置”的意思,那他放置了什么呢?举个例子,我们看Hello World!这一行,push后面跟了一串地址0040ED00,而Hello World!本身也有地址,在最左边是00401007,push的意思就是将0040ED00的数据放到00401007这个内存里,接下来去我们在数据区去找0040ED00这个地址
图2-33 数据区
我们先选中数据区,然后摁下快捷键ctrl+G
图2-34 查找地址
可以看到,出来一个窗口让我们输入跟随的地址,我们输入0040ED00,摁下回车,数据区就会跳转到这个地址
图2-35 数据区1
我们点一下上方的“ASCII”,讲数据转换成更直观地方式呈现
图2-36 数据区2
然后我们再将左边的“数值”转换成“hex”
图2-37 hex
下面我们要做的是在右边的unicode区域中选中“Hello World!”修改他的值,但是要注意,我们不逛选择“Hello World!”还要多选后面的一个“点”
图2-38 Hello World!
然后我们鼠标右键,二进制->编辑
图2-39 二进制编辑
弹出来一个窗口,里面一开始是有值的,我们把“保存大小”这个勾去掉,然后删掉“UNICODE”这一栏里面的值,随便重新输入你想输入的值,然后点击确定
图2-40 修改值
修改完值了,我们接下来要做的就是保存这个exe程序,变成我们自己修改后的新的程序,我们选中修改后的部分,再往后面多选一点,多选个“点”,然后鼠标右键->复制到可执行文件
图2-41 复制到可执行文件
这里说明一下,当我们点“复制到可执行文件”之后,就会跳转到上图所示界面,紫色的部分是自动选择好的,我们不需要动,只用鼠标右键->保存文件即可
图2-42 保存文件
之后会弹出一个对话框,让我们选定文件保存的位置
图2-43 文件另存
之后我们点开我们更改后的程序,发现信息框中的内容已经被修改了
图4-44www.mathor.top
2.8另类方法利用缓冲区动态破解
我们上面讲的方法是直接修改缓冲区(数据区)内的值,使他程序被修改,换个思路,我们也可以直接修改push后面的地址,使这个地址指向我们自己写的数据的地址,首先,我们现在缓冲区找一块空白的区域
图4-45 空白缓冲区
然后我们随便选中一块区域,还是按照之前的步骤鼠标右键->二进制->编辑
图4-46 再次二进制编辑
和之前一样,我们修改“UNICODE”内的值,这里我修改成我的群号码689696631,这里记得记住这个地址的位置,应为等会儿我们要把这个地址push进去,我这里地址是0040F730
图4-47 689696631
然后我们还是找到main函数,之前我们已经找过了,并且记得他的地址值是00401000,然后我们找到“Hello World!”这一行的“push”的位置,鼠标右键->汇编
图4-48 汇编
把地址改成我们的地址,0040F730就行了
图4-49 修改地址
修改完成之后,我们按F9运行程序
图4-50 修改后的数据
图4-51 修改后的程序
因为这种方法是动态破解,不是静态的,所以没办法复制到可执行文件,可执行文件加大再到内存中编译进程的形式运行并非原封不动的载入内存,而是遵循一定的规则进行,这一个过程中,进程的内存是的确存在的,但是文件偏移(offset)是不存在的,所以程序无法正常运行,这个以后会讲到
第一部分基础讲解差不多就结束了,我们最后做个小总结
OD常用命令:
指令 | 快捷键 | 说明 |
---|---|---|
Step Into | F7 | 执行一条OP Code(操作码),遇到CALL命令时,进入函数代码内部 |
Step Over | F8 | 执行一条OP Code(操作码),遇到CALL命令时,不进入函数代码内部,仅执行函数本身 |
Restart | Ctrl+F2 | 再次从头调试(终止调试中的进程,重新载入调试程序) |
Go To | Ctrl+G | 跳转到指定地址(查看代码时使用,非运行时命令) |
Run | F9 | 运行(遇到断点时暂停) |
Execute till return | Ctrl+F9 | 执行函数代码内的命令,直到遇到RETN命令,用于跳出函数体 |
Execute till cursor | F4 | 执行到光标所在位置(直接转到要调试的位置) |
Comment | ; | 添加注释 |
汇编基础的一些指令:
指令 | 说明 |
---|---|
CALL XXXX | 调用XXXX地址处的函数 |
JMP XXXX | 跳转到XXXX地址处 |
PUSH XXXX | 保存XXXX到栈 |
RETN | 跳转到栈中保存的地址 |