【文章标题】:PEBundle+UPX的还原修复
【文章作者】: hulucc
【软件】: 咪兔象棋助手
【下载地址】:
Me2wg.rar
PEBundle已经是个很老很老的壳了,论坛里随便来个人应该都能轻易搞定,所以不会有人去写这种壳的文章吧?当然对于我这种菜B来说这个壳也可以搞很久了,所以有必要总结一下。
在网上或者看雪搜搜PEBundle的破文会发现大多数都是F8F8然后F9,接着到OEP了,然后就没有然后了。有时会不那么顺利,有ImportREC修复的时候有2个指针无效,导致程序修复完不能运行。再不顺利点就程序正常运行了,但是用上一段时间发现脱壳后的程序有功能上的缺失。
这次修复对象是咪兔象棋助手,PEBundle+UPX的壳,目标是完全还原成加壳前的状态。
让我们先来看看区段吧。
区段略多,除去自己的PE头还有8个。这些区段都是做什么的呢?想要自己分析的话可以去下个PEBundle,然后写个小demo,用高级捆绑方式(运行时不释放捆绑文件到磁盘)。这里只说结论。
PEBundle在高级捆绑模式下,会直接把捆绑文件的区段添加到主EXE后面,比如一个dll,然后在最后再加上一个pebundle段来存放壳代码。
进一步得说,PEBundle在这种模式下连压缩壳都是算不上的,你会发现文件并没有被压缩,只是被放在了一起而已。所以对于这个壳,没有必要跑到所有为OEP,直接在EP就可以dump了。
再来看看PEBundle的壳代码
00507000 > 9C pushfd
00507001 60 pushad
00507002 E8 02000000 call Me2wg_mo.00507009
00507007 33C0 xor eax,eax
00507009 8BC4 mov eax,esp
0050700B 83C0 04 add eax,0x4
0050700E 93 xchg eax,ebx
0050700F 8BE3 mov esp,ebx
00507011 8B5B FC mov ebx,dword ptr ds:[ebx-0x4]
00507014 81EB 07204000 sub ebx,Me2wg_mo.00402007
0050701A 87DD xchg ebp,ebx
0050701C 01AD BB2F4000 add dword ptr ss:[ebp+0x402FBB],ebp
00507022 01AD E5304000 add dword ptr ss:[ebp+0x4030E5],ebp
00507028 01AD 5E304000 add dword ptr ss:[ebp+0x40305E],ebp
0050702E 01AD 92314000 add dword ptr ss:[ebp+0x403192],ebp
00507034 01AD 42314000 add dword ptr ss:[ebp+0x403142],ebp
0050703A 01AD F7314000 add dword ptr ss:[ebp+0x4031F7],ebp
00507040 01AD 66324000 add dword ptr ss:[ebp+0x403266],ebp
00507046 01AD 2F324000 add dword ptr ss:[ebp+0x40322F],ebp
0050704C 01AD FD344000 add dword ptr ss:[ebp+0x4034FD],ebp
00507052 01AD 52354000 add dword ptr ss:[ebp+0x403552],ebp
00507058 E8 DF0B0000 call Me2wg_mo.00507C3C
0050705D E8 740E0000 call Me2wg_mo.00507ED6
00507062 85C0 test eax,eax
00507064 74 15 je short Me2wg_mo.0050707B
00507066 FFB5 B2214000 push dword ptr ss:[ebp+0x4021B2]
0050706C E8 E5140000 call Me2wg_mo.00508556
00507071 8985 01384000 mov dword ptr ss:[ebp+0x403801],eax
00507077 85C0 test eax,eax
00507079 75 0E jnz short Me2wg_mo.00507089
0050707B 8D85 3B234000 lea eax,dword ptr ss:[ebp+0x40233B]
00507081 C700 00000000 mov dword ptr ds:[eax],0x0
00507087 EB 3E jmp short Me2wg_mo.005070C7
00507089 8D85 5D254000 lea eax,dword ptr ss:[ebp+0x40255D]
0050708F 8D8D 91254000 lea ecx,dword ptr ss:[ebp+0x402591]
00507095 FFB5 01384000 push dword ptr ss:[ebp+0x403801]
0050709B FFB5 B2214000 push dword ptr ss:[ebp+0x4021B2]
005070A1 51 push ecx
005070A2 50 push eax
005070A3 E8 000A0000 call Me2wg_mo.00507AA8
005070A8 8D85 25264000 lea eax,dword ptr ss:[ebp+0x402625]
005070AE 8D8D 89264000 lea ecx,dword ptr ss:[ebp+0x402689]
005070B4 FFB5 01384000 push dword ptr ss:[ebp+0x403801]
005070BA FFB5 B2214000 push dword ptr ss:[ebp+0x4021B2]
005070C0 51 push ecx
005070C1 50 push eax
005070C2 E8 E1090000 call Me2wg_mo.00507AA8
005070C7 8D85 2B234000 lea eax,dword ptr ss:[ebp+0x40232B]
005070CD 50 push eax
005070CE E8 030B0000 call Me2wg_mo.00507BD6
005070D3 FFB5 B2214000 push dword ptr ss:[ebp+0x4021B2]
005070D9 FFB5 F5224000 push dword ptr ss:[ebp+0x4022F5]
005070DF E8 C90C0000 call Me2wg_mo.00507DAD
005070E4 72 17 jb short Me2wg_mo.005070FD
005070E6 FFB5 AE214000 push dword ptr ss:[ebp+0x4021AE]
005070EC FFB5 F1224000 push dword ptr ss:[ebp+0x4022F1]
005070F2 E8 B60C0000 call Me2wg_mo.00507DAD
005070F7 0F83 A9000000 jnb Me2wg_mo.005071A6
005070FD 8D9D CA214000 lea ebx,dword ptr ss:[ebp+0x4021CA]
00507103 53 push ebx
00507104 FF95 F9284000 call dword ptr ss:[ebp+0x4028F9]
0050710A 8985 BE214000 mov dword ptr ss:[ebp+0x4021BE],eax
00507110 8D9D E7224000 lea ebx,dword ptr ss:[ebp+0x4022E7]
00507116 53 push ebx
00507117 FFB5 BE214000 push dword ptr ss:[ebp+0x4021BE]
0050711D FF95 E9284000 call dword ptr ss:[ebp+0x4028E9]
00507123 8B8D C6214000 mov ecx,dword ptr ss:[ebp+0x4021C6]
00507129 51 push ecx
0050712A 8B9D C2214000 mov ebx,dword ptr ss:[ebp+0x4021C2]
00507130 85DB test ebx,ebx
00507132 75 1B jnz short Me2wg_mo.0050714F
00507134 8D8D A2224000 lea ecx,dword ptr ss:[ebp+0x4022A2]
0050713A 8D9D 09234000 lea ebx,dword ptr ss:[ebp+0x402309]
00507140 51 push ecx
00507141 53 push ebx
00507142 FFD0 call eax
00507144 83C4 0C add esp,0xC
00507147 8D8D 8D224000 lea ecx,dword ptr ss:[ebp+0x40228D]
0050714D EB 30 jmp short Me2wg_mo.0050717F
0050714F 81FB 00000100 cmp ebx,0x10000 ; UNICODE "=::=::\"
00507155 72 08 jb short Me2wg_mo.0050715F
00507157 8D8D 3B224000 lea ecx,dword ptr ss:[ebp+0x40223B]
0050715D EB 0C jmp short Me2wg_mo.0050716B
0050715F 81E3 FFFF0000 and ebx,0xFFFF
00507165 8D8D F7214000 lea ecx,dword ptr ss:[ebp+0x4021F7]
0050716B 53 push ebx
0050716C 51 push ecx
0050716D 8D8D 09234000 lea ecx,dword ptr ss:[ebp+0x402309]
00507173 51 push ecx
00507174 FFD0 call eax
00507176 83C4 10 add esp,0x10
00507179 8D8D E1214000 lea ecx,dword ptr ss:[ebp+0x4021E1]
0050717F 6A 30 push 0x30
00507181 51 push ecx
00507182 8D9D D5214000 lea ebx,dword ptr ss:[ebp+0x4021D5]
00507188 53 push ebx
00507189 FFB5 BE214000 push dword ptr ss:[ebp+0x4021BE]
0050718F FF95 E9284000 call dword ptr ss:[ebp+0x4028E9]
00507195 8D9D 09234000 lea ebx,dword ptr ss:[ebp+0x402309]
0050719B 53 push ebx
0050719C 6A 00 push 0x0
0050719E FFD0 call eax
005071A0 FFA5 CD284000 jmp dword ptr ss:[ebp+0x4028CD]
005071A6 61 popad
005071A7 9D popfd
005071A8 68 10FB4400 push Me2wg_mo.0044FB10
005071AD C3 retn
整个壳流程主要就做了一件事,模仿系统为主程序和捆绑在一起的pe文件(不是PE文件会被跳过)填写IAT,顺便把和壳的IAT一样的函数,还有捆绑dll的函数都加密重定向。说到这里你应该理解到了,如果跑到OEP除了把IAT加上密以外,没有任何其他作用。
所以正确的做法是,OD打开,停在EP,直接dump,然后就没OD什么事了。dump时需要把主程序与dll分开dump,解开捆绑,从上上图的区段表可以看出前4段是主程序的,后4段是dll的,exe和dll都被另外加了层upx,这个upx是这个程序特有的,pebundle不对原区段做任何修改(除主exe的PE头)
由于主exe会调用捆绑dll,所以先修复dll。
dump下来以后用peid看一看你会发现输入输出表都是损坏的,明明没被修改过为什么会损坏呢?问题出在upx的区段上。
dump下来的文件是按照Voffset地址保存在磁盘上的,而原先的PE头信息里的Roffset和Voffset并不相等,所以只要把dump下来的文件修改成原先在磁盘上的形式就好了。
UPX0段直接全部移除(RSize=0),UPX1段最后(4A000-49200)位0全部删除。rsrc不用动,是正确的。修改完以后再看输入输出表,信息都出来了,oep也是正确,很标准的upx。
这个时候直接用upx -d,脱掉upx(自己手脱upx区段难以完美还原,用upx自带脱壳可以完美还原),看到dll是Automation wrapper for SQLite3 database LiteX Automation 1.0.2.7版的。
接下来是主exe,主exe的upx0段到rsrc段同样没有被修改过,但不同的是pe头丢失了,dll的pe头被单独保存在一个区段当中,从图1可以看到,而主exe的pe头被pebundle的pe头所代替。除了向之前dll那样修复磁盘文件以外,要需要修改大部分pe头参数:
OEP
输入表
区段
镜像大小
我这里用的PETools改的。OEP的话(主EXE的UPX壳的入口)可以直接从pebundle壳流程倒数第二句看到,区段只要删除多余的区段就ok,确保磁盘文件格式与驱动上Roffset和Rsize一致。
输入表的话,不建议去用importRec修,理由有2个:一、不是完美修复(增加一个输入表区段),后续的upx -d进行不下去;二、主EXE的输入表里是有捆绑的那个dll的,为了得到这个dll具体导入了哪些函数,你首先要修改壳的IAT加密跳转,确保出来的都是未加密的,其次你需要注入这个dll到OD里确保importREC能够识别得到。前面说过了pebundle不修改原区段的,所以输入表还在原来的位置上,只是偏移不知道罢了。我直接用OD打开主exe的rscs段,前后翻了翻,就找到了,办法有点笨,不过没想到其他更好的办法。
最后把镜像大小改好。就OK了,直接upx -d就能够完美还原了。
顺带一提的是,如果直接用od2次堆栈平衡就能直接到oep了,不过这样会导致开局库功能的丢失(sqlite3.dll的问题),去网上下一个sqlite3.dll也和还原出来的这个长的不一样
。
unpacked.rar
[课程]FART 脱壳王!加量不加价!FART作者讲授!