PELock 1.0x -> Bartosz Wojcik简单脱壳
最近碰到PELock 1.0x -> Bartosz Wojcik的壳,以前没见过,索性研究了一下。
准备工作,忽略除内存异常外的其他异常。11次异常程序运行。
脱这个壳主要是要解决三个问题。
1:输入表。程序的输入表被替换到壳中去了。
00374661  MOV DWORD PTR DS:[ECX],EBX 
00374663  JMP SHORT 00374668
EBX中指向壳的地址,EAX为api的地址。直接改EBX为EAX的话后面的crc校验会出错。所以要想改就要先搞定crc。jingulong大虾给了一段代码,不过本人比较懒,用的是fxyang的script,速度有点慢,两三分钟才解出整个输入表
=======================================
//获取iat表Script
//by  fxyang  2005.5.20
//由于只想得到iat表,所以没有检查表的结束。
var index
#LOG

gpa "LoadLibraryA", "kernel32.dll"
bprm $RESULT,1
mov index,1
eob exp1
run

exp1:
cmp index,0
je exp2
dec index
esto

exp2:
bpmc 
rtu
bprm 00374661,1
mov index,1
eob exp3
esto

exp3:
cmp index,0
je exp4
dec index
esto

exp4:
mov [ecx],eax
add eip,2
mov index,1
esto
=========================================
2。搞定了输入表,接下来就是壳转移数据的问题了。
用401000内存断点方法dump下来,修复一下后会出现这个问题
00402814    $  53             push ebx
00402815    .  85C0           test eax,eax
00402817    .  7E 15          jle short dumped_.0040282E
00402819    .- E9 FFDBE900    jmp 012A041D  //这里出错
0040281E       00             db 00
0040281F    .  8BD8           mov ebx,eax
00402821    .  85DB           test ebx,ebx

原来这个壳把程序的一部分参数和函数的调用都弄到了动态申请的地址,dump下来的程序当然没有这个地址了,跟踪一下源程序八次异常后来到处理上面数据的地方
00378367     3017            xor byte ptr ds:[edi],dl       //特殊处理,edi放填充地址
00378369     47              inc edi
0037836A     8B16            mov edx,dword ptr ds:[esi]
0037836C     83C6 04         add esi,4
0037836F     C602 E9         mov byte ptr ds:[edx],0E9
00378372     8BC7            mov eax,edi
00378374     2BC2            sub eax,edx
00378376     83E8 05         sub eax,5
00378379     8942 01         mov dword ptr ds:[edx+1],eax
0037837C     8A06            mov al,byte ptr ds:[esi]
0037837E     46              inc esi
0037837F     0FB6C8          movzx ecx,al
00378382     83E0 03         and eax,3
00378385     C1E9 02         shr ecx,2
00378388     F3:A5           rep movs dword ptr es:[edi],dword ptr ds:[esi]
0037838A     8BC8            mov ecx,eax
0037838C     F3:A4           rep movs byte ptr es:[edi],byte ptr ds:[esi]
0037838E     8A06            mov al,byte ptr ds:[esi]
00378390     46              inc esi
00378391     03D0            add edx,eax
00378393     C607 E9         mov byte ptr ds:[edi],0E9
00378396     2BD7            sub edx,edi
00378398     83EA 05         sub edx,5
0037839B     8957 01         mov dword ptr ds:[edi+1],edx
0037839E     83C7 05         add edi,5
003783A1     4B              dec ebx
003783A2   ^ 75 C3           jnz short 00378367         //循环
第一次循环的时候在 xor byte ptr ds:[edi],dl中的edi放的是代码被转移的起始地址,看一下edi是12A000,原版打算自己添加一个段然后把数据写入这个段里,但是添加失败了,郁闷!不过dump下来的程序的中有一个起始地址5d3000,大小为1c0000的段是空的,所以直接把edi的值改为5d3000即可。
3。壳转移数据(二)
 运行修复了的程序,还是出错
00480AD4     55               push ebp
00480AD5     68 100C4800      push H_Client.00480C10
00480ADA     64:FF30          push dword ptr fs:[eax]
00480ADD     64:8920          mov dword ptr fs:[eax],esp
00480AE0     A1 E4755C00      mov eax,dword ptr ds:[5C75E4]
00480AE5     8B00             mov eax,dword ptr ds:[eax]
00480AE7     8B10             mov edx,dword ptr ds:[eax]   //指向壳中
00480AE9     FF52 14          call dword ptr ds:[edx+14]
00480AEC     33C0             xor eax,eax
跟踪原程序,发现有这么一个很长的表,程序会不断的从这个表中找调用数据
00376C44  0102A50F
00376C48  000000E9
00376C4C  00000000
00376C50  00406E3C  H_Client.00406E3C
00376C54  00406E0C  H_Client.00406E0C
00376C58  00406C30  H_Client.00406C30
00376C5C  00406BDC  H_Client.00406BDC
00376C60  00406F70  H_Client.00406F70
00376C64  00406F40  H_Client.00406F40
00376C68  00408094  H_Client.00408094
00376C6C  00408064  H_Client.00408064
这些数据跟壳是在一个段中的,但是单独把这些数据转移会出错,这个段的地址又小于基址,dump下这个段来也不好弄,搞了半天发现这个段的内存是动态申请的,重新来过,下he VitrualProtect
断下后ctrl+f9返回,eax为370000,看了一下申请的大小要比1c0000小许多,干脆把eax改为5d3000,把这个壳整个调到5d3000段,然后第八个异常的时候再处理一下上面处理的数据
00378367     3017            xor byte ptr ds:[edi],dl   
改edi为5e0000
最后修复下stolen code,纠正jmagesize后dump下来,修复输入表,ok
总结一下:
一,获取输入表
二,修改VirtualProtect返回值,修改00378367处edi值,使这些数据可以被dump下来。
三,修复stolen code,dump下来后修复输入表。
by ak[BCG][DCM][DFCG]