标 题: PELock 1.0x -> Bartosz Wojcik简单脱壳
发帖人:aki
时 间: 2005-06-05 09:18
原文链接:http://bbs.pediy.com/showthread.php?threadid=14253
详细信息:
PELock 1.0x -> Bartosz Wojcik简单脱壳
最近碰到PELock 1.0x -> Bartosz Wojcik的壳,以前没见过,索性研究了一下。
准备工作,忽略除内存异常外的其他异常。11次异常程序运行。
脱这个壳主要是要解决三个问题。
1:输入表。程序的输入表被替换到壳中去了。
00374661MOV DWORD PTR DS:,EBX
00374663JMP SHORT 00374668
EBX中指向壳的地址,EAX为api的地址。直接改EBX为EAX的话后面的crc校验会出错。所以要想改就要先搞定crc。jingulong大虾给了一段代码,不过本人比较懒,用的是fxyang的script,速度有点慢,两三分钟才解出整个输入表
=======================================
//获取iat表Script
//byfxyang2005.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 ,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:,dl //特殊处理,edi放填充地址
00378369 47 inc edi
0037836A 8B16 mov edx,dword ptr ds:
0037836C 83C6 04 add esi,4
0037836F C602 E9 mov byte ptr ds:,0E9
00378372 8BC7 mov eax,edi
00378374 2BC2 sub eax,edx
00378376 83E8 05 sub eax,5
00378379 8942 01 mov dword ptr ds:,eax
0037837C 8A06 mov al,byte ptr ds:
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:,dword ptr ds:
0037838A 8BC8 mov ecx,eax
0037838C F3:A4 rep movs byte ptr es:,byte ptr ds:
0037838E 8A06 mov al,byte ptr ds:
00378390 46 inc esi
00378391 03D0 add edx,eax
00378393 C607 E9 mov byte ptr ds:,0E9
00378396 2BD7 sub edx,edi
00378398 83EA 05 sub edx,5
0037839B 8957 01 mov dword ptr ds:,edx
0037839E 83C7 05 add edi,5
003783A1 4B dec ebx
003783A2 ^ 75 C3 jnz short 00378367 //循环
第一次循环的时候在 xor byte ptr ds:,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:
00480ADD 64:8920 mov dword ptr fs:,esp
00480AE0 A1 E4755C00 mov eax,dword ptr ds:
00480AE5 8B00 mov eax,dword ptr ds:
00480AE7 8B10 mov edx,dword ptr ds: //指向壳中
00480AE9 FF52 14 call dword ptr ds:
00480AEC 33C0 xor eax,eax
跟踪原程序,发现有这么一个很长的表,程序会不断的从这个表中找调用数据
00376C440102A50F
00376C48000000E9
00376C4C00000000
00376C5000406E3CH_Client.00406E3C
00376C5400406E0CH_Client.00406E0C
00376C5800406C30H_Client.00406C30
00376C5C00406BDCH_Client.00406BDC
00376C6000406F70H_Client.00406F70
00376C6400406F40H_Client.00406F40
00376C6800408094H_Client.00408094
00376C6C00408064H_Client.00408064
这些数据跟壳是在一个段中的,但是单独把这些数据转移会出错,这个段的地址又小于基址,dump下这个段来也不好弄,搞了半天发现这个段的内存是动态申请的,重新来过,下he VitrualProtect
断下后ctrl+f9返回,eax为370000,看了一下申请的大小要比1c0000小许多,干脆把eax改为5d3000,把这个壳整个调到5d3000段,然后第八个异常的时候再处理一下上面处理的数据
00378367 3017 xor byte ptr ds:,dl
改edi为5e0000
最后修复下stolen code,纠正jmagesize后dump下来,修复输入表,ok
总结一下:
一,获取输入表
二,修改VirtualProtect返回值,修改00378367处edi值,使这些数据可以被dump下来。
三,修复stolen code,dump下来后修复输入表。
by ak 标 题: PELock1.0x脱壳实例
发帖人:fxyang
时 间: 2005-05-24 11:12
原文链接:http://bbs.pediy.com/showthread.php?threadid=13924
详细信息:
PELock 1.0x -> Bartosz Wojcik脱壳实例之CryptCD Professional version 4.0.exe
下载地址:http://bbs.hanzify.org/index.php?act=Attach&type=post&id=14354
1.借尸还魂--搞定iat表
用OD加载CryptCD Professional version 4.0.exe
OD的异常全部勾上,到壳的入口:
0049D05C >JMP SHORT CryptCD_.0049D060
0049D05EXCHG ESP,ESI
0049D060CLC
0049D061JNB SHORT CryptCD_.0049D064
Alt+E打开模块窗口,光标选择kernel32 (system) Ctrl+N打开函数窗口
找到LoadLibraryA这个函数,双击它:
77E5D8B4 >CMP DWORD PTR SS:,0
77E5D8B9PUSH EBX
77E5D8BAPUSH ESI
77E5D8BBJE SHORT kernel32.77E5D8D6
在77E5D8B9PUSH EBX 这行下内存访问中断,F9运行程序:
第二次中断在:
00374CD9MOV EDX,DWORD PTR DS:
00374CDCJMP SHORT 00374CE1
......
0037501DMOV EAX,DWORD PTR DS:
0037501FMOV EDX,EAX
00375021CMP AL,0CC
00375023JNZ SHORT 00375054
......
00375B22MOV AL,BYTE PTR DS:
00375B24INC ECX
00375B25OR EDX,DWORD PTR DS:
00375B28TEST DL,8
00375B2BJNZ SHORT 00375B1F
壳会全程检查函数代码,所以int3中断不能使用。
Shift+F9继续运行,直到重新被中断在函数中
77E5D8B9PUSH EBX
77E5D8BAPUSH ESI
77E5D8BBJE SHORT kernel32.77E5D8D6
堆栈中出现:
0012EA54 72F44841返回到 72F44841 来自 kernel32.LoadLibraryA
0012EA58 72F1A978ASCII "gdi32.dll"
回到壳代码中,F7运行到:
00374661MOV DWORD PTR DS:,EBX
00374663JMP SHORT 00374668
EAX 77D18ABC USER32.TranslateMessage
ECX 00426288 CryptCD_.00426288
EDX 77D10000 USER32.77D10000
EBX 003E193F
ESP 0012FFAC
EBP 0037062D
ESI 00380399
EDI 00380389 ASCII "USER32.dll"
EIP 00374661
分析代码发现,是iat表中的地址,EBX是加密后的函数地址,再仔细分析发现,
这时候的EAX中就是未加密的函数,如果把:
00374661MOV DWORD PTR DS:,EBX
修改成:
00374661MOV DWORD PTR DS:,EAX
嘿嘿就可以得到正确的iat表了,修改看看
继续运行,出现Invalid version of library USER32.dll错误。是因为下面的CRC没有通过。
没有关系,用OllyScript来搞定它:
=======================================
//PELock 1.0x 脱壳实例之CryptCD Professional version 4.0
//获取iat表Script
//byfxyang2005.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 ,eax
add eip,2
mov index,1
esto
=========================================
脚本完成后到iat表中看看:
00426000D8 17 DA 77 9A 22 DA 77?趙?趙
0042600868 6A DB 77 10 24 DA 77hj踳$趙
0042601000 00 00 00 A4 7F 33 77....?3w
......
00426370CF 90 32 76 0F DA 33 76蠍2v?v
0042637800 00 00 00 59 58 F3 4F....YX驩
004263800B 65 EE 4F 00 10 EF 4Fe頞.颫
00426388A8 12 EF 4F A6 F2 ED 4F?颫︱鞳
0042639000 00 00 00 00 00 00 00........
一个完整的表,用Import.Reconstructor得到完整的表,保存备用。
2.修复被壳转移的代码
重新OD加载程序,重新对LoadLibraryA函数的代码下内存访问中断。F9运行:
在第二次被中断在函数中时,Alt+M打开内存窗口,双击00401000段:
00401000MOV EAX,DWORD PTR SS:
00401004MOV DWORD PTR DS:,EAX
00401009CALL CryptCD_.00401080
0040100ECALL CryptCD_.00401320
00401013CALL CryptCD_.00403A20
00401018TEST EAX,EAX
0040101AJNZ SHORT CryptCD_.00401033
0040101CPUSH 5BCD98
00401021PUSH 6DE6CC
00401026CALL CryptCD_.00403560
对0040101CPUSH 5BCD98下内存访问中断,Shift+F9运行:
003780F0PUSHAD
003780F1PUSH 4
003780F3PUSH 3000
003780F8PUSH 5D58
003780FDPUSH 0
003780FFCALL DWORD PTR SS:
00378102XCHG EAX,EDI
00378103CALL 003780E9
00378108LEA ESI,DWORD PTR SS:
0037810BSUB ESI,0BAB
00378111PUSH ESI
00378112MOV EBX,101
00378117XOR BYTE PTR DS:,DL
00378119INC EDI
0037811AMOV EDX,DWORD PTR DS:
0037811CADD ESI,4
0037811FMOV BYTE PTR DS:,0E9
00378122MOV EAX,EDI
00378124SUB EAX,EDX
00378126SUB EAX,5
00378129MOV DWORD PTR DS:,EAX
0037812CMOV AL,BYTE PTR DS:
0037812EINC ESI
0037812FMOVZX ECX,AL
00378132AND EAX,3
00378135SHR ECX,2
00378138REP MOVS DWORD PTR ES:,DWORD PTR DS:
0037813AMOV ECX,EAX
0037813CREP MOVS BYTE PTR ES:,BYTE PTR DS:
0037813EMOV AL,BYTE PTR DS:
00378140INC ESI
00378141ADD EDX,EAX
00378143MOV BYTE PTR DS:,0E9
00378146SUB EDX,EDI
00378148SUB EDX,5
0037814BMOV DWORD PTR DS:,EDX
0037814EADD EDI,5
00378151DEC EBX
00378152JNZ SHORT 00378117
00378154POP EDI
00378155LEA ECX,DWORD PTR SS:
00378158SUB ECX,EDI
0037815AREP STOS BYTE PTR ES:
0037815CPOPAD
0037815DRETN
这段代码就是把程序的代码修改为调用到壳中转移的地址,分析这段代码
0037811FMOV BYTE PTR DS:,0E9
修改指向的地址40101C为JMP
00378122MOV EAX,EDI
00378124SUB EAX,EDX
00378126SUB EAX,5
00378129MOV DWORD PTR DS:,EAX
计算跳转偏移,然后写入到程序中
0037812CMOV AL,BYTE PTR DS:
0037812EINC ESI
0037812FMOVZX ECX,AL
00378132AND EAX,3
00378135SHR ECX,2
00378138REP MOVS DWORD PTR ES:,DWORD PTR DS:
0037813AMOV ECX,EAX
0037813CREP MOVS BYTE PTR ES:,BYTE PTR DS:
到指向的地址看看:
0037753E1C 10 40 00 05 68 C4 82@.h膫
0037754642 00 05 21 10 40 00 05B.!@.
0037754E68 B8 82 42 00 05 38 10h競B.8
0037755640 00 05 68 18 82 42 00@.h侭.
0037755E05 3D 10 40 00 05 68 08=@.h
0037756682 42 00 05 53 10 40 00侭.S@.
0037756E05 68 F0 81 42 00 05 58h饋B.X
0037757610 40 00 05 68 E4 81 42@.h鋪B
0037757E00 05 81 10 40 00 12 8D.?@.
这个地址中其实是一个表,表的组成是:
1.)需要修改的程序地址 :1C 10 40 00
2.)需要复制到壳申请临时空间的代码长度:05
3.)需要转移的代码:68 C4 82 42 00
4.)写入jump回程序中地址的偏移:05
0037813EMOV AL,BYTE PTR DS:
00378140INC ESI
00378141ADD EDX,EAX
00378143MOV BYTE PTR DS:,0E9
00378146SUB EDX,EDI
00378148SUB EDX,5
0037814BMOV DWORD PTR DS:,EDX
计算jump回到程序中的偏移,写入jump回的代码
分析完了上面的流程和方法后,就可以利用这段代码把转移的代码写回到程序中:
修改:
003780F0PUSHAD
003780F1PUSH 4
003780F3PUSH 3000
003780F8PUSH 5D58
003780FDPUSH 0
003780FFCALL DWORD PTR SS:
00378102XCHG EAX,EDI
00378103CALL 003780E9
00378108LEA ESI,DWORD PTR SS:
0037810BSUB ESI,0BAB
00378111PUSH ESI
00378112MOV EBX,101
00378117NOP
00378118NOP
00378119INC EDI
0037811AMOV EDX,DWORD PTR DS:
0037811CADD ESI,4
0037811FMOV EDI,EDX //关键,把壳的地址替换为程序的地址
00378121NOP
00378122MOV EAX,EDI
00378124SUB EAX,EDX
00378126SUB EAX,5
00378129NOP
0037812ANOP
0037812BNOP
0037812CMOV AL,BYTE PTR DS:
0037812EINC ESI
0037812FMOVZX ECX,AL
00378132AND EAX,3
00378135SHR ECX,2
00378138REP MOVS DWORD PTR ES:,DWORD PTR DS:
0037813AMOV ECX,EAX
0037813CREP MOVS BYTE PTR ES:,BYTE PTR DS:
0037813EMOV AL,BYTE PTR DS:
00378140INC ESI
00378141ADD EDX,EAX
00378143NOP
00378144NOP
00378145NOP
00378146SUB EDX,EDI
00378148SUB EDX,5
0037814BNOP
0037814CNOP
0037814DNOP
0037814EADD EDI,5
00378151DEC EBX
00378152JNZ SHORT 00378117
00378154POP EDI
00378155LEA ECX,DWORD PTR SS:
00378158SUB ECX,EDI
0037815AREP STOS BYTE PTR ES:
0037815CPOPAD
0037815DRETN
修改完成后,F4到0037815DRETN
Alt+M打开内存窗口,在00401000的代码段下内存访问中断,Shift+F9运行程序:
0041B9D4CALL DWORD PTR DS:
0041B9DAXOR EDX,EDX
0041B9DCMOV DL,AH
0041B9DEMOV DWORD PTR DS:,EDX
这是程序的伪OEP,在堆栈中检查:
0012FFA8 0012FFB8指针到下一个 SEH 记录
0012FFAC 0041F270SE 句柄
0012FFB0 004263F0CryptCD_.004263F0
0012FFB4 FFFFFFFF
0012FFB8 0012FFE0指针到下一个 SEH 记录
这个程序是VC++编译的,根据堆栈中的数据恢复代码:
0041B9AE >PUSH EBP
0041B9AFMOV EBP,ESP
0041B9B1PUSH -1
0041B9B3PUSH CryptCD_.004263F0
0041B9B8PUSH CryptCD_.0041F270 ;SE handler installation
0041B9BDMOV EAX,DWORD PTR FS:
0041B9C3PUSH EAX
0041B9C4MOV DWORD PTR FS:,ESP
0041B9CBSUB ESP,58
0041B9CEPUSH EBX
0041B9CFPUSH ESI
0041B9D0PUSH EDI
0041B9D1MOV DWORD PTR SS:,ESP
用LordPE dump下程序,修改程序的OEP为0041B9AE,保存备用.
3.还原IAT表
用Import.Reconstructor加载保存的iat表,去掉增加新的区段的勾,然后在新的输入表信息的
RVA 中填入原iat表的RVA 00026000 在OEP中填入0001B9AE 后,修复上面保存的dump程序.
看似修复好了iat表,运行看看,程序不见了:( 看来还是有问题.有什么问题呢?
用OD 加载原程序,直接运行,运行成功后来到imports段00426000
再用OD加载修复后的dump程序,比较imports段和原来的有些什么不同,发现原imports表中多了些数据:
0042639000 00 00 00 00 00 00 00 9A 99 99 99 99 99 E9 3F........殭櫃櫃?
004263A000 00 00 00 00 00 50 3F 00 00 80 3A 00 00 00 00......P?.. 原帖由 繁华亦凄凉 于 2006-6-23 15:27 发表
我很菜,想和大家学点东西,感谢有这么一个空间.
我刚刚学脱壳不久,遇到了俩很难的壳.
在网上找了很就,没有找到太好的解决办法(也许我太菜了)
希望高人可以点动画来帮助我们刚刚接触脱壳的小菜鸟.
一个 ...
刚刚学脱壳,建议从简单的如:UPX,ASP开始~~
页:
[1]