吾爱破解 - LCG - LSG |安卓破解|病毒分析|www.52pojie.cn

 找回密码
 注册[Register]

QQ登录

只需一步,快速开始

查看: 12836|回复: 8
收起左侧

[原创] 吾爱破解脱壳练习----PUNiSHER 1.5

 关闭 [复制链接]
小生我怕怕 发表于 2008-10-27 00:11
一转眼我们的脱壳练习已经第19期啦,在这其中我相信许多的朋友也学习到了东西
必能脱掉此壳
本期考核主题为:PUNiSHER 1.5
1.脱壳后的文件大家以千脑形式上传,目的是为了便于隐藏文件和节约论坛空间
2.脱壳后的文件,请大家以脱文附带脱壳后程序打包压缩传于千脑网盘
3.对于回帖过程中千万不要出现灌水,否则BAN了ID
4.对于有优秀脱文或优秀脱壳方法的朋友,给于适当威望奖励
5.鉴于此练习是针对论坛的所有人,请大家踊跃参加,如果不是脱了壳教作业的,请不要顶帖子,方便管理查阅,及时给出评分
6.以下为需要设置威望的格式
7.脱壳一以周期计算,(周期=等于二天)
8.脱壳周期一结束,就开始公布答案让大家能有更充分的学习环境,让不懂脱的朋友去寻找你失误的地方争取早日赶上论坛的积极份子
9.我们要的是脱文,并不是脱壳机去脱的,如果用脱机脱了别拿来,请一定附带上脱文
10.我们讲对每次脱壳练习选择一个最好的脱壳分析过程,方便大家学习,每次脱壳练习结束后会说出楼数,对于被选种的朋友,我们会酌情给予CB或者威望进行奖励
11.由于前段时间我们的练习群开放式验证加入,导致群在短短几天爆满,现在已经清除了所有没有参加练习的朋友,以后只要参加我们一次练习就会收到我们的短消息邀请加入
平时我们都是关闭模式

12.本期看点:熟悉入口特征,针对被抽取的OEP进行简单有效的填补!



公告:
暂无


紧急通知:
本期练习由于交作业的情况不是非常满意,特决定将本期练习延期一天,让更多的朋友有充裕的时间去进行整理分析,争取拿出更好的答案

练习一:(结果已经公布)
http://www.52pojie.cn/thread-10496-1-1.html
最佳分析:第10楼unpack

练习二:(结果已经公布)
http://www.52pojie.cn/thread-10607-1-1.html
最佳分析:第9楼lqiulu

练习三:(结果已经公布)
http://www.52pojie.cn/thread-10688-1-1.html
最佳分析:第11楼傻人有傻福

练习四:(结果已经公布)
http://www.52pojie.cn/thread-10850-1-1.html
最佳分析:第11楼维护世界和平

练习五:(结果已经公布)
http://www.52pojie.cn/thread-10990-1-1.html
最佳分析:第3楼维护世界和平

练习六:(结果已经公布)
http://www.52pojie.cn/thread-11112-1-1.html
最佳分析:第12楼ximo

练习七:(结果已经公布)
http://www.52pojie.cn/thread-11244-1-1.html
最佳分析:第14楼傻人有傻福

练习八:(结果已经公布)
http://www.52pojie.cn/thread-11306-1-1.html
最佳分析: 第15楼unpack

练习九:(结果已经公布)
http://www.52pojie.cn/thread-11446-1-1.html
最佳分析: 第1楼小生我怕怕

练习十:(结果已经公布)
http://www.52pojie.cn/thread-11585-1-1.html
最佳分析:第10楼unpack

练习十一:(结果已经公布)
http://www.52pojie.cn/thread-11747-1-1.html
最佳分析:第9楼unpack

练习十二:(结果已经公布)
http://www.52pojie.cn/thread-11883-1-1.html
最佳分析:第19楼unpack

练习十三:(结果已经公布)
http://www.52pojie.cn/thread-12011-1-1.html
最佳分析:第1楼小生我怕怕

练习十四:(结果已经公布)
http://www.52pojie.cn/thread-12135-1-1.html
最佳分析:第3楼 qiulu

练习十五:(结果已经公布)
http://www.52pojie.cn/thread-12279-1-1.html
最佳分析:第13楼pcfans

练习十六:(结果已经公布)
http://www.52pojie.cn/thread-12362-1-1.html
最佳分析:第18楼unpack

练习十七:(结果已经公布)
http://www.52pojie.cn/thread-12498-1-1.html
最佳分析:第6楼 aisht

练习十八:(结果已经公布)
http://www.52pojie.cn/thread-12620-1-1.html
最佳分析:第8楼 unpack

UnPackMe.rar

14 KB, 下载次数: 439, 下载积分: 吾爱币 -1 CB

发帖前要善用论坛搜索功能,那里可能会有你要找的答案或者已经有人发布过相同内容了,请勿重复发帖。

unpack 发表于 2008-10-28 17:04
OD载入,忽略所有异常,然后载入出现错误,直接点确定,停在
00408061 > /EB 04 jmp short 0040806700408063 |83A4BC CE60EB04>and dword ptr [esp+edi*4+4EB60CE], F>0040806BBC 0411E800 mov esp, 0E81104004080700000add [eax], al004080720081 2C24CAC2 add [ecx+C2CA242C], al0040807841inc ecx

花指令很多,不会搞,直接下断点 HE LoadLibraryA
然后shift+f9运行三次来到
7C801D77 >8BFFmov edi, edi7C801D7955pushebp7C801D7A8BECmov ebp, esp7C801D7C837D 08 00cmp dword ptr [ebp+8], 07C801D8053pushebx7C801D8156pushesi7C801D8274 14 jeshort 7C801D98
堆栈窗口显示

第一次
0012FF9C 004083EC/CALL 到 LoadLibraryA 来自 UnPackMe.004083E60012FFA0 0040821F\FileName = "USER32.DLL"0012FFA4 7C930738ntdll.7C930738

第二次
0012E998 73FBE21F/CALL 到 LoadLibraryA 来自 USP10.73FBE2190012E99C 73FA1850\FileName = "gdi32.dll"0012E9A0 73FA0000USP10.73FA0000
第三次:
0012FF9C 003C0470/CALL 到 LoadLibraryA 来自 003C046A0012FFA0 003C00B7\FileName = "USER32.DLL"0012FFA4 7C930738ntdll.7C930738
然后取消断点,alt+f9返回
003C0470BB 25459C9A mov ebx, 9A9C4525003C04758BD0mov edx, eax003C0477E8 0B000000 call003C0487003C047C8985 23CE4100 mov [ebp+41CE23], eax003C0482E9 71020000 jmp 003C06F8
F8单步走,这个跳到了
003C06F883C4 E0 add esp, -20003C06FBE8 00000000 call003C0700003C07005Dpop ebp003C070160pushad
然后来到
003C07558A95 DDCE4100 mov dl, [ebp+41CEDD]003C075B301439xor [ecx+edi], dl003C075E^ E2 FB loopd short 003C075B003C0760301439xor [ecx+edi], dl; //f4
接着走
003C07B98DBC0D 54CE4100 lea edi, [ebp+ecx+41CE54]003C07C0833F 00 cmp dword ptr [edi], 0003C07C3^ 0F85 56FFFFFF jnz 003C071F003C07C98A85 B4CE4100 mov al, [ebp+41CEB4] ; //f4
到这儿的时候堆栈和寄存器中可以看到MFC42.DLL
003C081A03F1add esi, ecx003C081C03C1add eax, ecx003C081E50pusheax003C081F03D9add ebx, ecx ; UnPackMe.00400000003C0821FF95 2FCE4100 call[ebp+41CE2F] ; kernel32.LoadLibraryA003C08278BD0mov edx, eax ; MFC42.#1489003C082983FA FF cmp edx, -1003C082C74 49 jeshort 003C0877 ; //这个不跳
然后
003C0857FF95 27CE4100 call[ebp+41CE27]003C085D5Apop edx; MFC42.#1489
这个在寄存器,堆栈中出现函数
0012FF3C 73D30000offset MFC42.#14890012FF40 73D98D67MFC42.#4486_CWinApp::OnDDECommand0012FF44 73D30000offset MFC42.#1489

003C08618907mov [edi], eax ; MFC42.#4486_CWinApp::OnDDECommand

这句就把函数给了相应的地址了~~~~
003C086E85C0testeax, eax003C08708D1C08lea ebx, [eax+ecx]003C0873^ 75 CE jnz short 003C0843
这里是个循环,然后一直恢复函数给地址了,但是还有些地方没有出现,不知道这个循环出现在那个问题中

接着还有一个循环
003C088A^\0F85 77FFFFFF jnz 003C0807003C0890EB 33 jmp short 003C08C5003C089225 73257325 and eax, 25732573

从跟踪的看,是不断取DLL文件,然后再在上面的循环加载函数了



然后来到这个地方,
003C08C58D85 ADD64100 lea eax, [ebp+41D6AD]003C08CB870424xchg[esp], eax003C08CEFF95 E1CE4100 call[ebp+41CEE1] ; kernel32.OutputDebugStringA003C08D480BD E9CE4100 00cmp byte ptr [ebp+41CEE9], 0
在003C08C5处的时候信息窗口显示

地址=003C0892, (ASCII "%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s")
eax=00402494 (UnPackMe.00402494)

不知道什么意思,看看堆栈
0012FF48 003C0892ASCII "%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s"0012FF4C 003F0FFC0012FF50 FFFA31E50012FF54 00001000
根据这个解释看,应该是把这个字符串给eax,然后跟[ESP]交换了,也就是ESP就变成了乱码,那么就是说到OEP入口的跳转地方,如jmp、retn、push这些加OEP的时候,就会OutputDebugStringA,退出调试器字符串了吧
所以这两句一看就应该是NOP掉的

所以这个地方可以用作这个壳的特征搜索码了:87 04 24 FF 95 E1 CE 41 00 80 BD E9 CE 41 00 00
需要改成87 04 24 FF 95 ?? ?? ?? ?? 80 BD ?? ?? ?? ?? 00
因为[ebp+41CEE1]和byte ptr [ebp+41CEE9]这两个由于不同程序,所以就不一样了
,这样NOP掉后变成了
003C08C58D85 ADD64100 lea eax, [ebp+41D6AD]003C08CB90nop003C08CC90nop003C08CD90nop003C08CE90nop003C08CF90nop003C08D090nop003C08D190nop003C08D290nop003C08D390nop003C08D480BD E9CE4100 0>cmp byte ptr [ebp+41CEE9], 0003C08DB74 77 jeshort 003C0954



继续走

003C08DB /74 77 jeshort 003C0954
003C08DD |EB 34 jmp short 003C0913 ; //又是花指令,跳到不知云深处,跟下去

很变态啊 ,花指令如此之多啊
003C09138D85 1DD74100 lea eax, [ebp+41D71D]003C091950pusheax003C091A6A 01 push1003C091C6A 00 push0003C091EFF95 E5CE4100 call[ebp+41CEE5] ; kernel32.CreateMutexA


003C0913这一行显示什么,信息窗口看看

地址=003C0902, (ASCII "ycmoE7cummS9cSMG")
eax=003C0892, (ASCII "%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s")

不明白哦,只知道把前面的字母和数字个了EAX,也就是说EAX中不存放%S这些字符了


继续吧

003C09303D B7000000 cmp eax, 0B7
003C093575 1D jnz short 003C0954

跳了
003C0954 /E9 DF000000 jmp 003C0A38003C0959 |8B85 EACE4100 mov eax, [ebp+41CEEA]003C095F |8D9D FEDC4100 lea ebx, [ebp+41DCFE]003C0965 |50pusheax
跳向何处???
003C0A3880BD CDCE4100 00cmp byte ptr [ebp+41CECD], 0003C0A3F0F84 D9000000 je003C0B1E ; //不跳的哦003C0A458B8D C9CE4100 mov ecx, [ebp+41CEC9]

接着看
003C0A8483F8 03 cmp eax, 3003C0A8775 02 jnz short 003C0A8B003C0A89EB 54 jmp short 003C0ADF003C0A8B83F8 0E cmp eax, 0E003C0A8E75 02 jnz short 003C0A92003C0A90EB 4D jmp short 003C0ADF003C0A9283F8 0A cmp eax, 0A003C0A9575 02 jnz short 003C0A99003C0A97EB 46 jmp short 003C0ADF003C0A9983F8 18 cmp eax, 18003C0A9C75 02 jnz short 003C0AA0003C0A9EEB 3F jmp short 003C0ADF003C0AA083F8 10 cmp eax, 10003C0AA375 02 jnz short 003C0AA7003C0AA5EB 38 jmp short 003C0ADF
这几个jnz都没有跳,不管、

003C0AC8^\EB 9D jmp short 003C0A67
003C0ACA8B30mov esi, [eax] ; //f4

有一个循环,F4过
003C0B11FFB5 50CE4100 pushdword ptr [ebp+41CE50]003C0B17E8 B5FEFFFF call003C09D1003C0B1C^ EB BF jmp short 003C0ADD ; //这里有一个循环,直接下一行F4003C0B1E^ E9 36FEFFFF jmp 003C0959 ; //这里F4了,网上跳的,跳转比较大,所以不用再F4了
然后003C0B1E跳向了
003C09598B85 EACE4100 mov eax, [ebp+41CEEA]003C095F8D9D FEDC4100 lea ebx, [ebp+41DCFE]003C096550pusheax003C0966E8 0E000000 call003C0979003C096B50pusheax; //这个得到一个地址003C096C53pushebx003C096DE8 8EF7FFFF call003C0100003C097283C4 08 add esp, 8003C0975- FF6424 FC jmp [esp-4]; //跳向刚刚上面的地址了003C097960 pushad003C097AEB 04jmp short 003C0980

所以可以搜索的特征码为:FF 64 24 FC 60 EB 04


然后JMP进入后来到
009D0000 /EB 04 jmp short 009D0006009D0002 |8182 8241D9EE EB04838>add dword ptr [edx+EED94182], 8C8304>009D000C8C82 DB5C24FC mov [edx+FC245CDB], es009D0012EB 04 jmp short 009D0018
又是花指令了,如果我们单步走过的话,是可以到加的OEP的,也就是被抽取了代码的OEP了,所以这些花指令的地方就是被抽取代码的地方了~~~~~~,还是一步一步把这些代码找到吧


F8单步了!
009D0006D9EE fldz009D000EDB5C24 FCfistp dword ptr [esp-4]009D00188B5C24 FCmov ebx, [esp-4]
这几句看看:FLDZ 浮点加载零 ;FISTP 浮点保存整数出栈 ;那么这些就可以看出,[ESP-4]的值先给了00000000,然后再给EBX,也就是ebx==00000000


此时寄存器的数据记下:
EAX 00000417ECX 00000000EDX 7C92EB94 ntdll.KiFastSystemCallRetEBX 003C0EE3ESP 0012FF48EBP FFFA31E5ESI 00404038 UnPackMe.00404038EDI 00407B90 UnPackMe.00407B90EIP 009D0018
堆栈显示
0012FF44 00000000
0012FF48 003C0051 //记住,这个地方是ESP-4
0012FF4C 003F0FFC

此时ESP显示的数值是0012FF48,然后
继续单步开始分析偷取的代码:

1、
009D00226A 00push0; //这里相当于给压入ESP地址了经过这一步后,也就是说把0012FF44压入到ESP中,也就是ESP显示为0012FF44了,可以看寄存器中看到,下面就是分析到底压入了PUSH ****是寄存器中的哪一个!009D002A87DC xchgesp, ebx009D003287EE xchgesi, ebp009D003A93 xchgeax, ebx009D00418930 mov [eax], esi//到这句的时候可以知道,经过交换,已经吧ESP的值给了EAX,也就是此时[EAX]就表示一个地址了,也就是说把ESI的值给了[EAX]这个地址,而此时ESI的值为EBP的值,也就说此时堆栈显示的0012FF44后面的数值就是ESI即开始给出的寄存器中EBP的值,也就可以确定偷取的第一行就是PUSH EBP009D004993 xchgeax, ebx009D005087EE xchgesi, ebp ; UnPackMe.00404038009D005887DC xchgesp, ebx009D006090 nop呵呵后面的三句就是要恢复现场了,O(∩_∩)O哈哈~也就是找到第一句了PUSH EBP
2、
009D006750 pusheax //把EAX压栈,占据的地址是0012FF40009D006E53 pushebx //把EBX压栈,占据的地址是0012FF3C,遵循先进后出,地址减4009D007554 pushesp //同样了,ESP占据的是0012FF38009D007C55 pushebp 009D008357 pushedi; UnPackMe.00407B90009D008A56 pushesi; UnPackMe.00404038009D0091FF7424 0Cpushdword ptr [esp+C]到这儿,看看堆栈0012FF2C 00404038UnPackMe.004040380012FF30 00407B90UnPackMe.00407B900012FF34 FFFA31E50012FF38 0012FF3C0012FF3C 000000000012FF40 00000417也就是说PUSH DWORD PTR [ESP+C],此时[ESP]为0012FF2C,那么[ESP+C]就是0012FF38了,信息窗口显示堆栈 ss:[0012FF38]=0012FF3C然后压入堆栈后,给入[ESP+C]的地址就是 0012FF28 0012FF3C继续:009D009B830424 08add dword ptr [esp], 8 //此时的[ESP]的地址处的值+8也就是0012FF44009D00A55D pop ebp; 0012FF44 //这就可以看到了,EBP出栈,给的值就是刚刚入栈的了,就是0012FF44009D00AC83C4 18add esp, 18 //ESP+18的压栈地址就是0012FF2C+18==0012FF44,此时的最外的地址就是012FF244了009D00B590 nop这样完了,分析下这个过程,就是MOV EBP,ESP为什么呢?还记得分析这句前的压栈的地址可以知道0012FF44 FFFA31E50012FF48 003C0051就是0012FF44,也就是那时的ESP的数值为0012FF44,而经过这样折腾,POP出栈时的地址就是0012FF44了,其作用就是如此了故第二句被偷取的就是MOV EBP,ESP
3、
009D00C8E8 00000000call009D00CD经这句,此时ESP显示就是EAX 00000417ECX 00000000EDX 7C92EB94 ntdll.KiFastSystemCallRetEBX 00000000ESP 0012FF40EBP 0012FF44ESI 00404038 UnPackMe.00404038EDI 00407B90 UnPackMe.00407B90EIP 009D00CD先放着,待会有用,也就是说这个call后,也是单步过后猜的,就是使[ESP]==009D00CD009D00D3812C24 A6B64100sub dword ptr [esp], 41B6A6//009D00CD-41B6A6=005B4A27009D00E0810424 97B64100add dword ptr [esp], 41B697//005B4A27+41B697=009D00BE009D00ED83C4 04add esp, 4//ESP显示就是0012FF44了009D00F68B4424 FCmov eax, [esp-4]//把[ESP-4]也就是009D00BE给EAX了009D01008B00 mov eax, [eax]//此时可以在寄存器中的EAX上数据跟随,得知[EAX]即[009D00BE]=156783AA,就是说EAX在寄存器显示就是156783AA009D0108894424 FCmov [esp-4], eax //麻烦,把156783AA给[ESP-4],即0012FF40了,堆栈看看0012FF40 156783AA0012FF44 FFFA31E5009D0112817424 FC 55836715 xor dword ptr [esp-4], 15678355//[ESP-4]==156783AA xor 15678355==000000FF009D012083EC 04sub esp, 4 //esp-4就是0012FF40了,009D012390 nop这些乱七八糟的分析出来相当于第三行偷取的代码push -1

4、
009D0136E8 00000000call009D013B009D013BEB 04jmp short 009D0141同样,此时ESP就是0012FF3C了,其[ESP]==009D013B寄存器显示:EAX 156783AAECX 00000000EDX 7C92EB94 ntdll.KiFastSystemCallRetEBX 00000000ESP 0012FF40EBP 0012FF44ESI 00404038 UnPackMe.00404038EDI 00407B90 UnPackMe.00407B90EIP 009D015E继续下面的分析009D0141812C24 26B74100sub dword ptr [esp], 41B726//009D013B-41B726==005B4A15009D014E810424 17B74100add dword ptr [esp], 41B717//005B4A15+41B717==009D012C009D015B83C4 04add esp, 4 //ESP==0012FF40009D0164894424 D8mov [esp-28], eax//ESP-28==12FF18,即12FF18显示EAX的值156783AA009D016E8B4424 FCmov eax, [esp-4] //EAX的值在寄存器中显示009D012C009D01788B00 mov eax, [eax] //009D012C在数据窗口跟随的到[009D012C]=457517B5009D018035 65343545xor eax, 45353465//457517B5xor45353465==004023D0009D018B894424 FCmov [esp-4], eax; UnPackMe.004023D0//怎么样,把004023D0放入0012FF3C009D01958B4424 D8mov eax, [esp-28] //恢复现场,把刚刚EAX的值返回来009D019F83C4 FCadd esp, -4//把ESP定位到地址0012FF3C去009D01A890 nop这些句子就相当于 PUSH 004023D0
5、
009D01BBE8 00000000call009D01C0009D01C0EB 04jmp short 009D01C6009D01C6812C24 26B74100sub dword ptr [esp], 41B726009D01D3810424 17B74100add dword ptr [esp], 41B717009D01E083C4 04add esp, 4009D01E9894424 D8mov [esp-28], eax009D01F38B4424 FCmov eax, [esp-4]009D01FD8B00 mov eax, [eax]009D020535 65343545xor eax, 45353465009D0210894424 FCmov [esp-4], eax ; UnPackMe.00401616009D021A8B4424 D8mov eax, [esp-28]009D022483C4 FCadd esp, -4009D022D90 nop跟上面一样了,那么这些就相当与PUSH 004016166、009D022E64:A1 00000000 mov eax, fs:[0]009D023450 pusheax009D023564:8925 00000000 mov fs:[0], esp009D023C83EC 68sub esp, 68009D023F53 pushebx009D024056 pushesi009D024157 pushedi009D02428965 E8mov [ebp-18], esp009D024533DB xor ebx, ebx009D0247895D FCmov [ebp-4], ebx这些就是没有加花指令的,直接偷取了放在这儿二进制为64 A1 00 00 00 00 50 64 89 25 00 00 00 00 83 EC 68 53 56 57 89 65 E8 33 DB 89 5D FC
7、
009D025CE8 00000000call009D0261009D0261EB 04jmp short 009D0267经过这个,看看寄存器EAX 0012FF5CECX 00000000EDX 7C92EB94 ntdll.KiFastSystemCallRetEBX 00000000ESP 0012FEBCEBP 0012FF44ESI 00404038 UnPackMe.00404038EDI 00407B90 UnPackMe.00407B90EIP 009D0267接着分析009D0267812C24 A6B64100sub dword ptr [esp], 41B6A6009D0274810424 97B64100add dword ptr [esp], 41B697009D028183C4 04add esp, 4009D028A8B4424 FCmov eax, [esp-4]009D02948B00 mov eax, [eax]009D029C894424 FCmov [esp-4], eax009D02A6817424 FC 55836715 xor dword ptr [esp-4], 15678355009D02B483EC 04sub esp, 4009D02B790 nop这句分析的结果跟上面一样,相当于偷取的代码为PUSH 00000002
8、
009D02B8FF15 7C214000call[40217C] ; msvcrt.__set_app_type009D02BE59 pop ecx009D02BF830D 3C314000 FF ordword ptr [40313C], FFFFFFFF009D02C6830D 40314000 FF ordword ptr [403140], FFFFFFFF009D02CDFF15 78214000call[402178] ; msvcrt.__p__fmode009D02D38B0D 30314000mov ecx, [403130]009D02D98908 mov [eax], ecx009D02DBFF15 74214000call[402174] ; msvcrt.__p__commode009D02E18B0D 2C314000mov ecx, [40312C]009D02E78908 mov [eax], ecx009D02E9A1 70214000mov eax, [402170]009D02EE8B00 mov eax, [eax]009D02F0A3 38314000mov [403138], eax又是全部被偷取的了二进制为FF 15 7C 21 40 00 59 83 0D 3C 31 40 00 FF 83 0D 40 31 40 00 FF FF 15 78 21 40 00 8B 0D 30 31 4000 89 08 FF 15 74 21 40 00 8B 0D 2C 31 40 00 89 08 A1 70 21 40 00 8B 00 A3 38 31 40 00
9、
009D0301E8 06000000call009D030C //这个F7009D0306EB 04jmp short 009D030C记下寄存器:EAX 00000000ECX 00000000EDX 7C92EB94 ntdll.KiFastSystemCallRetEBX 00000000ESP 0012FEBCEBP 0012FF44ESI 00404038 UnPackMe.00404038EDI 00407B90 UnPackMe.00407B90EIP 009D0312分析代码009D0312FF3424 pushdword ptr [esp] //压栈,同时也把[ESP]存放的值也给了此时压栈后的ESP了009D031B812C24 12B44100sub dword ptr [esp], 41B412009D0328810424 FDB34100add dword ptr [esp], 41B3FD009D0335830424 06add dword ptr [esp], 6009D033F55 pushebp009D034660 pushad//花指令开始009D034D6A 00push0009D035568 0F31C208push8C2310F009D0360FFD4 callesp009D03688BC8 mov ecx, eax009D037C0F31 rdtsc009D03842BC1 sub eax, ecx009D038C66:3D FF0F cmp ax, 0FFF009D03AC2BC0 sub eax, eax009D03B4FD std009D03BB6A 00push0009D03C961 popad//花指令结束,没有什么意义,干扰而已 009D03D08B6C24 04mov ebp, [esp+4]009D03DA8B6D 00 mov ebp, [ebp] ; UnPackMe.00401615009D03E3896C24 04mov [esp+4], ebp009D03ED5D pop ebp009D03F4814424 04 FD000000 add dword ptr [esp+4], 0FD009D0402C3retn009D040990 nop在RETN处,显示的是00401615,也就说,这个retn先到了00401615而00401615C3retn//返回到009D0403那么把花指令撇开,分析得到,先PUSH在RETN,相当于CALL 地址了所以这就相当于偷取了 call 00401615分析如果在这里我们F8单步的话,根本到不了OEP处,为什么呢??因为花指令处有一个垃圾代码rdtsc,就是这个了,如果我们根本不知道有这个垃圾代码的话,我们直接将这行花指令直接NOP掉,一到那个花指令处就NOP掉;如果你跟踪过,也可以这样来,进入这个抽取代码的地方的时候,我们查找地址:009D03D0 直接下断,然后再shift+f9运行,这样也可避开花指令了!如果知道RDTSC是垃圾代码的话,可以直接NOP掉这个就OK,后面的STD也不会出现,其余的分析也就明朗了网上对这两个的分析如下RDTSC 读时间戳计数 rdtsc指令:计算机启动以来的CPU运行周期数放到EDX:EAX里面,EDX是高位,EAX是低位利用 rdtsc 汇编指令可以得到 CPU 内部定时器的值, 每经过一个 CPU 周期, 这个定时器就加一STD 方向设置
10、
009D040A391D 50304000cmp [403050], ebx//这也是偷取的了009D041068 04154000push401504009D0415C3 retn然后两句相当于JMP 00401504,这个地址是假的OEP,真正的OEP可以自己算出偷取的字节去找到OEP了
11、
00401504 /75 0Cjnz short 0040151200401506 |68 12164000push004016120040150B |FF15 6C214000call[40216C] ; msvcrt.__setusermatherr00401511 |59 pop ecx由于这几句由于上面的代码代码被花指令了,所以一往上翻就会乱了也赋值出来75 0C 68 12 16 40 00 FF 15 6C 21 40 00 59


最后修复为
0040148F55 pushebp004014908BEC mov ebp, esp004014926A FFpush-10040149468 D0234000push004023D00040149968 16164000push00401616 ; jmp 到 msvcrt._except_handler30040149E64:A1 00000000 mov eax, fs:[0]004014A450 pusheax004014A564:8925 00000000 mov fs:[0], esp004014AC83EC 68sub esp, 68004014AF53 pushebx004014B056 pushesi004014B157 pushedi004014B28965 E8mov [ebp-18], esp004014B533DB xor ebx, ebx004014B7895D FCmov [ebp-4], ebx004014BA6A 02push2004014BCFF15 7C214000call[40217C] ; msvcrt.__set_app_type004014C259 pop ecx004014C3830D 3C314000 FF ordword ptr [40313C], FFFFFFFF004014CA830D 40314000 FF ordword ptr [403140], FFFFFFFF004014D1FF15 78214000call[402178] ; msvcrt.__p__fmode004014D78B0D 30314000mov ecx, [403130]004014DD8908 mov [eax], ecx004014DFFF15 74214000call[402174] ; msvcrt.__p__commode004014E58B0D 2C314000mov ecx, [40312C]004014EB8908 mov [eax], ecx004014EDA1 70214000mov eax, [402170]004014F28B00 mov eax, [eax]004014F4A3 38314000mov [403138], eax004014F9E8 17010000 call00401615004014FE391D 50304000cmp [403050], ebx二进制代码:55 8B EC 6A FF 68 D0 23 40 00 68 16 16 40 00 64 A1 00 00 00 00 50 64 89 25 00 00 00 00 83 EC 6853 56 57 89 65 E8 33 DB 89 5D FC 6A 02 FF 15 7C 21 40 00 59 83 0D 3C 31 40 00 FF 83 0D 40 31 4000 FF FF 15 78 21 40 00 8B 0D 30 31 40 00 89 08 FF 15 74 21 40 00 8B 0D 2C 31 40 00 89 08 A1 7021 40 00 8B 00 A3 38 31 40 00 E8 17 01 00 00 39 1D 50 30 40 00


用ImpREC修复的时候,OEP:148FRVA:2000大小:1C4
修复后可以正常运行

然后再用LordPE进行减肥,将PUNiSHER这个区段删除,就可以达到只有二十几K了





dumped_减肥1225184618046.rar
 楼主| 小生我怕怕 发表于 2008-10-27 00:12
首先本次壳的类别比较特殊,所以采取原版OD进行,首先忽略所有异常,隐藏好OD
━━━━━━━━━━━━━━━━━━━━━━━━━━
00408061 > /EB 04 jmp short 52pojie.00408067//OD载入程序停在这里
00408063 |83A4BC CE60EB04>and dword ptr ss:[esp+edi*4+4EB60CE],FFF> //在命令行下断 bp LoadLibraryA+5
0040806BBC 0411E800 mov esp,0E81104//下好断点后我们shift+f9运行程序
004080700000add byte ptr ds:[eax],al
004080720081 2C24CAC2 add byte ptr ds:[ecx+C2CA242C],al
━━━━━━━━━━━━━━━━━━━━━━━━━━
以下为堆栈变化
0012FF98 FFFEBDA9 //shift+f9运行第一次后
0012FF9C 004083ECRETURN to 52pojie.004083EC
0012FFA0 0040821FASCII "USER32.DLL"
0012FFA4 7C930738ntdll.7C930738
━━━━━━━━━━━━━━━━━━━━━━━━━━
0012E994/0012EA3C//shift+f9运行第二次后
0012E998|73FBE21FRETURN to USP10.73FBE21F from kernel32.LoadLibraryA
0012E99C|73FA1850ASCII "gdi32.dll"
0012E9A0|73FA0000USP10.73FA0000
━━━━━━━━━━━━━━━━━━━━━━━━━━
0012FF98 FFFA31E5 //shift+f9运行第三次后
0012FF9C 003C0470RETURN to 003C0470 //此时为我们的最佳返回时机
0012FFA0 003C00B7ASCII "USER32.DLL"
0012FFA4 7C930738ntdll.7C930738
━━━━━━━━━━━━━━━━━━━━━━━━━━
003C0470BB 25459C9A mov ebx,9A9C4525//返回到了这里
003C04758BD0mov edx,eax //此时我们开始单步漫游吧
003C0477E8 0B000000 call 003C0487
003C047C8985 23CE4100 mov dword ptr ss:[ebp+41CE23],eax
003C0482E9 71020000 jmp 003C06F8
003C0487E8 00000000 call 003C048C
━━━━━━━━━━━━━━━━━━━━━━━━━━
003C07C3^\0F85 56FFFFFF jnz 003C071F //我们一路向下,遇见向上的就打断一下
003C07C98A85 B4CE4100 mov al,byte ptr ss:[ebp+41CEB4]//在这里执行F4运行到所选,继续单步走
003C07CF84C0test al,al
003C07D174 05 je short 003C07D8
━━━━━━━━━━━━━━━━━━━━━━━━━━
003C0873^\75 CE jnz short 003C0843//这里向上跳,我们在下面打断
003C0875EB 06 jmp short 003C087D//在这个JMP处执行F4运行到所选
003C08778B8D C1CE4100 mov ecx,dword ptr ss:[ebp+41CEC1] //继续F8单步走
003C087D36:8B4424 10mov eax,dword ptr ss:[esp+10]
003C088283C0 14 add eax,14
003C088536:894424 10mov dword ptr ss:[esp+10],eax
003C088A^ 0F85 77FFFFFF jnz 003C0807 //这里向上跳
003C0890EB 33 jmp short 003C08C5 //在这个JMP处执行F4运行到所选
003C089225 73257325 and eax,25732573
003C089773 25 jnb short 003C08BE
━━━━━━━━━━━━━━━━━━━━━━━━━━
003C08C58D85 ADD64100 lea eax,dword ptr ss:[ebp+41D6AD]//我们停在了这里
003C08CB870424xchg dword ptr ss:[esp],eax//此时我们注意下我们的信息窗口
003C08CEFF95 E1CE4100 call dword ptr ss:[ebp+41CEE1] //把上面的两句NOP掉
003C08D480BD E9CE4100 0>cmp byte ptr ss:[ebp+41CEE9],0 //这里是为了避免益出的错误
003C08DB74 77 je short 003C0954
信息窗口如下:
Address=003C0892, (ASCII "%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s")
eax=00402494 (52pojie.00402494)
━━━━━━━━━━━━━━━━━━━━━━━━━━
003C08C590nop //修改后的代码
003C08C690nop //我们继续F8向下走
003C08C790nop //遇见向上的跳转把他打断向下走
003C08C890nop
003C08C990nop
003C08CA90nop
003C08CB90nop
003C08CC90nop
003C08CD90nop
003C08CEFF95 E1CE4100 call dword ptr ss:[ebp+41CEE1]
003C08D480BD E9CE4100 0>cmp byte ptr ss:[ebp+41CEE9],0
003C08DB74 77 je short 003C0954
━━━━━━━━━━━━━━━━━━━━━━━━━━
003C0B1050push eax //程序到达这里后我们注意下
003C0B11FFB5 50CE4100 push dword ptr ss:[ebp+41CE50]
003C0B17E8 B5FEFFFF call 003C09D1
003C0B1C^ EB BF jmp short 003C0ADD //这里向上跳
003C0B1E^ E9 36FEFFFF jmp 003C0959 //这里也向跳,我们F4运行到这里
003C0B2355push ebp //F4运行到上面的JMP后,继续单步一步
003C0B248BECmov ebp,esp
━━━━━━━━━━━━━━━━━━━━━━━━━━
003C09598B85 EACE4100 mov eax,dword ptr ss:[ebp+41CEEA]//我们通过下面的JMP跳到了这里
003C095F8D9D FEDC4100 lea ebx,dword ptr ss:[ebp+41DCFE]//继续单步走吧
003C096550push eax
003C0966E8 0E000000 call 003C0979
003C096B50push eax
003C096C53push ebx
003C096DE8 8EF7FFFF call 003C0100
003C097283C4 08 add esp,8
003C0975FF6424 FC jmp dword ptr ss:[esp-4] //这里跳到我们的Stolen Code的开始处
003C097960pushad
003C097AEB 04 jmp short 003C0980
━━━━━━━━━━━━━━━━━━━━━━━━━━
009D0000 /EB 04 jmp short 009D0006//从这里开始我们要开始注意我们的被抽取的代码啦
009D0002 |8182 8241D9EE E>add dword ptr ds:[edx+EED94182],8C8304EB//我们在不熟悉入口特征的情况下可以复制一个VC的入口来进行比对
009D000C8C82 DB5C24FC mov word ptr ds:[edx+FC245CDB],es //这里我就不比对啦,通常我们VC的入口开头都是一样的如下面的代码
009D0012EB 04 jmp short 009D0018//在跟踪下面的被抽取的代码时,近CALL我们要F7跟进
009D0014819433 968B5C24>adc dword ptr ds:[ebx+esi+245C8B96],2E04>
009D001F028C21 6A00EB04 add cl,byte ptr ds:[ecx+4EB006A]
009D0026F786 777487DC E>test dword ptr ds:[esi+DC877477],670F04E>
━━━━━━━━━━━━━━━━━━━━━━━━━━
009D0360FFD4call esp//单步走到这里直接F8步过就好
009D0362EB 04 jmp short 009D0368
009D0364F781 D9EE8BC8 E>test dword ptr ds:[ecx+C88BEED9],22E04EB
━━━━━━━━━━━━━━━━━━━━━━━━━━
009D037C0F31rdtsc//这句直接NOP掉,因为他是一句垃圾语句,不NOP掉程序会出错
009D037EEB 04 jmp short 009D0384 //处理好后我们F8继续走
009D03808182 82412BC1 E>add dword ptr ds:[edx+C12B4182],8C8304EB
009D038A8C82 663DFF0F mov word ptr ds:[edx+FFF3D66],es
009D0390EB 04 jmp short 009D0396
━━━━━━━━━━━━━━━━━━━━━━━━━━
009D03DA8B6D 00 mov ebp,dword ptr ss:[ebp] ; 52pojie.00401615//走到这里时要注意
009D03DD /EB 04 jmp short 009D03E3 //上面的这句既为我们被抽取的CALL 00401615
009D03DF |8182 8241896C 2>add dword ptr ds:[edx+6C894182],4EB0424//具体看下面的分析
009D03E9F781 D9EE5DEB 0>test dword ptr ds:[ecx+EB5DEED9],D981F70>
━━━━━━━━━━━━━━━━━━━━━━━━━━
009D0402C3retn//当走到这里时我们注意如下
009D0403EB 04 jmp short 009D0409//我们直接F4运行到所选来到这个JMP处
009D0405838C8C 8290391D>or dword ptr ss:[esp+ecx*4+1D399082],50 //程序停在上面的JMP处后我们继续F8单步走
009D040D3040 00 xor byte ptr ds:[eax],al
009D041068 04154000 push 401504
009D0415C3retn
━━━━━━━━━━━━━━━━━━━━━━━━━━
009D040A391D 50304000 cmp dword ptr ds:[403050],ebx //这句即为我们被抽取的最后一句
009D041068 04154000 push 401504 //复制好后我们F8单步
009D0415C3retn//通过这里返回到我们被抽取的伪OEP
━━━━━━━━━━━━━━━━━━━━━━━━━━
被抽取的代码:
push ebp
mov ebp,esp
push -1
push 004023D0//此句由堆栈中分析得来如下
push 00401616 //此句由堆栈中分析得来如下
009D022E64:A1 00000000mov eax,dword ptr fs:[0] //继续单步几步后又会看见了这一串
009D023450push eax
009D023564:8925 0000000>mov dword ptr fs:[0],esp
009D023C83EC 68 sub esp,68
009D023F53push ebx
009D024056push esi
009D024157push edi
009D02428965 E8 mov dword ptr ss:[ebp-18],esp
009D024533DBxor ebx,ebx
009D0247895D FC mov dword ptr ss:[ebp-4],ebx
009D02B8FF15 7C214000 call dword ptr ds:[40217C] ; msvcrt.__set_app_type
009D02BE59pop ecx
009D02BF830D 3C314000 F>or dword ptr ds:[40313C],FFFFFFFF
009D02C6830D 40314000 F>or dword ptr ds:[403140],FFFFFFFF
009D02CDFF15 78214000 call dword ptr ds:[402178] ; msvcrt.__p__fmode
009D02D38B0D 30314000 mov ecx,dword ptr ds:[403130]
009D02D98908mov dword ptr ds:[eax],ecx
009D02DBFF15 74214000 call dword ptr ds:[402174] ; msvcrt.__p__commode
009D02E18B0D 2C314000 mov ecx,dword ptr ds:[40312C]
009D02E78908mov dword ptr ds:[eax],ecx
009D02E9A1 70214000 mov eax,dword ptr ds:[402170]
009D02EE8B00mov eax,dword ptr ds:[eax]
009D02F0A3 38314000 mov dword ptr ds:[403138],eax
call 00401615//此句由下面的分析得来
009D040A391D 50304000 cmp dword ptr ds:[403050],ebx


━━━━━━━━━━━━━━━━━━━━━━━━━━
分析语句:
009D0227 /EB 04 jmp short 009D022D//停在这里时就可以留意堆栈中啦
0012FF38 00401616jmp to msvcrt._except_handler3 //此句为我们的第2句push
0012FF3C 004023D052pojie.004023D0 //此句为我们的第1句push
0012FECC 00000000
分析语句:
009D03DA8B6D 00 mov ebp,dword ptr ss:[ebp] ; 52pojie.00401615
以下为信息窗口
ss:[009D02F7]=00401615 (52pojie.00401615) //这里为把我们的指令转换
ebp=009D02F7//即还原我们的真实地址
上面这句即为我们的CALL 00401615
━━━━━━━━━━━━━━━━━━━━━━━━━━
00401504 /75 0C jnz short 52pojie.00401512 //这里即为我们的伪OEP
00401506 |68 12164000 push 52pojie.00401612//我们直接向上拉着去找我们的开头段首
0040150B |FF15 6C214000 call dword ptr ds:[40216C] ; msvcrt.__setusermatherr
00401511 |59pop ecx
00401512 \E8 E9000000 call 52pojie.00401600
━━━━━━━━━━━━━━━━━━━━━━━━━━
004014A7 \7B D5 jpo short 52pojie.0040147E //这里开始就是我们被抽取的代码,我们先把他NOP掉
004014A964:03D4 add edx,esp//NOP掉后会显示我们刚被拉混淆的代码也被我们NOP掉啦
004014AC3Faas//如下图
004014AD01AF 6998F16F add dword ptr ds:[edi+6FF19869],ebp
004014B3EB 45 jmp short 52pojie.004014FA
004014B52972 DC sub dword ptr ds:[edx-24],esi
004014B8A4movs byte ptr es:[edi],byte ptr ds:[esi]
004014B9C5FDlds edi,ebp; Illegal use of register
004014BBF0:4C lock dec esp ; LOCK prefix is not allowed
004014BDB6 01 mov dh,1
004014BFBF 27DB3791 mov edi,9137DB27
004014C474 02 je short 52pojie.004014C8
004014C6F5cmc
004014C70C 11 or al,11
004014C9383C31cmp byte ptr ds:[ecx+esi],bh
004014CC0373 C7 add esi,dword ptr ds:[ebx-39]
004014CFBC 17715304 mov esp,4537117
004014D491xchg eax,ecx
004014D5^ EB CE jmp short 52pojie.004014A5
004014D735 0C448D4D xor eax,4D8D440C
004014DC^ 75 D5 jnz short 52pojie.004014B3
004014DE3A8461 4AB5CB15 cmp al,byte ptr ds:[ecx+15CBB54A]
004014E5F7DAneg edx
004014E783A0 9488380A 3>and dword ptr ds:[eax+A388894],30
004014EE034CA6 DD add ecx,dword ptr ds:[esi-23]
004014F2B4 3B mov ah,3B
004014F4^ 76 9D jbe short 52pojie.00401493
004014F6AEscas byte ptr es:[edi]
004014F7A7cmps dword ptr ds:[esi],dword ptr es:[ed>
004014F835 8F50CC69 xor eax,69CC508F
004014FDE7 53 out 53,eax
004014FF694C51 54 C1750>imul ecx,dword ptr ds:[ecx+edx*2+54],680>
━━━━━━━━━━━━━━━━━━━━━━━━━━
下图即显示为我们此时停在程序的地方也被我们NOP掉啦
把我们所停的行向下拉把我们NOP掉多余的代码给他还原
还原后的程序如图2
图1
1.jpg

图2
2.jpg


━━━━━━━━━━━━━━━━━━━━━━━━━━
接下来我们去断首可以选择二进制粘贴的形式也可以采取逐一汇编的方式进行修改
二进制代码如下,这是我汇编好后复制出来的二进制代码
55 8B EC 6A FF 68 D0 23 40 00 68 16 16 40 00 64 A1 00 00 00 00 50 64 89 25 00 00 00 00 83 EC 68
53 56 57 89 65 E8 33 DB 89 5D FC 6A 02 FF 15 7C 21 40 00 59 83 0D 3C 31 40 00 FF 83 0D 40 31 40
00 FF FF 15 78 21 40 00 8B 0D 30 31 40 00 89 08 FF 15 74 21 40 00 8B 0D 2C 31 40 00 89 08 A1 70
21 40 00 8B 00 A3 38 31 40 00 E8 17 01 00 00 39 1D 50 30 40 00
━━━━━━━━━━━━━━━━━━━━━━━━━━
004014A755push ebp//补好代码后我们在OEP处新建EIP
004014A88BECmov ebp,esp //然后我们运行lordPE把程序DUMP
004014AA6A FF push -1 //在运行importRCE修复下就可以啦,修复时一个无效剪切掉
004014AC68 D0234000 push 52pojie.004023D0
004014B168 16164000 push 52pojie.00401616; jmp to msvcrt._except_handler3
004014B664:A1 00000000mov eax,dword ptr fs:[0]

dumped_.rar

14 KB, 下载次数: 7, 下载积分: 吾爱币 -1 CB

zeger 发表于 2008-10-27 13:56
初次尝试分析。。。。。。。。。。见谅啊

0040149155PUSH EBP
004014928BECMOV EBP,ESP
004014946A FF PUSH -1
0040149668 00254000 PUSH 402500
0040149B68 86184000 PUSH 401886
004014A064:A1 00000000MOV EAX,[DWORD FS:0]
004014A650PUSH EAX
004014A764:8925 00000000MOV [DWORD FS:0],ESP
004014AE83EC 68 SUB ESP,68
004014B153PUSH EBX
004014B256PUSH ESI
004014B357PUSH EDI
004014B48965 E8 MOV [DWORD SS:EBP-18],ESP
004014B733DBXOR EBX,EBX
004014B9895D FC MOV [DWORD SS:EBP-4],EBX
004014BC6A 02 PUSH 2
004014BEFF15 7C214000 CALL [DWORD DS:40217C] ; msvcrt.__set_app_type
004014C459POP ECX
004014C5830D 3C314000 83OR [DWORD DS:40313C],FFFFFF83
004014CC0D 40314000 OR EAX,403140
004014D1FF15 78214000 CALL [DWORD DS:402178] ; msvcrt.__p__fmode
004014D78B0D 30314000 MOV ECX,[DWORD DS:403130]
004014DD8908MOV [DWORD DS:EAX],ECX
004014DFFF15 74214000 CALL [DWORD DS:402174] ; msvcrt.__p__commode
004014E58B0D 2C314000 MOV ECX,[DWORD DS:40312C]
004014EB8908MOV [DWORD DS:EAX],ECX
004014EDA1 70214000 MOV EAX,[DWORD DS:402170]
004014F28B00MOV EAX,[DWORD DS:EAX]
004014F4A3 38314000 MOV [DWORD DS:403138],EAX
004014F9E8 16010000 CALL 00401614; UnPackMe.00401614
004014FE391D 40304000 CMP [DWORD DS:403040],EBX
0040150475 0C JNZ SHORT 00401512 ; UnPackMe.00401512
0040150668 82184000 PUSH 401882
0040150BFF15 80214000 CALL [DWORD DS:402180] ; msvcrt._except_handler3


以上是被抽取的
被抽了128个字节啊....找晕了


4次内存到OEP
1.F2下断shift+F9
内存映射,项目 22
地址=00404000
大小=00004000 (16384.)
物主=UnPackMe 00400000
区段=.rsrc
包含=resources
类型=Imag 01001002
访问=R
初始访问=RWE

2.F2下断shift+F9
内存映射,项目 21
地址=00403000
大小=00001000 (4096.)
物主=UnPackMe 00400000
区段=
类型=Imag 01001002
访问=R
初始访问=RWE

3.F2下断shift+F9
内存映射,项目 20
地址=00402000
大小=00001000 (4096.)
物主=UnPackMe 00400000
区段=
包含=data
类型=Imag 01001002
访问=R
初始访问=RWE

4.F2下断shift+F9
内存映射,项目 19
地址=00401000
大小=00001000 (4096.)
物主=UnPackMe 00400000
区段=
包含=code,relocations
类型=Imag 01001002
访问=R
初始访问=RWE

程序断到这里
00401615C3RETN
00401616- FF25 80214000 JMP [DWORD DS:402180]; msvcrt._except_handler3
0040161C- FF25 84214000 JMP [DWORD DS:402184]; msvcrt._controlfp
00401622FF7424 10 PUSH [DWORD SS:ESP+10]
00401626FF7424 10 PUSH [DWORD SS:ESP+10]
0040162AFF7424 10 PUSH [DWORD SS:ESP+10]
0040162EFF7424 10 PUSH [DWORD SS:ESP+10]
00401632E8 43000000 CALL 0040167A; JMP to MFC42.#1576
00401637C2 1000 RETN 10
0040163AE8 BDFDFFFF CALL 004013FC; JMP to MFC42.#1168
0040163F8B4C24 04 MOV ECX,[DWORD SS:ESP+4]
004016438B5424 08 MOV EDX,[DWORD SS:ESP+8]
0040164785C9TEST ECX,ECX
004016498848 14 MOV [BYTE DS:EAX+14],CL
0040164C8990 40100000 MOV [DWORD DS:EAX+1040],EDX
0040165275 09 JNZ SHORT 0040165D ; UnPackMe.0040165D
004016546A FD PUSH -3
00401656FF15 94214000 CALL [DWORD DS:402194] ; msvcrt._setmbcp


F8走。。。到这里就是OEP了。。

00401504 /75 0C JNZ SHORT 00401512 ; UnPackMe.00401512 到这里 上面的字节全部被抽取了
00401506 |68 12164000 PUSH 401612
0040150B |FF15 6C214000 CALL [DWORD DS:40216C] ; msvcrt.__setusermatherr
00401511 |59POP ECX
00401512 \E8 E9000000 CALL 00401600; UnPackMe.00401600
0040151768 14304000 PUSH 403014
0040151C68 10304000 PUSH 403010
00401521E8 D4000000 CALL 004015FA; JMP to msvcrt._initterm
00401526A1 28314000 MOV EAX,[DWORD DS:403128]
0040152B8945 94 MOV [DWORD SS:EBP-6C],EAX
0040152E8D45 94 LEA EAX,[DWORD SS:EBP-6C]
0040153150PUSH EAX
00401532FF35 24314000 PUSH [DWORD DS:403124]
004015388D45 9C LEA EAX,[DWORD SS:EBP-64]
0040153B50PUSH EAX
0040153C8D45 90 LEA EAX,[DWORD SS:EBP-70]
0040153F50PUSH EAX
004015408D45 A0 LEA EAX,[DWORD SS:EBP-60]
0040154350PUSH EAX

抽取字节我找头晕了,我不懂分析。。看高手们分析

在00401504 /75 0C JNZ SHORT 00401512 ; UnPackMe.00401512 以上NOP掉把128个被抽取的字节黏贴上去 新建EIP。。

dump有一个无效cut掉。。。 修复程序可以运行



找stolen code
ALT+M F2断下 shift+F9 运行
内存映射,项目 21
地址=00403000
大小=00001000 (4096.)
物主=UnPackMe 00400000
区段=
类型=Imag 01001002
访问=R
初始访问=RWE

再次ALT+M F2断下 shift+F9 运行
内存映射,项目 24
地址=00402000
大小=00001000 (4096.)
物主=UnPackMe 00400000
区段=
包含=data
类型=Imag 01001002
访问=R
初始访问=RWE
00920B36 AD LODS [DWORD DS:ESI] 来到这里。 F8单步走
00920B37 D3C8 ROR EAX,CL
00920B39 03D0 ADD EDX,EAX
00920B3B ^ E2 F9 LOOPD SHORT 00920B36 这个循环F4打断到下句 继续F8
00920B3D 8955 FC MOV [DWORD SS:EBP-4],EDX
00920B40 8B45 FC MOV EAX,[DWORD SS:EBP-4]
00920B43 59 POP ECX
00920B44 5F POP EDI
00920B45 5E POP ESI
00920B46 5B POP EBX
00920B47 C9 LEAVE
00920B48 C3 RETN
-----------------------------------------------------
00920BB7 5A POP EDX ; UnPackMe.00402000 继续F8走
00920BB8 5A POP EDX
00920BB9 5B POP EBX
00920BBA 8B941D 06DA4100 MOV EDX,[DWORD SS:EBP+EBX+41DA06]
00920BC1 3BC2 CMP EAX,EDX
00920BC3 75 16 JNZ SHORT 00920BDB
00920BC5 59 POP ECX
00920BC6 8DBC0D 54CE4100 LEA EDI,[DWORD SS:EBP+ECX+41CE54]
00920BCD 83C1 08 ADD ECX,8
00920BD0 83C3 04 ADD EBX,4
00920BD3 837F 08 00 CMP [DWORD DS:EDI+8],0
00920BD7 ^ 75 C5 JNZ SHORT 00920B9E
00920BD9 61 POPAD
00920BDA C3 RETN
-----------------------------------------------------------------------------------

009207D8 8985 B9CE4100 MOV [DWORD SS:EBP+41CEB9],EAX 一直单步走。。 有往上跳的跳转F4到下一句
009207DE C785 BDCE4100 0>MOV [DWORD SS:EBP+41CEBD],0
009207E8 51 PUSH ECX
009207E9 8B8D C1CE4100 MOV ECX,[DWORD SS:EBP+41CEC1]
009207EF 8B85 B5CE4100 MOV EAX,[DWORD SS:EBP+41CEB5]
009207F5 53 PUSH EBX
009207F6 03C1 ADD EAX,ECX
009207F8 55 PUSH EBP
009207F9 56 PUSH ESI
009207FA 85C0 TEST EAX,EAX
009207FC 57 PUSH EDI
009207FD 894424 10 MOV [DWORD SS:ESP+10],EAX
00920801 0F84 89000000 JE 00920890
00920807 8B30 MOV ESI,[DWORD DS:EAX]
00920809 85F6 TEST ESI,ESI
0092080B 75 07 JNZ SHORT 00920814
0092080D 8B70 10 MOV ESI,[DWORD DS:EAX+10]
00920810 85F6 TEST ESI,ESI
00920812 74 7C JE SHORT 00920890
。。。。。。。。。。。。。。省略代码
00920AFE E8 FDF5FFFF CALL 00920100
00920B03 83C4 08 ADD ESP,8
00920B06 8BFE MOV EDI,ESI
00920B08 8BB5 50CE4100 MOV ESI,[DWORD SS:EBP+41CE50]
00920B0E F3:A4 REP MOVS [BYTE ES:EDI],[BYTE DS:ESI]
00920B10 50 PUSH EAX
00920B11 FFB5 50CE4100 PUSH [DWORD SS:EBP+41CE50]
00920B17 E8 B5FEFFFF CALL 009209D1
00920B1C ^ EB BF JMP SHORT 00920ADD---F4 到下面
00920B1E ^ E9 36FEFFFF JMP 00920959
这个跳 跟进去!!!

---------------------------------------------------------
009209598B85 EACE4100 MOV EAX,[DWORD SS:EBP+41CEEA] 跟进去到这里。。
0092095F8D9D FEDC4100 LEA EBX,[DWORD SS:EBP+41DCFE]
0092096550PUSH EAX
00920966E8 0E000000 CALL 00920979
0092096B50PUSH EAX
0092096C53PUSH EBX
0092096DE8 8EF7FFFF CALL 00920100
0092097283C4 08 ADD ESP,8
00920975FF6424 FC JMP [DWORD SS:ESP-4] 这里F7进入

--------------------------------------------------------
00A20006D9EEFLDZ 程序来到这里,我一直F7走
00A20008EB 04 JMP SHORT 00A2000E
00A2000A838C8C 82DB5C24>OR [DWORD SS:ESP+ECX*4+245CDB82],FFFFFFF>
00A20012EB 04 JMP SHORT 00A20018
。。。。。。。。。。。。。。。。省略代码
N次F7后 来到以下代码 , 红色部分是我们要找的一部分, 复制下来
00A2022D90NOP
00A2022E64:A1 00000000MOV EAX,[DWORD FS:0]
00A2023450PUSH EAX
00A2023564:8925 0000000>MOV [DWORD FS:0],ESP
00A2023C83EC 68 SUB ESP,68
00A2023F53PUSH EBX
00A2024056PUSH ESI
00A2024157PUSH EDI
00A202428965 E8 MOV [DWORD SS:EBP-18],ESP
00A2024533DBXOR EBX,EBX
00A20247895D FC MOV [DWORD SS:EBP-4],EBX

00A2024AEB 04 JMP SHORT 00A20250 继续F7走!!

---------------------------------------------------------------------------
红色部分代码复制下来
00A202B483EC 04 SUB ESP,4
00A202B790NOP
00A202B8FF15 7C214000 CALL [DWORD DS:40217C] ; msvcrt.__set_app_type
00A202BE59POP ECX
00A202BF830D 3C314000 F>OR [DWORD DS:40313C],FFFFFFFF
00A202C6830D 40314000 F>OR [DWORD DS:403140],FFFFFFFF
00A202CDFF15 78214000 CALL [DWORD DS:402178] ; msvcrt.__p__fmode
00A202D38B0D 30314000 MOV ECX,[DWORD DS:403130]
00A202D98908MOV [DWORD DS:EAX],ECX
00A202DBFF15 74214000 CALL [DWORD DS:402174] ; msvcrt.__p__commode
00A202E18B0D 2C314000 MOV ECX,[DWORD DS:40312C]
00A202E78908MOV [DWORD DS:EAX],ECX
00A202E9A1 70214000 MOV EAX,[DWORD DS:402170]
00A202EE8B00MOV EAX,[DWORD DS:EAX]
00A202F0A3 38314000 MOV [DWORD DS:403138],EAX

00A202F5EB 04 JMP SHORT 00A202FB

---------------------------------------------------------------------------
就是找到这些stolen code。 剩下的代码是对照源程序进行修复的
本人太菜,希望大牛们多多指点。。。。。。。。
傻人有傻福 发表于 2008-10-27 15:28
00408061 > /EB 04 JMP SHORT 00408067; OD载入到这里
00408063 |83A4BC CE60EB04>AND DWORD PTR SS:[ESP+EDI*4+4EB60CE],>
0040806BBC 0411E800 MOV ESP,0E81104
004080700000ADD BYTE PTR DS:[EAX],AL
004080720081 2C24CAC2 ADD BYTE PTR DS:[ECX+C2CA242C],AL
0040807841INC ECX

bp CreateMutexASHIFT+F9 断下后返回到这里
003D09242BC0SUB EAX,EAX ; 返回到这里
003D092664:A1 18000000MOV EAX,DWORD PTR FS:[18]
003D092C3E:8B40 34MOV EAX,DWORD PTR DS:[EAX+34]
003D09303D B7000000 CMP EAX,0B7
003D093575 1D JNZ SHORT 003D0954
003D09378D9D 17D74100 LEA EBX,DWORD PTR SS:[EBP+41D717]
003D093D6A 30 PUSH 30
003D093F53PUSH EBX; UnPackMe.00400000
003D09408D9D FAD64100 LEA EBX,DWORD PTR SS:[EBP+41D6FA]

ALT+M在CODE段下内存访问 SHIFT+F9来到这里
00401615C3RET ; 内存访问来到这里
00401616- FF25 80214000 JMP DWORD PTR DS:[402180] ; msvcrt._except_handler3
0040161C- FF25 84214000 JMP DWORD PTR DS:[402184] ; msvcrt._controlfp
00401622FF7424 10 PUSH DWORD PTR SS:[ESP+10]
00401626FF7424 10 PUSH DWORD PTR SS:[ESP+10]
0040162AFF7424 10 PUSH DWORD PTR SS:[ESP+10]
0040162EFF7424 10 PUSH DWORD PTR SS:[ESP+10]
00401632E8 43000000 CALL 0040167A ; JMP to MFC42.#1576
00401637C2 1000 RET 10

接着单步往下走,稍微走几步就来到这里
00401504 /75 0C JNZ SHORT 00401512;单步来到这里
00401506 |68 12164000 PUSH 00401612
0040150B |FF15 6C214000 CALL DWORD PTR DS:[40216C]; msvcrt.__setusermatherr
00401511 |59POP ECX ; UnPackMe.00407B90
00401512 \E8 E9000000 CALL 00401600
0040151768 14304000 PUSH 00403014
0040151C68 10304000 PUSH 00403010
00401521E8 D4000000 CALL 004015FA ; JMP to msvcrt._initterm
00401526A1 28314000 MOV EAX,DWORD PTR DS:[403128]
0040152B8945 94 MOV DWORD PTR SS:[EBP-6C],EAX
0040152E8D45 94 LEA EAX,DWORD PTR SS:[EBP-6C]
0040153150PUSH EAX
00401532FF35 24314000 PUSH DWORD PTR DS:[403124]
004015388D45 9C LEA EAX,DWORD PTR SS:[EBP-64]
0040153B50PUSH EAX
0040153C8D45 90 LEA EAX,DWORD PTR SS:[EBP-70]
0040153F50PUSH EAX
004015408D45 A0 LEA EAX,DWORD PTR SS:[EBP-60]
0040154350PUSH EAX
00401544FF15 64214000 CALL DWORD PTR DS:[402164]; msvcrt.__getmainargs
0040154A68 0C304000 PUSH 0040300C
0040154F68 00304000 PUSH 00403000
00401554E8 A1000000 CALL 004015FA ; JMP to msvcrt._initterm
0040155983C4 24 ADD ESP,24
0040155CA1 60214000 MOV EAX,DWORD PTR DS:[402160]
004015618B30MOV ESI,DWORD PTR DS:[EAX]
004015638975 8C MOV DWORD PTR SS:[EBP-74],ESI ; UnPackMe.00404038
00401566803E 22 CMP BYTE PTR DS:[ESI],22
0040156975 3A JNZ SHORT 004015A5
0040156B46INC ESI ; UnPackMe.00404038
0040156C8975 8C MOV DWORD PTR SS:[EBP-74],ESI ; UnPackMe.00404038
0040156F8A06MOV AL,BYTE PTR DS:[ESI]
004015713AC3CMP AL,BL
0040157374 04 JE SHORT 00401579
004015753C 22 CMP AL,22
00401577^ 75 F2 JNZ SHORT 0040156B
00401579803E 22 CMP BYTE PTR DS:[ESI],22
0040157C75 04 JNZ SHORT 00401582
0040157E46INC ESI ; UnPackMe.00404038
0040157F8975 8C MOV DWORD PTR SS:[EBP-74],ESI ; UnPackMe.00404038
004015828A06MOV AL,BYTE PTR DS:[ESI]
004015843AC3CMP AL,BL
0040158674 04 JE SHORT 0040158C
004015883C 20 CMP AL,20
0040158A^ 76 F2 JBE SHORT 0040157E
0040158C895D D0 MOV DWORD PTR SS:[EBP-30],EBX
0040158F8D45 A4 LEA EAX,DWORD PTR SS:[EBP-5C]
0040159250PUSH EAX
00401593FF15 04204000 CALL DWORD PTR DS:[402004];kernel32.GetStartupInfoA

好像就是MFC的入口代码,我们找一个MFC的程序来对比一下,确实应该就是入口代码了,只不过
被抽的代码比较多,我们现在就来把代码找回来。

重新载入程序,bp CreateMutexA SHIFT+F9后返回:
003D08278BD0MOV EDX,EAX ; 返回到这里
003D082983FA FF CMP EDX,-1
003D082C74 49 JE SHORT 003D0877
003D082E8B4C24 10 MOV ECX,DWORD PTR SS:[ESP+10] ; UnPackMe.00402480
003D08328B06MOV EAX,DWORD PTR DS:[ESI]
003D08348B79 10 MOV EDI,DWORD PTR DS:[ECX+10]

我们单步往下走去寻找被抽取的代码
003D0B17E8 B5FEFFFF CALL 003D09D1
003D0B1C^ EB BF JMP SHORT 003D0ADD
003D0B1E^ E9 36FEFFFF JMP 003D0959; 这个JMP要让它跳回去,要不然就跑起来了

上面那个JMP来到这里
003D09598B85 EACE4100 MOV EAX,DWORD PTR SS:[EBP+41CEEA] ; 那个JMP跳到这里
003D095F8D9D FEDC4100 LEA EBX,DWORD PTR SS:[EBP+41DCFE]
003D096550PUSH EAX
003D0966E8 0E000000 CALL 003D0979
003D096B50PUSH EAX
003D096C53PUSH EBX; UnPackMe.00400000
003D096DE8 8EF7FFFF CALL 003D0100
003D097283C4 08 ADD ESP,8
003D0975- FF6424 FC JMP DWORD PTR SS:[ESP-4]; 这个跳向是变化的特别注意,这里可能是个关键

我们继续单步找被抽取的代码,来到这里:
009E020535 65343545 XOR EAX,45353465; 走到这里注意看寄存器窗口和堆栈窗口
009E020AEB 04 JMP SHORT 009E0210

此时寄存器窗口显示如下:
EAX 00401616 JMP to msvcrt._except_handler3
堆栈窗口显示如下:
0012FF40 004023D0UnPackMe.004023D0
这就是说我们要找的其中2句代码是这样的:
push 004023D0
push 00401616

我们继续单步往下走,这一整段就是我们要找的一部分代码:
009E022E64:A1 00000000MOV EAX,DWORD PTR FS:[0]
009E023450PUSH EAX
009E023564:8925 0000000>MOV DWORD PTR FS:[0],ESP
009E023C83EC 68 SUB ESP,68
009E023F53PUSH EBX
009E024056PUSH ESI; UnPackMe.00404038
009E024157PUSH EDI; UnPackMe.00407B90
009E02428965 E8 MOV DWORD PTR SS:[EBP-18],ESP
009E024533DBXOR EBX,EBX
009E0247895D FC MOV DWORD PTR SS:[EBP-4],EBX



我们继续往下走就又可以看到一整段代码:
009E02B483EC 04 SUB ESP,4 ;不包括这句
009E02B790NOP ;不包括这句
(完整的是下面这段)
009E02B8FF15 7C214000 CALL DWORD PTR DS:[40217C]; msvcrt.__set_app_type
009E02BE59POP ECX ; UnPackMe.00407B90
009E02BF830D 3C314000 F>OR DWORD PTR DS:[40313C],FFFFFFFF
009E02C6830D 40314000 F>OR DWORD PTR DS:[403140],FFFFFFFF
009E02CDFF15 78214000 CALL DWORD PTR DS:[402178]; msvcrt.__p__fmode
009E02D38B0D 30314000 MOV ECX,DWORD PTR DS:[403130]
009E02D98908MOV DWORD PTR DS:[EAX],ECX
009E02DBFF15 74214000 CALL DWORD PTR DS:[402174]; msvcrt.__p__commode
009E02E18B0D 2C314000 MOV ECX,DWORD PTR DS:[40312C]
009E02E78908MOV DWORD PTR DS:[EAX],ECX
009E02E9A1 70214000 MOV EAX,DWORD PTR DS:[402170]
009E02EE8B00MOV EAX,DWORD PTR DS:[EAX]
009E02F0A3 38314000 MOV DWORD PTR DS:[403138],EAX

同时我们走到009E02B790NOP 这句的时候注意看堆栈窗口,此时栈顶显示的
是这样的0012FEC0 00000002也就是说在这段代码前一句的PUSH XXX是PUSH 2。

我们单步往下走,再走一段就无法再单步了,可我们还有几句没找回来,我们没找回来的几句就
在一开始的被抽取代码的伪OEP前面,我们就从这里找线索,重复最开始的到达伪OEP的方法,内
存断点断下后单步来找剩下的被抽取的代码。

单步来到这里
009E040A391D 50304000 CMP DWORD PTR DS:[403050],EBX ; 这句就是我们要的
009E041068 04154000 PUSH 401504
009E0415C3RET

可是在MOV DWORD PTR DS:[403138],EAX和CMP DWORD PTR DS:[403050],EBX中间还有一个CALL
XXXXX没找到,怎么办呢?没找到的这个CALL XXXXX到底是什么东东,我们载入一个MFC程序看看
,原来是这样的
00401885 C3retn; 这个就是CALL的内容
00401886 - FF25 94214000 jmp dword ptr ds:[<&msvcrt._except_handler3>; msvcrt._except_handler3
0040188C - FF25 98214000 jmp dword ptr ds:[<&msvcrt._controlfp>] ; msvcrt._controlfp

我们在上面的内存断点断下后也可以看到这段类似的代码,我们只要找到retn的这个地址就可以了:
00401615C3RET ; 来到这里
00401616- FF25 80214000 JMP DWORD PTR DS:[402180] ; msvcrt._except_handler3
0040161C- FF25 84214000 JMP DWORD PTR DS:[402184] ; msvcrt._controlfp

原来内存断点断下的地方就是我们要找的CALL的地址了,所以这句要找回来的代码就是CALL 00401615

我们整理一下找回来的代码:
55push ebp
8BECmov ebp,esp
6A FF push -1 (前面这3句代码我看的时候没找到,反正MFC的都是这样的就偷
懒一下吧)
68 D0234000 push 004023D0
68 16164000 push 00401616
64:A1 00000000MOV EAX,DWORD PTR FS:[0]
50PUSH EAX
64:8925 0000000>MOV DWORD PTR FS:[0],ESP
83EC 68 SUB ESP,68
53PUSH EBX
56PUSH ESI; UnPackMe.00404038
57PUSH EDI; UnPackMe.00407B90
8965 E8 MOV DWORD PTR SS:[EBP-18],ESP
33DBXOR EBX,EBX
895D FC MOV DWORD PTR SS:[EBP-4],EBX
6A 02 PUSH 2
FF15 7C214000 CALL DWORD PTR DS:[40217C]; msvcrt.__set_app_type
59POP ECX ; UnPackMe.00407B90
830D 3C314000 F>OR DWORD PTR DS:[40313C],FFFFFFFF
830D 40314000 F>OR DWORD PTR DS:[403140],FFFFFFFF
FF15 78214000 CALL DWORD PTR DS:[402178]; msvcrt.__p__fmode
8B0D 30314000 MOV ECX,DWORD PTR DS:[403130]
8908MOV DWORD PTR DS:[EAX],ECX
FF15 74214000 CALL DWORD PTR DS:[402174]; msvcrt.__p__commode
8B0D 2C314000 MOV ECX,DWORD PTR DS:[40312C]
8908MOV DWORD PTR DS:[EAX],ECX
A1 70214000 MOV EAX,DWORD PTR DS:[402170]
8B00MOV EAX,DWORD PTR DS:[EAX]
A3 38314000 MOV DWORD PTR DS:[403138],EAX
E8 A0010000 CALL 00401615
391D 50304000 CMP DWORD PTR DS:[403050],EBX

接着我们把代码补回去,注意:补的时候要注意看要从0040148F这里开始补起,千万不要从
00401470这里开始补,一开始我嫌麻烦不想去算字节数从比较开头的00401470补起,以为多出来的代码
NOP掉就可以了,结果一直有问题,找了很久才想到会不会是位置的问题,仔细看了一下才看到
00401470到0040148E这里的代码很清楚应该是正常的代码我从这里补起就有问题了,而且字节数
算一下也刚好应该从0040148F这里补就刚好了。补完之后,LORDPE脱出来,IMPORTREC修复一下,
有一个无效指针,稍微看了一下应该是个没用的假指针,把它剪掉,转存修复,可以运行o(∩_∩)o

总结一下:脱这个壳最需要的是耐心和细心,我自己回过头来看一下自己写的我也有点晕,但是
只要耐心和细心一点就应该可以脱这个壳了,特别是最后代码补完之后还要仔细看下,我也是花
了挺久的时间在看补的代码是否有问题,有错的话把补完代码的程序再从新放到OD里面看看,找
一下哪里有问题。有时候复制都会复制出错[s:38]
lqiulu 发表于 2008-10-27 18:40
下断点:bp OpenMutexA,运行一次返回程序领空。

003C08D4 80BD E9CE4100 00CMP BYTE PTR SS:[EBP+41CEE9],0//返回到这里单步。
003C08DB 74 77 JE SHORT 003C0954
003C08DD EB 34 JMP SHORT 003C0913
003C08DF 41INC ECX
003C08E0 70 70 JO SHORT 003C0952
003C08E2 6CINS BYTE PTR ES:[EDI],DX
003C08E3 6963 61 74696F6EIMUL ESP,DWORD PTR DS:[EBX+61],6E6F6974
..................................................................................
003C0ABE/74 0A JE SHORT 003C0ACA
003C0AC0|8BF0MOV ESI,EAX
003C0AC2|FF85 BDCE4100 INC DWORD PTR SS:[EBP+41CEBD]
003C0AC8 ^|EB 9D JMP SHORT 003C0A67//F4执行到这里继续单步
003C0ACA\8B30MOV ESI,DWORD PTR DS:[EAX]
..................................................................................

003C0B17 E8 B5FEFFFF CALL 003C09D1
003C0B1C ^ EB BF JMP SHORT 003C0ADD
003C0B1E ^ E9 36FEFFFF JMP 003C0959//这里F4,单步
003C0B23 55PUSH EBP
-------------------------------------------------------------------------------------

003C0959 8B85 EACE4100MOV EAX,DWORD PTR SS:[EBP+41CEEA] //跳到这里
003C095F 8D9D FEDC4100LEA EBX,DWORD PTR SS:[EBP+41DCFE]
003C0965 50 PUSH EAX
003C0966 E8 0E000000CALL 003C0979
003C096B 50 PUSH EAX
003C096C 53 PUSH EBX
003C096D E8 8EF7FFFFCALL 003C0100
003C0972 83C4 08ADD ESP,8
003C0975 FF6424 FCJMP DWORD PTR SS:[ESP-4]

//这里跳向9F0000,大跳转,stole oep区段,F7进入。
003C0979 60 PUSHAD
003C097A EB 04JMP SHORT 003C0980
003C097C 65:D1AC40 6A04EB04 SHR DWORD PTR GS:[EAX+EAX*2+4EB046A],1
003C0984 C782 5BED6800 100000EB MOV DWORD PTR DS:[EDX+68ED5B],EB000010

=================================================================

009F0000/EB 04JMP SHORT 009F0006
009F0002|8182 8241D9EE EB04838C ADD DWORD PTR DS:[EDX+EED94182],8C8304EB
009F000C 8C82 DB5C24FCMOV WORD PTR DS:[EDX+FC245CDB],ES
009F0012 EB 04JMP SHORT 009F0018


009F00A5 5DPOP EBP
009F00A6 EB 04 JMP SHORT 009F00AC


009F0180 35 65343545XOR EAX,45353465
009F0185 EB 04JMP SHORT 009F018B //运行到这里时,eax为004023D0
009F0187 819433 96894424 FCEB04FC ADC DWORD PTR DS:[EBX+ESI+24448996],F704EBFC
009F0192 81D9 EE8B4424SBB ECX,24448BEE
009F0198 D8EB FSUBR ST,ST(3)

009F0205 35 65343545XOR EAX,45353465
009F020A EB 04JMP SHORT 009F0210//运行到这里时,eax值为00401616

009F0210 894424 FCMOV DWORD PTR SS:[ESP-4],EAX
009F0214 EB 04JMP SHORT 009F021A //运行到这里时,堆栈中的内容为。
009F0216 F781 D9EE8B44 24D8EB04 TEST DWORD PTR DS:[ECX+448BEED9],4EBD824


0012FF3C 00401616JMP to msvcrt._except_handler3//两个push。
0012FF40 004023D0UnPackMe.004023D0


009F022E 64:A1 00000000 MOV EAX,DWORD PTR FS:[0]//记录以下代码
009F0234 50 PUSH EAX
009F0235 64:8925 00000000 MOV DWORD PTR FS:[0],ESP
009F023C 83EC 68SUB ESP,68
009F023F 53 PUSH EBX
009F0240 56 PUSH ESI
009F0241 57 PUSH EDI
009F0242 8965 E8MOV DWORD PTR SS:[EBP-18],ESP
009F0245 33DB XOR EBX,EBX
009F0247 895D FCMOV DWORD PTR SS:[EBP-4],EBX
..............................................................................
009F02B4 83EC 04 SUB ESP,4 //堆栈中00000002入栈,即代码:push 2
009F02B7 90NOP
009F02B8 FF15 7C214000 CALL DWORD PTR DS:[40217C] //记录下代码
009F02BE 59POP ECX
009F02BF 830D 3C314000 FFOR DWORD PTR DS:[40313C],FFFFFFFF
009F02C6 830D 40314000 FFOR DWORD PTR DS:[403140],FFFFFFFF
009F02CD FF15 78214000 CALL DWORD PTR DS:[402178];
009F02D3 8B0D 30314000 MOV ECX,DWORD PTR DS:[403130]
009F02D9 8908MOV DWORD PTR DS:[EAX],ECX
009F02DB FF15 74214000 CALL DWORD PTR DS:[402174];

009F02E1 8B0D 2C314000 MOV ECX,DWORD PTR DS:[40312C]
009F02E7 8908MOV DWORD PTR DS:[EAX],ECX
009F02E9 A1 70214000 MOV EAX,DWORD PTR DS:[402170]
009F02EE 8B00MOV EAX,DWORD PTR DS:[EAX]
009F02F0 A3 38314000 MOV DWORD PTR DS:[403138],EAX
009F02F5 EB 04 JMP SHORT 009F02FB
------------------------------------------------------------------------------
009F0301 E8 06000000CALL 009F030C //F7进入
009F0306 EB 04JMP SHORT 009F030C
009F0308 838C8C 82EB04F7 81 OR DWORD PTR SS:[ESP+ECX*4+F704EB82],FFFFFF81
----------------------------------------------------------------------------------
009F030C/EB 04 JMP SHORT 009F0312
009F030E|F781 D9EEFF34 24EB0481TEST DWORD PTR DS:[ECX+34FFEED9],8104EB24
009F0318 94XCHG EAX,ESP

009F037C 0F31RDTSC //nop掉
009F037E EB 04 JMP SHORT 009F0384
009F0380 8182 82412BC1 EB04838CADD DWORD PTR DS:[EDX+C12B4182],8C8304EB
009F038A 8C82 663DFF0F MOV WORD PTR DS:[EDX+FFF3D66],ES
009F0390 EB 04 JMP SHORT 009F0396

009F03E3 896C24 04MOV DWORD PTR SS:[ESP+4],EBP ; UnPackMe.00401615
009F03E7 EB 04JMP SHORT 009F03ED
009F03E9 F781 D9EE5DEB 04F781D9 TEST DWORD PTR DS:[ECX+EB5DEED9],D981F704
堆栈中:
0012FEB8 0012FF48
0012FEBC 00401615UnPackMe.00401615//call的内容

009F040A 391D 50304000CMP DWORD PTR DS:[403050],EBX //记录代码
009F0410 68 04154000PUSH 401504


总的代码如下:

0040148F 55 PUSH EBP
00401490 8BEC MOV EBP,ESP
00401492 6A FFPUSH -1 //堆栈中得到
00401494 68 D0234000PUSH 004023D0 //堆栈第一次压入,下部的
00401499 68 16164000PUSH 00401616 //堆栈第二次压入,上部的
0040149E 64:A1 00000000 MOV EAX,DWORD PTR FS:[0]
004014A4 50 PUSH EAX
004014A5 64:8925 00000000 MOV DWORD PTR FS:[0],ESP
004014AC 83EC 68SUB ESP,68
004014AF 53 PUSH EBX
004014B0 56 PUSH ESI
004014B1 57 PUSH EDI
004014B2 8965 E8MOV DWORD PTR SS:[EBP-18],ESP
004014B5 33DB XOR EBX,EBX
004014B7 895D FCMOV DWORD PTR SS:[EBP-4],EBX
004014BA 6A 02PUSH 2
004014BC FF15 7C214000CALL DWORD PTR DS:[40217C] ; msvcrt.__set_app_type
004014C2 59 POP ECX
004014C3 830D 3C314000 FF OR DWORD PTR DS:[40313C],FFFFFFFF
004014CA 830D 40314000 FF OR DWORD PTR DS:[403140],FFFFFFFF
004014D1 FF15 78214000CALL DWORD PTR DS:[402178] ; msvcrt.__p__fmode
004014D7 8B0D 30314000MOV ECX,DWORD PTR DS:[403130]
004014DD 8908 MOV DWORD PTR DS:[EAX],ECX
004014DF FF15 74214000CALL DWORD PTR DS:[402174] ; msvcrt.__p__commode
004014E5 8B0D 2C314000MOV ECX,DWORD PTR DS:[40312C]
004014EB 8908 MOV DWORD PTR DS:[EAX],ECX
004014ED A1 70214000MOV EAX,DWORD PTR DS:[402170]
004014F2 8B00 MOV EAX,DWORD PTR DS:[EAX]
004014F4 A3 38314000MOV DWORD PTR DS:[403138],EAX
004014F9 E8 17010000CALL 00401615//堆栈中得到。
004014FE 391D 50304000CMP DWORD PTR DS:[403050],EBX

00401504 75 0CJNZ SHORT 00401512
00401506 68 12164000PUSH 00401612
0040150B FF15 6C214000CALL DWORD PTR DS:[40216C] ; msvcrt.__setusermatherr
00401511 59 POP ECX
00401512 E8 E9000000CALL 00401600
00401517 68 14304000PUSH 00403014
0040151C 68 10304000PUSH 00403010
00401521 E8 D4000000CALL 004015FA; JMP to msvcrt._initterm
00401526 A1 28314000MOV EAX,DWORD PTR DS:[403128]
0040152B 8945 94MOV DWORD PTR SS:[EBP-6C],EAX
0040152E 8D45 94LEA EAX,DWORD PTR SS:[EBP-6C]
00401531 50 PUSH EAX
00401532 FF35 24314000PUSH DWORD PTR DS:[403124]
00401538 8D45 9CLEA EAX,DWORD PTR SS:[EBP-64]
0040153B 50 PUSH EAX

补完代码在新的入口新建eip,dump,修复。
nv21 发表于 2008-10-27 21:51
首先OD载入到OEP 去看一下 下断点bp GetModuleHandleA SHIFT+F9运行 注意堆栈变化
00408061 > /EB 04 JMP SHORT UnPackMe.00408067
00408063 |83A4BC CE60EB04 80AND DWORD PTR SS:[ESP+EDI*4+4EB60CE],FFFFFF80
0040806BBC 0411E800 MOV ESP,0E81104
004080700000ADD BYTE PTR DS:[EAX],AL
004080720081 2C24CAC2 ADD BYTE PTR DS:[ECX+C2CA242C],AL
0040807841INC ECX
0040807900EBADD BL,CH
0040807B04 64 ADD AL,64
0040807D6B88 185DE800 00IMUL ECX,DWORD PTR DS:[EAX+E85D18],0
004080840000ADD BYTE PTR DS:[EAX],AL
00408086EB 04 JMP SHORT UnPackMe.0040808C
0040808864:6B88 18812C24 86 IMUL ECX,DWORD PTR FS:[EAX+242C8118],-7A
004080900000ADD BYTE PTR DS:[EAX],AL
0040809200EBADD BL,CH

第一次
0012FF9C 0012FFE0指向下一个 SEH 记录的指针
0012FFA0 003D00FBSE 处理器
0012FFA4 7C930208ntdll.7C930208
0012FFA8 FFFFFFFF
0012FFAC 0012FFF0
第二次
0012F734 77C079B2/CALL 到 GetModuleHandleA 来自 77C079AC
0012F738 77BE31BC\pModule = "kernel32.dll"
0012F73C 77C31A70
0012F740 00000000
第三次

0012F7DC 77F45CD0/CALL 到 GetModuleHandleA 来自 77F45CCA
0012F7E0 77F4501C\pModule = "KERNEL32.DLL"
0012F7E4 00000001
0012F7E8 77F40000
第四次
0012EFD0 5D175324/CALL 到 GetModuleHandleA 来自 5D17531E
0012EFD4 5D175370\pModule = "kernel32.dll"
0012EFD8 5D1E3AB8
这里返回
5D17532485C0TEST EAX,EAX ; kernel32.7C800000
5D1753260F84 8C7B0200 JE 5D19CEB8
5D17532C68 4853175D PUSH 5D175348; ASCII "InitializeCriticalSectionAndSpinCount"
5D17533150PUSH EAX
5D175332FF15 B011175D CALL DWORD PTR DS:[5D1711B0] ; kernel32.GetProcAddress
5D175338A3 F83B1E5D MOV DWORD PTR DS:[5D1E3BF8],EAX
5D17533D85C0TEST EAX,EAX
5D17533F^ 75 A3 JNZ SHORT 5D1752E4
5D175341E9 727B0200 JMP 5D19CEB8
5D17534690NOP
5D17534790NOP

从这里开始单步跟的话大概可以找到STOLEN CODE
但是路太长了 很累所以找个简单的方法
ALT +M打开内存境像
Memory map, 项目 20
地址=00401000
大小=00001000 (4096.)
属主=UnPackMe 00400000
区段=
包含=代码,重定位
类型=映像 01001002
访问=R
初始访问=RWE

在00401000下断 SHIFT+F9运行
00401615 .C3RETN运行到这一句
00401616 .- FF25 80214000 JMP DWORD PTR DS:[402180];msvcrt._except_handler3
0040161C $- FF25 84214000 JMP DWORD PTR DS:[402184];msvcrt._controlfp
00401622/$FF7424 10 PUSH DWORD PTR SS:[ESP+10]
00401626|.FF7424 10 PUSH DWORD PTR SS:[ESP+10]
0040162A|.FF7424 10 PUSH DWORD PTR SS:[ESP+10]
0040162E|.FF7424 10 PUSH DWORD PTR SS:[ESP+10]
00401632|.E8 43000000 CALL UnPackMe.0040167A ;JMP 到 MFC42.#1576_AfxWinMain
00401637\.C2 1000 RETN 10
0040163A/$E8 BDFDFFFF CALL UnPackMe.004013FC ;JMP 到 MFC42.#1168_AfxGetModuleState
0040163F|.8B4C24 04 MOV ECX,DWORD PTR SS:[ESP+4]
00401643|.8B5424 08 MOV EDX,DWORD PTR SS:[ESP+8]
00401647|.85C9TEST ECX,ECX


单步F8运行
到达假的OEP

00401504 ? /75 0C JNZ SHORT UnPackMe.00401512
00401506 ? |68 12164000 PUSH UnPackMe.00401612
0040150B ? |FF15 6C214000 CALL DWORD PTR DS:[40216C] ;msvcrt.__setusermatherr
00401511 . |59POP ECX
00401512 . \E8 E9000000 CALL UnPackMe.00401600
00401517 .68 14304000 PUSH UnPackMe.00403014
0040151C .68 10304000 PUSH UnPackMe.00403010
00401521 .E8 D4000000 CALL UnPackMe.004015FA ;JMP 到 msvcrt._initterm
00401526 .A1 28314000 MOV EAX,DWORD PTR DS:[403128]
0040152B .8945 94 MOV DWORD PTR SS:[EBP-6C],EAX
0040152E .8D45 94 LEA EAX,DWORD PTR SS:[EBP-6C]
00401531 .50PUSH EAX
00401532 .FF35 24314000 PUSH DWORD PTR DS:[403124]
00401538 .8D45 9C LEA EAX,DWORD PTR SS:[EBP-64]
0040153B .50PUSH EAX
0040153C .8D45 90 LEA EAX,DWORD PTR SS:[EBP-70]

向上看一下被抽的代码很多
接下来找STOLEN CODE
重载同样下断bp GetModuleHandleA4次返回然后打开内存境像
在00401000处下断SHIFT+F9运行
然后单步F8到这里00A00403 /EB 04 JMP SHORT 00A00409
00A00405 |838C8C 8290391D 50OR DWORD PTR SS:[ESP+ECX*4+1D399082],50
00A0040D3040 00 XOR BYTE PTR DS:[EAX],AL
00A0041068 04154000 PUSH 401504
00A00415C3RETN

将程序向上翻
很容易看到STOLEN CODE的所在这是一部份
00A0022E64:A1 00000000MOV EAX,DWORD PTR FS:[0]
00A0023450PUSH EAX
00A0023564:8925 00000000MOV DWORD PTR FS:[0],ESP
00A0023C83EC 68 SUB ESP,68
00A0023F53PUSH EBX
00A0024056PUSH ESI
00A0024157PUSH EDI
00A002428965 E8 MOV DWORD PTR SS:[EBP-18],ESP
00A0024533DBXOR EBX,EBX
00A00247895D FC MOV DWORD PTR SS:[EBP-4],EBX
这是一部份
00A002B8FF15 7C214000 CALL DWORD PTR DS:[40217C] ; msvcrt.__set_app_type
00A002BE59POP ECX
00A002BF830D 3C314000 FFOR DWORD PTR DS:[40313C],FFFFFFFF
00A002C6830D 40314000 FFOR DWORD PTR DS:[403140],FFFFFFFF
00A002CDFF15 78214000 CALL DWORD PTR DS:[402178] ; msvcrt.__p__fmode
00A002D38B0D 30314000 MOV ECX,DWORD PTR DS:[403130]
00A002D98908MOV DWORD PTR DS:[EAX],ECX
00A002DBFF15 74214000 CALL DWORD PTR DS:[402174] ; msvcrt.__p__commode
00A002E18B0D 2C314000 MOV ECX,DWORD PTR DS:[40312C]
00A002E78908MOV DWORD PTR DS:[EAX],ECX
00A002E9A1 70214000 MOV EAX,DWORD PTR DS:[402170]
00A002EE8B00MOV EAX,DWORD PTR DS:[EAX]
00A002F0A3 38314000 MOV DWORD PTR DS:[403138],EAX
然后回到EIPF8一次

这也是一部份
00A0040A391D 50304000 CMP DWORD PTR DS:[403050],EBX

现在来的假的OEP

把假OEP上面一句NOP掉 这样会看的清楚些
跟据 对入口的判断不难发现 是MFC的程序
看一下我们找到的STOLEN CODE还少什么呢 ?
PUSH EBP
MOV EBP,ESP 这两句是固定的
PUSH XXXXXX
PUSH YYYYYY
要做的就是找 X 和Y
些时看堆栈
向下找


0012FF3C 00401616SE 处理器------YYYYYY
0012FF40 004023D0UnPackMe.004023D0- -------XXXXX
现在所有的STOLEN CODE都找到了
总结的二进制代码为
55 8B EC 6A FF 68 D0 23 40 00 68 16 16 40 00 64 A1 00 00 00 00 50 64 A1 00 00 00 00 50 64 89 25
00 00 00 00 83 EC 68 53 56 57 89 65 E8 33 DB 89 5D FC FF 15 7C 21 40 00 59 83 0D 3C 31 40 00 FF
83 0D 40 31 40 00 FF FF 15 78 21 40 00 8B 0D 30 31 40 00 89 08 FF 15 74 21 40 00 8B 0D 2C 31 40
00 89 08 A1 70 21 40 00 8B 00 A3 38 31 40 00 39 1D 50 30 40 00

二进制粘贴构建完整的OEP为
0040148F >/$55push ebp
00401490|.8BECmov ebp,esp
00401492|.6A FF push -1
00401494|.68 D0234000 push dumped_.004023D0
00401499|.68 16164000 push <jmp.&msvcrt._except_handler3>
0040149E|.64:A1 0000000>mov eax,dword ptr fs:[0]
004014A4|.50push eax
004014A5|.64:A1 0000000>mov eax,dword ptr fs:[0]
004014AB|.50push eax
004014AC|.64:8925 00000>mov dword ptr fs:[0],esp
004014B3|.83EC 68 sub esp,68
004014B6|.53push ebx
004014B7|.56push esi
004014B8|.57push edi
004014B9|.8965 E8 mov [local.6],esp
004014BC|.33DBxor ebx,ebx
004014BE|.895D FC mov [local.1],ebx
004014C1|.FF15 7C214000 call dword ptr ds:[<&msvcrt.__set_app_ty>;msvcrt.__set_app_type
004014C7|.59pop ecx
004014C8|.830D 3C314000>or dword ptr ds:[40313C],FFFFFFFF
004014CF|.830D 40314000>or dword ptr ds:[403140],FFFFFFFF
004014D6|.FF15 78214000 call dword ptr ds:[<&msvcrt.__p__fmode>] ;msvcrt.__p__fmode
004014DC|.8B0D 30314000 mov ecx,dword ptr ds:[403130]
004014E2|.8908mov dword ptr ds:[eax],ecx
004014E4|.FF15 74214000 call dword ptr ds:[<&msvcrt.__p__commode>;msvcrt.__p__commode
004014EA|.8B0D 2C314000 mov ecx,dword ptr ds:[40312C]
004014F0|.8908mov dword ptr ds:[eax],ecx
004014F2|.A1 70214000 mov eax,dword ptr ds:[<&msvcrt._adjust_f>
004014F7|.8B00mov eax,dword ptr ds:[eax]
004014F9|.A3 38314000 mov dword ptr ds:[403138],eax
004014FE|.391D 50304000 cmp dword ptr ds:[403050],ebx


在0040148F 新建EIP
LORDPE 脱壳 REC修复 一个无效指针直接CUT
脱壳结束
pcfans 发表于 2008-10-28 15:11
脱壳过程:

程序调试环境:Win Server 2003 Enterprise Edition
调试工具:某OD,LoadPE,ImportREC
********************************************************************
非常变态的一个壳,偷代码很多,而且试了10几个OD才找到一个可以调试的,也许是隐藏插件不会设置
,汗死~,这次脱壳用了最笨的方法,等公布答案了再学习先进的方法吧。

首先运行程序,打开OD,附加运行的程序,看数据窗口IAT的解码情况,知道这是个vc++的程序,从前几
期找个vc++的练习,看看程序入口是怎么样的,对比着找偷窃代码吧。
-----------------------------

记下附加后程序IAT的第一个地址00402000,ctrl+F2重载程序,在数据窗口的00402000处下内存访问断
点,shift+F9运行17次(第18次程序会跑飞)。

003F08618907MOV DWORD PTR DS:[EDI],EAX;17次后程序停在这里了
003F08638B8D C1CE4100 MOV ECX,DWORD PTR SS:[EBP+41CEC1]
003F086983C7 04 ADD EDI,4
003F086C8B06MOV EAX,DWORD PTR DS:[ESI]
003F086E85C0TEST EAX,EAX
003F08708D1C08LEA EBX,DWORD PTR DS:[EAX+ECX]
-----------------------------

鼠标往下拉寻找:
003F0966E8 0E000000 CALL 003F0979
003F096B50PUSH EAX
003F096C53PUSH EBX
003F096DE8 8EF7FFFF CALL 003F0100
003F097283C4 08 ADD ESP,8
003F0975FF6424 FC JMP DWORD PTR SS:[ESP-4];这行F4后,F8跟着跳过去找偷窃的
代码
--------------------------
程序跳到这里
00A10000 /EB 04 JMP SHORT 00A10006 ;上面的跳转来到这里
00A10002 |8182 8241D9EE EB04838CADD DWORD PTR DS:[EDX+EED94182],8C8304EB
00A1000C8C82 DB5C24FC MOV WORD PTR DS:[EDX+FC245CDB],ES
00A10012EB 04 JMP SHORT 00A10018
我们F8单步跟吧,对比打开的程序的OEP特征来寻找被偷窃的代码

--------------------------
00A1018035 65343545 XOR EAX,45353465;跟到这里的时候注意看要异或进行解码了
00A10185EB 04 JMP SHORT 00A1018B ;单步到这里,记下eax中解码的地址(004023D0)接着继续跟

--------------------------
00A1020535 65343545 XOR EAX,45353465;注意跟到这里又要解码一句了继续单步
00A1020AEB 04 JMP SHORT 00A10210 ;跟到这里看寄存器窗口,记下eax中地址(00401616 JMP 到 msvcrt._except_handler3)


怎么样这句看起来很眼熟吧,不错,这也是被偷窃的一个地址,证明我们的方向是没错的,点支烟振奋
下精神吧,哈哈,继续单步
--------------------------
00A1022D90NOP;这次来到这里了,看下面10句,都是被偷窃代码,记下来
00A1022E64:A1 00000000MOV EAX,DWORD PTR FS:[0]
00A1023450PUSH EAX
00A1023564:8925 00000000MOV DWORD PTR FS:[0],ESP
00A1023C83EC 68 SUB ESP,68

00A1023F53PUSH EBX
00A1024056PUSH ESI
00A1024157PUSH EDI
00A102428965 E8 MOV DWORD PTR SS:[EBP-18],ESP
00A1024533DBXOR EBX,EBX
00A10247895D FC MOV DWORD PTR SS:[EBP-4],EBX

00A1024AEB 04 JMP SHORT 00A10250 继续F8单步

----------------------------

00A102B790NOP;跟到这里了,OMG看看下面13句都是被偷的代码- -!赶快复制下来吧
00A102B8FF15 7C214000 CALL DWORD PTR DS:[40217C]
00A102BE59POP ECX
00A102BF830D 3C314000 FFOR DWORD PTR DS:[40313C],FFFFFFFF
00A102C6830D 40314000 FFOR DWORD PTR DS:[403140],FFFFFFFF
00A102CDFF15 78214000 CALL DWORD PTR DS:[402178]

00A102D38B0D 30314000 MOV ECX,DWORD PTR DS:[403130]
00A102D98908MOV DWORD PTR DS:[EAX],ECX
00A102DBFF15 74214000 CALL DWORD PTR DS:[402174]

00A102E18B0D 2C314000 MOV ECX,DWORD PTR DS:[40312C]
00A102E78908MOV DWORD PTR DS:[EAX],ECX
00A102E9A1 70214000 MOV EAX,DWORD PTR DS:[402170]
00A102EE8B00MOV EAX,DWORD PTR DS:[EAX]
00A102F0A3 38314000 MOV DWORD PTR DS:[403138],EAX
00A102F5EB 04 JMP SHORT 00A102FB ;单步到这里了,再继续吧看看还有没有被偷的了,继续F8
--------------------------

00A10301E8 06000000 CALL 00A1030C;跟到这里要F7跟进,不然就飞了
00A10306EB 04 JMP SHORT 00A1030C
00A10308838C8C 82EB04F7 81OR DWORD PTR SS:[ESP+ECX*4+F704EB82],FFF>
--------------------------

跟进call里了
00A1030C /EB 04 JMP SHORT 00A10312;跟进到这里,继续单步F8
00A1030E |F781 D9EEFF34 24EB0481TEST DWORD PTR DS:[ECX+34FFEED9],8104EB2>
00A1031894XCHG EAX,ESP
--------------------------

00A1037C0F31RDTSC ;跟到这里,要把这行nop掉,不然后面就出错了
继续F8
00A1037EEB 04 JMP SHORT 00A10384
--------------------------

00A10402C3RETN ;来到这行,在堆栈窗口中,记下栈顶的地址(00401615)
00A10403EB 04 JMP SHORT 00A10409 ;记好地址后在这样f4,再单步F8
--------------------------

00A1040990NOP;程序来到这里,记下下面这行代码,也是被偷窃的
00A1040A391D 50304000 CMP DWORD PTR DS:[403050],EBX
00A1041068 04154000 PUSH 401504
00A10415C3RETN ;最后到这行F4后再单步一次
--------------------------
删除分析一下
00401504 /75 0C JNZ SHORT UnPackMe.00401512 ;不容易啊,终于来到了程序的伪OEP了
00401506 |68 12164000 PUSH UnPackMe.00401612
0040150B |FF15 6C214000 CALL DWORD PTR DS:[40216C]
00401511 |59POP ECX
00401512 \E8 E9000000 CALL UnPackMe.00401600
0040151768 14304000 PUSH UnPackMe.00403014
0040151C68 10304000 PUSH UnPackMe.00403010
00401521E8 D4000000 CALL UnPackMe.004015FA
00401526A1 28314000 MOV EAX,DWORD PTR DS:[403128]
0040152B8945 94 MOV DWORD PTR SS:[EBP-6C],EAX
0040152E8D45 94 LEA EAX,DWORD PTR SS:[EBP-6C]
0040153150PUSH EAX

---------------------
下面我们就对比着以前的程序开始修补代码吧
PUSH EBP
MOV EBP,ESP
PUSH -1
这三句没找到,自己补上
---------------------
PUSH 004023D0
PUSH 00401616
这两句是上面异或解出来的两个地址,我们记下来的
---------------------
MOV EAX,DWORD PTR FS:[0]
PUSH EAX
MOV DWORD PTR FS:[0],ESP
SUB ESP,68
PUSH EBX
PUSH ESI
PUSH EDI
MOV DWORD PTR SS:[EBP-18],ESP
XOR EBX,EBX
MOV DWORD PTR SS:[EBP-4],EBX
这10句是我们刚才找到记下的
---------------------
PUSH 2
这一句没找到,就猜着补上吧
---------------------

CALL DWORD PTR DS:[40217C]
POP ECX
OR DWORD PTR DS:[40313C],FFFFFFFF
OR DWORD PTR DS:[403140],FFFFFFFF
CALL DWORD PTR DS:[402178]
MOV ECX,DWORD PTR DS:[403130]
MOV DWORD PTR DS:[EAX],ECX
CALL DWORD PTR DS:[402174]
MOV ECX,DWORD PTR DS:[40312C]
MOV DWORD PTR DS:[EAX],ECX
MOV EAX,DWORD PTR DS:[402170]
MOV EAX,DWORD PTR DS:[EAX]
MOV DWORD PTR DS:[403138],EAX
这13句是我们上面找到的
---------------------
call 00401615
这句是上面记下来堆栈窗口栈顶的那个地址
---------------------
CMP DWORD PTR DS:[403050],EBX
这句是上面我们找到的,好了全部被偷窃的代码找全了,补回去吧
---------------------
二进制代码
55 8B EC 6A FF 68 D0 23 40 00 68 16 16 40 00 64 A1 00 00 00 00 50 64 89 25 00 00 00 00 83 EC 68
53 56 57 89 65 E8 33 DB 89 5D FC 6A 02 FF 15 7C 21 40 00 59 83 0D 3C 31 40 00 FF 83 0D 40 31 40
00 FF FF 15 78 21 40 00 8B 0D 30 31 40 00 89 08 FF 15 74 21 40 00 8B 0D 2C 31 40 00 89 08 A1 70
21 40 00 8B 00 A3 38 31 40 00 E8 17 01 00 00 39 1D 50 30 40 00
---------------------
补好的OEP那部分的代码
0040148F55PUSH EBP;补好的OEP,在此新建EIP
004014908BECMOV EBP,ESP
004014926A FF PUSH -1
0040149468 D0234000 PUSH UnPackMe.004023D0
0040149968 16164000 PUSH UnPackMe.00401616
0040149E64:A1 00000000MOV EAX,DWORD PTR FS:[0]
004014A450PUSH EAX
004014A564:8925 00000000MOV DWORD PTR FS:[0],ESP
004014AC83EC 68 SUB ESP,68
004014AF53PUSH EBX
004014B056PUSH ESI
004014B157PUSH EDI
004014B28965 E8 MOV DWORD PTR SS:[EBP-18],ESP
004014B533DBXOR EBX,EBX
004014B7895D FC MOV DWORD PTR SS:[EBP-4],EBX
004014BA6A 02 PUSH 2
004014BCFF15 7C214000 CALL DWORD PTR DS:[40217C]
004014C259POP ECX
004014C3830D 3C314000 FFOR DWORD PTR DS:[40313C],FFFFFFFF
004014CA830D 40314000 FFOR DWORD PTR DS:[403140],FFFFFFFF
004014D1FF15 78214000 CALL DWORD PTR DS:[402178]
004014D78B0D 30314000 MOV ECX,DWORD PTR DS:[403130]
004014DD8908MOV DWORD PTR DS:[EAX],ECX
004014DFFF15 74214000 CALL DWORD PTR DS:[402174]
004014E58B0D 2C314000 MOV ECX,DWORD PTR DS:[40312C]
004014EB8908MOV DWORD PTR DS:[EAX],ECX
004014EDA1 70214000 MOV EAX,DWORD PTR DS:[402170]
004014F28B00MOV EAX,DWORD PTR DS:[EAX]
004014F4A3 38314000 MOV DWORD PTR DS:[403138],EAX
004014F9E8 17010000 CALL UnPackMe.00401615
004014FE391D 50304000 CMP DWORD PTR DS:[403050],EBX
0040150475 0C JNZ SHORT UnPackMe.00401512 ;原伪OEP
0040150668 12164000 PUSH UnPackMe.00401612
0040150BFF15 6C214000 CALL DWORD PTR DS:[40216C]
-------------------------------

下面就常规做法LoadPE dump,ImportREC修复,OEP填148F,自动获取输入表,剪切一个无效指针,抓取脱壳文件,程序运行正常,功能完好,脱壳完毕。
blgzs 发表于 2008-10-28 23:19
这个壳可是脱的异常艰辛啊.
而且使用的方法也比较笨,不过总算有效,把壳给搞了.
等待看高手的脱文.

我用的OD是flyODBG,用这个OD不会报错,但也有个问题,就是程序载入时到不了程序入口,不过也无所谓,到不了程序入口就到不了吧.

od载入,忽略所有异常
7C921231 C3 retn //停在这里,很明显在系统领空
7C921232 8BFF mov edi,edi
7C921234 90 nop

我们下hr 12fec0 ,为什么下这个,我们一会再说.
一直shift+F9,直到程序运行到,我们把下面这些的二进制代码复制下来
009D0261/EB 04jmp short 009D0267
009D0263|F781 D9EE812C 24A6B641 test dword ptr ds:[ecx+2C81EED9],41B6A624
009D026D 00EB add bl,ch

下面我们F8单步,都是花指令,我就不粘贴了.
一直到这里
009D02B4 83EC 04sub esp,4
009D02B7 90 nop //从这里往后的以下内容要记下来,这是OEP处被偷的代码的一部分
009D02B8 FF15 7C214000call dword ptr ds:[40217C]; msvcrt.__set_app_type
009D02BE 59 pop ecx
009D02BF 830D 3C314000 FF or dword ptr ds:[40313C],FFFFFFFF
009D02C6 830D 40314000 FF or dword ptr ds:[403140],FFFFFFFF
009D02CD FF15 78214000call dword ptr ds:[402178]; msvcrt.__p__fmode
009D02D3 8B0D 30314000mov ecx,dword ptr ds:[403130]
009D02D9 8908 mov dword ptr ds:[eax],ecx
009D02DB FF15 74214000call dword ptr ds:[402174]; msvcrt.__p__commode
009D02E1 8B0D 2C314000mov ecx,dword ptr ds:[40312C]
009D02E7 8908 mov dword ptr ds:[eax],ecx
009D02E9 A1 70214000mov eax,dword ptr ds:[402170]
009D02EE 8B00 mov eax,dword ptr ds:[eax]
009D02F0 A3 38314000mov dword ptr ds:[403138],eax

以上这些的二进制找码为:
FF 15 7C 21 40 00 59 83 0D 3C 31 40 00 FF 83 0D 40 31 40 00 FF FF 15 78 21 40 00 8B 0D 30 31 40
00 89 08 FF 15 74 21 40 00 8B 0D 2C 31 40 00 89 08 A1 70 21 40 00 8B 00 A3 38 31 40 00

记下之后,我们继续F9,此时我们刚开始下的断点 hr 12fec0 ,还没有取消
我们再F9 N次之后,来到这里
009D0403/EB 04jmp short 009D0409
009D0405|838C8C 8290391D 50 or dword ptr ss:[esp+ecx*4+1D399082],50
009D040D 3040 00xor byte ptr ds:[eax],al
009D0410 68 04154000push 401504//OEP地址
009D0415 C3 retn//注意此时的ESP为12FEC0,所以我们刚才下hr 12FEC0断点,因为在跳向OEP时要访问这个地址12FEC0

接下来,我们单步走就可以到OEP
00401504/75 0Cjnz short UnPackMe.00401512//OEP,被偷之的OEP
00401506|68 12164000push UnPackMe.00401612
0040150B|FF15 6C214000call dword ptr ds:[40216C]; msvcrt.__setusermatherr
00401511|59 pop ecx
00401512\E8 E9000000call UnPackMe.00401600

接下来,我们该补OEP了,被偷了很多.需要找个VC程序,来对比着添加.我们先用插件把壳脱了.保存为1.exe

下面我给出正常的VC6.0程序的OEP头,我们对比着来添加OEP处的代码
00402760 猜数字>/$55 push ebp
00402761 |.8BEC mov ebp,esp
00402763 |.6A FFpush -1
00402765 |.68 28554100push 猜数字游.00415528
0040276A |.68 C8294000push <jmp.&MSVCRTD._except_handler3>;SE 句柄安装
0040276F |.64:A1 00000000 mov eax,dword ptr fs:[0]
00402775 |.50 push eax
00402776 |.64:8925 00000000 mov dword ptr fs:[0],esp
0040277D |.83C4 94add esp,-6C
00402780 |.53 push ebx
00402781 |.56 push esi
00402782 |.57 push edi
00402783 |.8965 E8mov dword ptr ss:[ebp-18],esp
00402786 |.C745 FC 00000000 mov dword ptr ss:[ebp-4],0
0040278D |.6A 02push 2
0040278F |.FF15 FC764100call dword ptr ds:[<&MSVCRTD.__set_app_ty>;MSVCRTD.__set_app_type
00402795 |.83C4 04add esp,4
00402798 |.C705 40694100 FFFFFFFF mov dword ptr ds:[416940],-1
004027A2 |.A1 40694100mov eax,dword ptr ds:[416940]
004027A7 |.A3 50694100mov dword ptr ds:[416950],eax
004027AC |.FF15 20774100call dword ptr ds:[<&MSVCRTD.__p__fmode>] ;MSVCRTD.__p__fmode
004027B2 |.8B0D 2C694100mov ecx,dword ptr ds:[41692C]
004027B8 |.8908 mov dword ptr ds:[eax],ecx
004027BA |.FF15 F4764100call dword ptr ds:[<&MSVCRTD.__p__commode>;MSVCRTD.__p__commode
004027C0 |.8B15 28694100mov edx,dword ptr ds:[416928]
004027C6 |.8910 mov dword ptr ds:[eax],edx
004027C8 |.A1 F0764100mov eax,dword ptr ds:[<&MSVCRTD._adjust_f>
004027CD |.8B08 mov ecx,dword ptr ds:[eax]
004027CF |.890D 34694100mov dword ptr ds:[416934],ecx
004027D5 |.E8 D6010000call 猜数字游.004029B0
004027DA |.833D F0664100 00 cmp dword ptr ds:[4166F0],0
004027E1 |.75 0Ejnz short 猜数字游.004027F1//到这一句和我们的OEP处才一样,说明以上的代码全被偷了



重新打开一个OD,将脱壳后的程序“1.exe”载入,原OD不要关闭,我们还有用
此时我们载入的OD的版本是 ☆小生我怕怕☆.exe,这个OD版本能到程序入口处,但运行程序会出错,而flyODBG载入程序后不能到达程序入口,我们修改代码比较麻烦.
我们从401504这个地址往上看
算了算,我们从40148F处添加被偷的代码,首先,我们将下面的代码添加上
00402760 猜数字>/$55 push ebp
00402761 |.8BEC mov ebp,esp
00402763 |.6A FFpush -1
00402765 |.68 28554100push 猜数字游.00415528
0040276A |.68 C8294000push <jmp.&MSVCRTD._except_handler3>;SE 句柄安装
0040276F |.64:A1 00000000 mov eax,dword ptr fs:[0]
00402775 |.50 push eax
00402776 |.64:8925 00000000 mov dword ptr fs:[0],esp
0040277D |.83C4 94add esp,-6C
00402780 |.53 push ebx
00402781 |.56 push esi
00402782 |.57 push edi
00402783 |.8965 E8mov dword ptr ss:[ebp-18],esp
00402786 |.C745 FC 00000000 mov dword ptr ss:[ebp-4],0
0040278D |.6A 02push 2

接下来,我们将先前保存下来的二进制代码也添加上
最后,再加上这一句
004027D5 |.E8 D6010000call 猜数字游.004029B0


添加上后面的几个字节出现了花指令,把我们的OEP头给隐藏了,我们把这几个没用到的字节改成90,把我们的原来的OEP显示出来。

添完代码后,我们开始修改,因为有些地址是不正确的。
仔细观察,可发现需要修改的地方只有以下三处
0040149468 28554100 push 1.00415528
0040149968 C8294000 push 1.004029C8
....
....
004014FBE8 D6010000 call 1.004016D6

第一处和第二处是将两个值入栈,其中第二处入栈的值是SE 句柄
我们就在原来的OD中在堆栈中查找,看有SE句柄吗?
很明显,往下一拉就看到了
0012FF38 0012FF5C指针到下一个 SEH 记录
0012FF3C 00401616SE 句柄//这个值就是第二处要修改成的值
0012FF40 004023D0UnPackMe.004023D0//这个值就是第一处要修改成的值

第三处的值怎么修改呢?
我们打开一个无壳的VC6的程序,跟踪进入这个函数内,看这个函数 是怎么实现的,一看才知道这个函数的实现这么简单,只有四行代码,就是下面的四行
push ebp
mov ebp,esp
pop ebp
retn

这么简单的函数,我们自己实现算了,也不找程序中在哪里有实现了.
我们找个空白处,就定在004016AA处吧
将上面四行代码放入这个地址上
把第三处的值修改成004016AA
修改之后,我们保存修改
再用LoadPE将这个程序的入口地址改成148F

然后,双击,可以打开.不过有点不正常,就是程序上的图片没有显示出来,找了找原因,也没找到.
等待高手的脱文

嘎嘎...

2.rar

14 KB, 下载次数: 4, 下载积分: 吾爱币 -1 CB

您需要登录后才可以回帖 登录 | 注册[Register]

本版积分规则 警告:本版块禁止灌水或回复与主题无关内容,违者重罚!

快速回复 收藏帖子 返回列表 搜索

RSS订阅|小黑屋|处罚记录|联系我们|吾爱破解 - LCG - LSG ( 京ICP备16042023号 | 京公网安备 11010502030087号 )

GMT+8, 2024-4-26 03:36

Powered by Discuz!

Copyright © 2001-2020, Tencent Cloud.

快速回复 返回顶部 返回列表