之前写过一篇用OllyDbg做破解, 但是为了获得信息,需要通过OllyDbg调试,在适当的地方设断点,并查看内存,非常麻烦,不要说不懂的人,就算是我刚做过,没过几个礼拜就忘的差不多了。所以如果这个工具要经常性使用,最好还是能做成一个工具:比如能弹出一个对话框显示需要的信息。
这次花了两个晚上搜索、研究、实践了一下,终于搞了出来。
首先,在网上找到一篇非常靠谱的文章,正是exactly我想要的:How to inject code into an exe file, 照其步骤走一遍,弹出一个对话框应该不是问题了。其基本做法是:
- 在空白代码段(操作码为00, 一般在最后)插入对MessageBoxA的调用 - 可通过双击指令逐行修改添加。
- 在需要的信息产生之后的某处,加一行JMP到MessageBoxA调用的地方,当然,MessageBoxA传入的参数是重要信息的地址
- 因为在2出插入代码是实际上是覆盖了原有代码,一般是将被覆盖的代码放到MessageBoxA调用之后,并在最后加一个JMP,跳回其接下来指令的地址。
下面是几个值得注意/记录的地方:
- 传给MessageBoxA的message地址,能不用常量地址就尽量不用,因为其可能是动态算出,在不同的session值是不一样的 - 比如这里,授权码的地址是在寄存器EBX中,那么直接传EBX即可
- 如何保存修改过的exe? RMB->Edit->Select all; RMB->Edit->Copy to executable; In the new window, RMB->save file
- 有时打开后代码格式不是很正常,比如明明是正常的指令,却为解析为数据,可以RMB->Analysis->Remove analysis from module
- 右键jmp指令可以Follow到目标地址
- exe的断点、注释等信息存在:OllyDbg2.1\udd\*.udd文件中
修改代码后直接debug,发现信息是在弹出对话框中显示了出来。但是,当我保存后执行修改过的exe,却怎么也无法工作。Debug进去看了一下,是call MessageBoxA这个函数时出的错,事实上,这个函数调用是针对某个函数地址的,比如:CALL 754DE055, 但检查发现这个地址却是错误的,并不对应到MessageBoxA的加载地址。
为什么?
一番搜索与思考后,觉得这是ASLR的问题,ASLR=Addresss Space Layout Randomization, 他是Windows vista依赖引入的一个新的机制,其使得系统dll在进程中加载的基地址不再是固定的,从而防止用户恶意在exe中插入对windows api的调用 - 而它也确实成功了,对于windows xp与windows 2003, 没有ASLR这个特性,自然也不会有这个问题。
我用的是Windows7的系统,怎么办? 禁掉ASLR!
你需要下载一个叫做Enhanced Mitigation Experience Toolkit(EMET)的工具,安装并运行:
如图所示把ASLR disable掉并重启即可。
然后,插入MessageBoxA并保存,然后运行破解后的代码,一切ok!