若干年之前,曾经年少轻狂,不知天高地厚,研究了一段解密。大话西游2有段时间使用acp什么的加壳(现在情况怎样,早就忘记了),用程序脱壳之后,最有很多代码没能修复。幸好有Ollydbg,也幸好Ollydbg有一大堆辅助的插件。但总是手工修复实在不是人做的事情,于是,就找到了OllyMachine。更大的幸运是OllyMachine是开源的,于是就对它做了些修补,增加了些功能,可以自动将修复好的代码按照一定格式dump出来,这样可以更好的进一步处理。废话就不说了。先是README.txt。
README.txt
注意:
1、将ollymachine.dll放到ollydbg的plug目录中
2、OllyMachine手册中的GetProcAddress的简写是gpa,没有将这个添加到帮助手册中,帮助手册是原来版本。
3、在原来程序的基础上添加了inttostr函数,可以将int类型转成16进制ASCII码,调用之后存放在FreeBufferReg中
使用方法:
invoke inttostr, reg01
4、在原来程序的基础上添加了dumpwitheip….,可以直接用eip的地址dump到文件中,不推荐使用
*.oms为ollymachine的执行脚本
功能介绍:
dumpxy2.oms 执行原始xy2.exe程序可以直接到第一个加密代码的地址。然后可以使用pushad.oms来处理pushad解密代码拦截
pushad.oms 执行原始xy2.exe程序,可以处理pushad和popad执行,但必须人工判断是否是成功了的解密代码地址
modif.oms 执行使用peid脱壳后的程序用来还原代码中加密块
dumpxy2all.oms 执行原始xy2.exe程序开始自动dump程序中加密的代码,单步执行,速度较慢,不用人工参与。dump出来的代码的文件名称就是加密代码的地址,文件的大小就是加密代码的长度。
pushaddump.oms 是dumpxy2all.oms的修正版本,修改了代码加密ret之前的指令不能dump出来的问题
dumpxy2.oms
invoke msg, "隐藏所有异常,恢复脚本运行!" PAUSE HideOD mov reg63, 0 mov reg62, 0 invoke gpa, "GetCurrentDirectoryA", "kernel32.dll" mov reg64, reg00 invoke BP, reg64 invoke run invoke bc, reg64 RunToUserCode invoke find, eip, "60" mov reg64, reg00 invoke LogLong reg64 invoke bp, reg64 invoke run invoke bc, reg64
pushad.oms
mov reg50, 0 start: invoke find, eip, "60" cmp reg00, eip jne nofind cmp reg50, 0 jne nocount mov reg60, eip nocount: mov reg64, esp invoke StepInto sub reg64, 4 invoke BPHWS, reg64, 2 invoke run invoke BPHWC, reg64 jmp end nofind: invoke StepInto jmp start end: invoke MSGYN, "解密完成?" cmp reg00, 1 je dump mov reg50, 1 jmp start dump: invoke find, eip, "60" mov reg63, reg00 mov reg62, reg63 sub reg62, eip invoke GotoCpuAddr reg60 invoke InputText, "输入CPU窗口地址" mov reg30, reg60 invoke WriteMemLong, reg30, 0xE9, 1 add reg30, 1 mov reg20, eip sub reg20, reg60 sub reg20, 5 invoke WriteMemLong, reg30, reg20, 4 invoke DumpMem, reg60, 5, FreeBufferReg invoke GotoCpuAddr eip invoke InputText, "输入CPU窗口地址" invoke DumpMem, eip, reg62, FreeBufferReg invoke PrintBufToNewDump, FreeBufferReg, eip, reg62 invoke bp, reg63 invoke run invoke bc, reg63
modif.oms
invoke InputText, "输入文件名" invoke ReadFileIntoMem, FreeBufferReg, indexof reg01, indexof reg02 mov reg10, reg01 invoke InputHexLong, 0xffffffff, "输入dump的地址" mov reg64, reg00 cmp reg64, 0xffffffff je end write_file_contents: invoke ReadMemLong, reg10, 1 invoke WriteMemLong, reg64, reg00, 1 inc reg10 inc reg64 dec reg02 cmp reg02, 0 jne write_file_contents end: invoke VirtualFreeEx, indexof reg01
dumpxy2all.oms
invoke msg, "隐藏所有异常,恢复脚本运行!" PAUSE HideOD mov reg63, 0 mov reg62, 0 invoke gpa, "GetCurrentDirectoryA", "kernel32.dll" mov reg64, reg00 invoke BP, reg64 invoke run invoke bc, reg64 RunToUserCode invoke find, eip, "60" mov reg64, reg00 invoke LogLong reg64 invoke bp, reg64 invoke run invoke bc, reg64 start: invoke find, eip, "60" cmp reg00, eip jne nofind //cmp reg50, 0 //jne nocount mov reg60, eip //nocount: mov reg64, esp invoke StepInto sub reg64, 4 invoke BPHWS, reg64, 2 invoke run invoke BPHWC, reg64 jmp end nofind: cmp eip,0x07ffffff jnb stepover2 invoke StepInto jmp start stepover2: invoke RunToUserCode jmp start end: //invoke MSGYN, "解密完成?" //cmp reg00, 1 //je dump //mov reg50, 1 //jmp start invoke inttostr, reg60 mov reg30, reg60 invoke readmemlong, reg30,4 mov reg40, reg00 mov reg31, reg30 add reg31, 4 xor reg41,reg41 invoke readmemlong, reg31, 1 mov reg41,reg00 invoke WriteMemLong, reg30, 0xE9, 1 add reg30, 1 mov reg20, eip sub reg20, reg60 sub reg20, 5 invoke WriteMemLong, reg30, reg20, 4 invoke DumpMem, reg60, 5, FreeBufferReg invoke WriteMemLong, reg60, reg40, 4 invoke WriteMemLong, reg31, reg41, 1 invoke find, eip, "60" mov reg20,reg00 invoke find, eip, "C3" mov reg21,reg00 invoke find,eip, "c2" mov reg22,reg00 invoke find,eip,"ca" mov reg23,reg00 invoke find,eip,"cb" mov reg24,reg00 cmp reg21,reg22 jb comp1 mov reg21,reg22 comp1: cmp reg21,reg23 jb comp2 mov reg21,reg23 comp2: cmp reg21,reg24 jb comp3 mov reg21,reg24 comp3: cmp reg20,reg21 jb dumpwork jmp start dumpwork: sub reg20,eip invoke inttostr,eip invoke dumpmem,eip,reg20,freeBufferReg jmp start
pushaddump.oms
start: invoke find, eip, "60" cmp reg00, eip jne nofind //cmp reg50, 0 //jne nocount mov reg60, eip //nocount: mov reg64, esp invoke StepInto sub reg64, 4 invoke BPHWS, reg64, 2 invoke run invoke BPHWC, reg64 jmp end nofind: cmp eip,0x70000000 jnb stepover2 invoke StepInto jmp start stepover2: invoke RunToUserCode jmp start end: //invoke MSGYN, "解密完成?" //cmp reg00, 1 //je dump //mov reg50, 1 //jmp start invoke inttostr, reg60 mov reg30, reg60 invoke WriteMemLong, reg30, 0xE9, 1 add reg30, 1 mov reg20, eip sub reg20, reg60 sub reg20, 5 invoke WriteMemLong, reg30, reg20, 4 invoke DumpMem, reg60, 5, FreeBufferReg invoke find, eip, "60" mov reg20,reg00 //invoke find, eip, "C3" //mov reg21,reg00 //invoke find,eip, "c2" //mov reg22,reg00 //invoke find,eip,"ca" //mov reg23,reg00 //invoke find,eip,"cb" //mov reg24,reg00 //cmp reg21,reg22 //jb comp1 //mov reg21,reg22 //comp1: //cmp reg21,reg23 //jb comp2 //mov reg21,reg23 //comp2: //cmp reg21,reg24 //jb comp3 //mov reg21,reg24 //comp3: //cmp reg20,reg21 //jb dumpwork //jmp start //dumpwork: sub reg20,eip invoke inttostr,eip invoke dumpmem,eip,reg20,freeBufferReg jmp start
OllyMachine的修改后的src在这里:OllyMachine_src_0.20.7z
这个是很早年代的产物了,里面的说明我自己现在也是迷迷糊糊的。也并未细看,脚本和代码也完全送上,有需要的人可以研究下。
PS:在整理资源的时候才发现原来OllyMachine是GPL协议,早年不注意的内容实在是太多了,罪过罪过。