首页
社区
课程
招聘
Unpacking yP v1.01
发表于: 2004-8-27 20:48 7521

Unpacking yP v1.01

2004-8-27 20:48
7521
Unpacking yP v1.01

不忽略INT3异常:

00450060 >PUSH EBP
00450061  MOV EBP,ESP
00450063  PUSH EBX
00450064  PUSH ESI
00450065  PUSH EDI
00450066  CALL yP.0045006E

跳过5次SEH以后,下断点bp Process32Next,然后Shift+F9,来到:
77E9BCD3 >PUSH EBP
77E9BCD4  MOV EBP,ESP
77E9BCD6  SUB ESP,22C
77E9BCDC  PUSH EBX
77E9BCDD  PUSH ESI

取消断点,Alt+F9返回:
00450636  CALL DWORD PTR DS:[EDX]
00450638  TEST EAX,EAX				;从这里出来
0045063A  JE SHORT yP.004506AA
0045063C  MOV EBX,DWORD PTR SS:[ESP+C]
00450641  JMP SHORT yP.00450646
00450643  LEA ECX,DWORD PTR DS:[ECX]
00450646  MOV EAX,DWORD PTR SS:[ESP+20]
0045064B  LEA ESI,DWORD PTR SS:[ESP+3C]
00450650  MOV EDI,ESI
00450652  PUSH ESI
00450653  PUSH EDI
00450654  CALL yP.00450E6C
00450659  ADD ESP,8
0045065C  PUSH EDI
0045065D  PUSH ESI
0045065E  CALL yP.00450EBC
00450663  ADD ESP,8
00450666  MOV ESI,EDI
00450668  MOV EDX,EBP
0045066A  ADD EDX,yP.0041FFF6
00450670  LEA EDI,DWORD PTR DS:[EDX]
00450672  MOV ECX,0D
00450677  XOR EDX,EDX
00450679  REPE CMPS BYTE PTR ES:[EDI],BYTE PTR DS:>
0045067B  JNZ SHORT yP.0045067F
0045067D  MOV EBX,EAX
0045067F  CMP EAX,DWORD PTR SS:[ESP+14]
00450684  JNZ SHORT yP.00450690
00450686  MOV EAX,DWORD PTR SS:[ESP+30]
0045068B  MOV DWORD PTR SS:[ESP+10],EAX
00450690  MOV EDX,DWORD PTR SS:[ESP+C]
00450695  LEA ECX,DWORD PTR SS:[ESP+18]
0045069A  PUSH ECX
0045069B  PUSH EDX
0045069C  MOV EDX,EBP
0045069E  ADD EDX,yP.0041FF62
004506A4  CALL DWORD PTR DS:[EDX]
004506A6  TEST EAX,EAX
004506A8  JNZ SHORT yP.00450646
004506AA  MOV EAX,DWORD PTR SS:[ESP+10]
004506AF  CMP EAX,EBX				;句柄比较
004506B1  JE SHORT yP.004506D3			;在这里让Z标志翻转
004506B3  PUSH EAX
004506B4  PUSH 1
004506B6  PUSH 1F0FFF
004506BB  MOV EDX,EBP
004506BD  ADD EDX,yP.0041FF95
004506C3  CALL DWORD PTR DS:[EDX]		;OpenProcess
004506C5  PUSH 0
004506C7  PUSH EAX
004506C8  MOV EDX,EBP
004506CA  ADD EDX,yP.0041FFAA
004506D0  CALL DWORD PTR DS:[EDX]		;TerminateProcess
004506D2  RETN					;永远不会走到这里

下面还有2次同样类型的检测,都这样跳过去,最后走到这里:
004511EF  XOR EAX,EAX
004511F1  MOV ECX,88
004511F6  MOV EDX,EBP
004511F8  ADD EDX,yP.00420030
004511FE  LEA EDI,DWORD PTR DS:[EDX]

下断点bp LoadLibraryA,走到这里:
0045146B  PUSH EBX
0045146C  MOV EDX,EBP
0045146E  ADD EDX,yP.0041FE42
00451474  CALL DWORD PTR DS:[EDX]                  ; KeRnEl32.LoadLibraryA
00451476  TEST EAX,EAX
00451478  JE yP.004515C4
0045147E  PUSH EDX
0045147F  PUSH EAX
00451480  MOV EDX,EBP
00451482  ADD EDX,yP.0041FD96
00451488  TEST DWORD PTR DS:[EDX],4
0045148E  JE SHORT yP.004514A2
00451490  MOV EDX,EBP
00451492  ADD EDX,yP.0041F8C2
00451498  LEA EAX,DWORD PTR DS:[EDX]

…………
…………

00451770  MOV BYTE PTR DS:[EAX],0		;清空dll字符串,NOP掉
00451774  INC EAX
00451775  CMP BYTE PTR DS:[EAX],0
00451779  JNZ SHORT yP.00451770

上面是加载dll,下面开始填充输入表:
004514A2  POP EBX
004514A3  POP EDX
004514A4  MOV ECX,DWORD PTR DS:[ESI+8]
004514A8  OR ECX,ECX				;是否有输入函数?
004514AA  JNZ SHORT yP.004514B0
004514AC  MOV ECX,DWORD PTR DS:[ESI+4]
004514B0  PUSH EBX

………………
………………

004514F1  PUSH EBX
004514F2  MOV EDX,EBP
004514F4  ADD EDX,yP.0041FE46
004514FA  CALL DWORD PTR DS:[EDX]                  ; KeRnEl32.GetProcAddress
004514FC  OR EAX,EAX
004514FE  JNZ SHORT yP.00451507
00451500  POP ECX

上面取函数地址

下面有一段清空函数名字符串:
00451770  MOV BYTE PTR DS:[EAX],0		;清空函数名,NOP掉
00451774  INC EAX
00451775  CMP BYTE PTR DS:[EAX],0
00451779  JNZ SHORT yP.00451770

注意下面这段代码:
00451589  PUSH EDI
0045158A  PUSH ESI
0045158B  MOV ECX,EBP
0045158D  ADD ECX,yP.00420030
00451593  LEA EDI,DWORD PTR DS:[ECX]
00451595  MOV ESI,DWORD PTR DS:[EDI+4]
00451599  MOV DWORD PTR DS:[EDX],ESI		;改成 MOV DWORD PTR DS:[EDX],EAX
0045159B  SUB EAX,ESI
0045159D  SUB EAX,5
004515A0  MOV BYTE PTR DS:[ESI],0E9		;生成JMP表
004515A3  MOV DWORD PTR DS:[ESI+1],EAX
004515A6  ADD DWORD PTR DS:[EDI+4],5
004515AB  POP ESI
004515AC  POP EDI
004515AD  POP ECX
004515AE  ADD ECX,4
004515B1  ADD EDX,4
004515B4  JMP yP.004514C2


原来外壳在动态申请的空间里形成了API跳转表,把IAT指向这个跳转表,这样ImportRec就不能恢复了
既然这样我们就直接patch,把输入函数地址直接填充到IAT中

把 00451599  MOV DWORD PTR DS:[EDX],ESI 这句
改成 00451599  MOV DWORD PTR DS:[EDX],EAX

EAX中恰好为输入函数的地址。

可以在这里设断点观察IAT的范围,等到EDX发生大范围变化的时候就可以用ImportRec收集了。

但是注意后面有CRC校验,所以必须重新跟踪一次到OEP,方法是对code段设内存镜像访问断点即可。

修复后出现异常,对照fly的unpacked发现是输入表识别问题,1.6把comdlg32.dll认错了,还有shell32.dll没认出来,不知道是不是ImportRec 1.6的bug(近日有此类流言)。一遍遍修复太麻烦,哪位兄弟写个Script再试试。

[课程]Linux pwn 探索篇!

收藏
免费 7
支持
分享
最新回复 (12)
雪    币: 221
活跃值: (55)
能力值: ( LV4,RANK:50 )
在线值:
发帖
回帖
粉丝
2
2004-8-27 22:50
0
雪    币: 898
活跃值: (4039)
能力值: ( LV9,RANK:3410 )
在线值:
发帖
回帖
粉丝
3
可以直接用ImportREC修复输入表的
我就是用ImportREC汉化版修复的
手动填入RVA和SIZE就行了
2004-8-27 23:04
0
雪    币: 392
活跃值: (909)
能力值: ( LV9,RANK:690 )
在线值:
发帖
回帖
粉丝
4
第一次写脚本,不妥之处敬请指教:D

//Script for yoda's Protector v1.01

//by cyclotron [BCG][DFCG][FCG][OCN]


//收集IAT

//━━━━━━━━━━━━━━━━━━━━━━━━━━━

gpa "Process32Next","kernel32.dll" 

bp $RESULT

run			//F9

bc $RESULT		//clear bp

rtu			//run to user code

find eip,#3BC374#	//cmp eax,ebx

add $RESULT,2		//next instruction

bp $RESULT

run

bc $RESULT

mov !ZF,1		//置Z标志

//━━━━━━━━━━━━━━━━━━━━━━━━━━━

gpa "Process32Next","kernel32.dll" 

bp $RESULT

run			//F9

bc $RESULT		//clear bp

rtu			//run to user code

find eip,#3BC374#	//cmp eax,ebx

add $RESULT,2		//next instruction

bp $RESULT

run

bc $RESULT

mov !ZF,1		//置Z标志

//━━━━━━━━━━━━━━━━━━━━━━━━━━━

gpa "Process32Next","kernel32.dll" 

bp $RESULT

run			//F9

bc $RESULT		//clear bp

rtu			//run to user code

find eip,#3BC374#	//cmp eax,ebx

add $RESULT,2		//next instruction

bp $RESULT

run

bc $RESULT

mov !ZF,1		//置Z标志

//━━━━━━━━━━━━━━━━━━━━━━━━━━━

gpa "LoadLibraryA","kernel32.dll" 

bp $RESULT

run			//F9

bc $RESULT		//clear bp

rtu			//run to user code

gpa "GetProcAddress","kernel32.dll" 

bp $RESULT

run			//F9

bc $RESULT		//clear bp

rtu			//run to user code

//━━━━━━━━━━━━━━━━━━━━━━━━━━━

bp 451599

run

bc 451599

asm eip,"MOV DWORD PTR [EDX],EAX"

add eip,2

bp eip

run

msg "IAT收集开始"

pause
2004-8-27 23:59
0
雪    币: 392
活跃值: (909)
能力值: ( LV9,RANK:690 )
在线值:
发帖
回帖
粉丝
5
//Script for yoda's Protector v1.01

//by cyclotron [BCG][DFCG][FCG][OCN]


//直取OEP

//━━━━━━━━━━━━━━━━━━━━━━━━━━━

gpa "Process32Next","kernel32.dll" 

bp $RESULT

run			//F9

bc $RESULT		//clear bp

rtu			//run to user code

find eip,#3BC374#	//cmp eax,ebx

add $RESULT,2		//next instruction

bp $RESULT

run

bc $RESULT

mov !ZF,1		//置Z标志

//━━━━━━━━━━━━━━━━━━━━━━━━━━━

gpa "Process32Next","kernel32.dll" 

bp $RESULT

run			//F9

bc $RESULT		//clear bp

rtu			//run to user code

find eip,#3BC374#	//cmp eax,ebx

add $RESULT,2		//next instruction

bp $RESULT

run

bc $RESULT

mov !ZF,1		//置Z标志

//━━━━━━━━━━━━━━━━━━━━━━━━━━━

gpa "Process32Next","kernel32.dll" 

bp $RESULT

run			//F9

bc $RESULT		//clear bp

rtu			//run to user code

find eip,#3BC374#	//cmp eax,ebx

add $RESULT,2		//next instruction

bp $RESULT

run

bc $RESULT

mov !ZF,1		//置Z标志

//━━━━━━━━━━━━━━━━━━━━━━━━━━━

var cbase

gmi eip,CODEBASE

mov cbase,$RESULT

var csize

gmi eip,CODESIZE

mov csize,$RESULT

bprm cbase,csize	//内存读断点

run

bpmc

pause

2004-8-28 00:00
0
雪    币: 392
活跃值: (909)
能力值: ( LV9,RANK:690 )
在线值:
发帖
回帖
粉丝
6
最初由 fly 发布
可以直接用ImportREC修复输入表的
我就是用ImportREC汉化版修复的
手动填入RVA和SIZE就行了


fly在哪里确定IAT的RVA和Size的?
2004-8-28 00:01
0
雪    币: 200
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
7
thanks for the excellent tut...:)
2004-8-28 00:06
0
雪    币: 898
活跃值: (4039)
能力值: ( LV9,RANK:3410 )
在线值:
发帖
回帖
粉丝
8
最初由 cyclotron 发布


fly在哪里确定IAT的RVA和Size的?


随便找个调用
转存里就可以看见
然后用追踪层次1就行了
2004-8-28 02:15
0
雪    币: 392
活跃值: (909)
能力值: ( LV9,RANK:690 )
在线值:
发帖
回帖
粉丝
9
最初由 fly 发布



随便找个调用
转存里就可以看见
然后用追踪层次1就行了


到入口以后认不出来的还要多,不少13XXXX都认不出来,追踪层次1也没用……
2004-8-28 10:32
0
雪    币: 898
活跃值: (4039)
能力值: ( LV9,RANK:3410 )
在线值:
发帖
回帖
粉丝
10
这个只是改了一下跳转表
填入RVA和Size
追踪层次1完全可以搞定
2004-8-28 13:01
0
雪    币: 296
活跃值: (250)
能力值: ( LV9,RANK:210 )
在线值:
发帖
回帖
粉丝
11
高深
2004-10-2 23:18
0
雪    币: 93908
活跃值: (200199)
能力值: (RANK:10 )
在线值:
发帖
回帖
粉丝
12
最初由 cyclotron 发布
Unpacking yP v1.01

不忽略INT3异常:

[code]
........


支持!!!
2004-10-3 00:30
0
雪    币: 221
活跃值: (70)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
13
好贴:D
2004-10-3 08:15
0
游客
登录 | 注册 方可回帖
返回
//