ASPROTECT 2.x 脱壳系列(三)
【目 标】:BeeIcons 4.02.1
【工 具】:Olydbg1.1(diy版)、LORDPE、ImportREC1.6F
【任 务】:简单的脱壳
【操作平台】:Windows XP sp2
【作 者】:LOVEBOOM[DFCG][FCG][US]
【相关链接】:自己搜索下
【简要说明】:继上一篇,这次的目标前两篇的又有所不同了.难度稍微大了点。这次来个一气呵成:-)
【详细过程】:
OD设置:忽略除int3之外的其它异常,载入目标:
00401000 > 68 01706100
PUSH 00617001
; 壳EP
00401005 E8 01000000
CALL 0040100B
F9运行后中断下来:
0103700B 90
NOP ; 异常中断
0103700C EB 01
JMP SHORT 0103700F
0103700E 6966 81 FE47467>
IMUL ESP,
DWORD PTR DS:[
ESI-7F], 7446>
异常中断在code段下F2断点,然后shift+f9,中断:
0102267D F3:A5
REP MOVS DWORD PTR ES:[
EDI],
DWORD P>
; 中断这里
0102267F 89C1
MOV ECX,
EAX
01022681 83E1 03
AND ECX, 3
01022684 83C6 03
ADD ESI, 3
01022687 83C7 03
ADD EDI, 3
0102268A F3:A4
REP MOVS BYTE PTR ES:[
EDI],
BYTE PTR>
断下后,查找相关命令:
mov [
ebp],
eax
push 0a
找到一处,在找到的位置下硬件执行断点:
01045F7B 8945 00
MOV DWORD PTR SS:[
EBP],
EAX ; 找到这里,直接在这里下硬件执行断点
01045F7E 6A 0A
PUSH 0A
01045F80 E8 8FCEFEFF
CALL 01032E14
01045F85 8BC8
MOV ECX,
EAX
和上两篇一样,找到相关地址,然后写上相关代码:
___________________________获取CALL 01270000全部地址的修复代码_______________________________
01045F7B /EB 43
JMP SHORT 01045FC0
; 找到这里,直接在这里下硬件执行断点
01045F7D |90
NOP
01045F7E |6A 0A
PUSH 0A
01045F80 |E8 8FCEFEFF
CALL 01032E14
01045F85 |8BC8
MOV ECX,
EAX
01045F87 |038B E4000000
ADD ECX,
DWORD PTR DS:[
EBX+E4]
01045F8D |8BD6
MOV EDX,
ESI
01045F8F |8BC3
MOV EAX,
EBX
01045F91 |E8 9EE5FFFF
CALL 01044534
01045F96 |FF0C24
DEC DWORD PTR SS:[
ESP]
01045F99 |03B3 E4000000
ADD ESI,
DWORD PTR DS:[
EBX+E4]
01045F9F |833C24 00
CMP DWORD PTR SS:[
ESP], 0
01045FA3 ^|0F87 55FEFFFF
JA 01045DFE
01045FA9 |53
PUSH EBX ; 这里F2断点
01045FAA |E8 5D000000
CALL 0104600C
01045FAF |0183 EC000000
ADD DWORD PTR DS:[
EBX+EC],
EAX
01045FB5 |B0 01
MOV AL, 1
01045FB7 |83C4 24
ADD ESP, 24
01045FBA |5D
POP EBP ; BeeIcons.0040129D
01045FBB |5F
POP EDI
01045FBC |5E
POP ESI
01045FBD |5B
POP EBX
01045FBE |C3
RETN
01045FBF |90
NOP
01045FC0 \53
PUSH EBX
01045FC1 51
PUSH ECX
01045FC2 B9 00916400
MOV ECX, 649100
01045FC7 8339 00
CMP DWORD PTR DS:[
ECX], 0
01045FCA 75 06
JNZ SHORT 01045FD2
01045FCC C701 10916400
MOV DWORD PTR DS:[
ECX], 649110
; 保存相关地址数据的起始地址
01045FD2 8B19
MOV EBX,
DWORD PTR DS:[
ECX]
01045FD4 4D
DEC EBP ; BeeIcons.0040129D
01045FD5 892B
MOV DWORD PTR DS:[
EBX],
EBP ; BeeIcons.0040129D
01045FD7 83C3 04
ADD EBX, 4
01045FDA 8919
MOV DWORD PTR DS:[
ECX],
EBX
01045FDC 45
INC EBP ; BeeIcons.0040129D
01045FDD 59
POP ECX
01045FDE 5B
POP EBX
01045FDF 8945 00
MOV DWORD PTR SS:[
EBP],
EAX
01045FE2 ^ EB 9A
JMP SHORT 01045F7E
_______________________________END___________________________________________
保存好全部数据后,F9再次发生INT3异常中断:
0103700B 90
NOP ; INT 3异常中断
0103700C EB 01
JMP SHORT 0103700F
0103700E 6966 81 FE47467>
IMUL ESP,
DWORD PTR DS:[
ESI-7F], 7446>
01037015 05 31C040EB
ADD EAX, EB40C031
0103701A 0231
ADD DH,
BYTE PTR DS:[
ECX]
0103701C C031
DB SAL BYTE PTR DS:[
ECX], 0DB
; Shift constant out of range 1..31
0103701F 64:8F03
POP DWORD PTR FS:[
EBX]
; 0012FF20
01037022 83C4 04
ADD ESP, 4
01037025 EB 01
JMP SHORT 01037028
01037027 E8 5F5E5BC3
CALL C45ECE8B
0103702C 51
PUSH ECX
0103702D 52
PUSH EDX
0103702E 53
PUSH EBX
0103702F 56
PUSH ESI
01037030 57
PUSH EDI
01037031 E8 01000000
CALL 01037037
01037036 - E9 5831C031
JMP 32C3A193
0103703B D2B9 03000000
SAR BYTE PTR DS:[
ECX+3],
CL
01037041 BE 8F700301
MOV ESI, 103708F
; ASCII " \\.\SICE"
01037046 EB 01
JMP SHORT 01037049
01037048 69AC50 516A0068>
IMUL EBP,
DWORD PTR DS:[
EAX+
EDX*2+680>
01037053 6A 03
PUSH 3
01037055 6A 00
PUSH 0
01037057 6A 01
PUSH 1
01037059 EB 01
JMP SHORT 0103705C
0103705B E8 68000000
CALL 010370C8
01037060 8056 E8 A5
ADC BYTE PTR DS:[
ESI-18], 0A5
01037064 E6 FE
OUT 0FE,
AL ; I/O command
01037066 FF59 5A
CALL FAR FWORD
PTR DS:[
ECX+5A]
; Far call
01037069 40
INC EAX
0103706A 75 0C
JNZ SHORT 01037078
0103706C 01D6
ADD ESI,
EDX
0103706E EB 02
JMP SHORT 01037072
01037070 CD 20
INT 20
01037072 ^ E2 D2 LOOPD SHORT 01037046
01037074 31C0
XOR EAX,
EAX
01037076 EB 0D
JMP SHORT 01037085
01037078 48
DEC EAX
01037079 50
PUSH EAX
0103707A E8 85E6FEFF
CALL 01025704
; JMP to kernel32.CloseHandle
0103707F EB 01
JMP SHORT 01037082
01037081 0F31
RDTSC
01037083 C040 5F 5E
ROL BYTE PTR DS:[
EAX+5F], 5E
; Shift constant out of range 1..31
01037087 EB 01
JMP SHORT 0103708A
01037089 C7 ???
; Unknown command
0103708A 5B
POP EBX ; 0012FF20
0103708B 5A
POP EDX ; 0012FF20
0103708C 59
POP ECX ; 直接在这里下F2断点
0103708D C3
RETN
0103708E 9A 095C5C2E 5C5>
CALL FAR 535C:2E5C5C09
; Far call
01037095 49
DEC ECX
01037096 43
INC EBX
01037097 45
INC EBP
在0103708C处下断,shift+f9一次中断,断下后在code段下断,断下后可以看到OEP了:
00569594 55
PUSH EBP ; OEP
00569595 8BEC
MOV EBP,
ESP
00569597 83C4 F0
ADD ESP, -10
到了OEP处后,像前面的文章一样,找到保存相关地方:
01022544 85C0
TEST EAX,
EAX
01022546 > 74 0A
JE SHORT 01022552
01022548 FF15 18900401
CALL DWORD PTR DS:[1049018]
;这里改成我们自己的代码
0102254E 09C0
OR EAX,
EAX
01022550 74 01
JE SHORT 01022553
......
012800A0 9D
POPFD
012800A1 5C
POP ESP
012800A2 FF6424 FC
JMP DWORD PTR SS:[
ESP-4]
;这里设置硬件断点用于写上我们自己的代码
012800A6 54
PUSH ESP
因为这个程序里的IAT是部分加密处理过的,所以相对来说处理会麻烦一点,这个要靠自己去想怎么去解决,我的处理方法比较麻烦。可能有更好的方法,我现在还没有想到:-(.再写上一段代码和一段脚本,然后运行脚本就可以了:
________________________-相关代码_________________________________
005695D0 . 60
PUSHAD
005695D1 . B9 10916400
MOV ECX, 00649110
; 调用call address的位置
005695D6 > 8339 00
CMP DWORD PTR DS:[
ECX], 0
005695D9 . 74 17
JE SHORT 005695F2
005695DB . 8B19
MOV EBX,
DWORD PTR DS:[
ECX]
; ntdll.7C92E64E
005695DD .- FFE3
JMP EBX ; 跳去执行原call
005695DF . 66:C703 FF15
MOV WORD PTR DS:[
EBX], 15FF
; 改写成call [addr]
005695E4 . 8B15 08916400
MOV EDX,
DWORD PTR DS:[649108]
; <&comdlg32.ChooseColorA>
005695EA . 8953 02
MOV DWORD PTR DS:[
EBX+2],
EDX ; ntdll.KiFastSystemCallRet
005695ED . 83C1 04
ADD ECX, 4
005695F0 .^ EB E4
JMP SHORT 005695D6
005695F2 > 33C0
XOR EAX,
EAX ; 修复为jmp [addr]的部分
005695F4 . B9 CC951600
MOV ECX, 1695CC
005695F9 . BF 00104000
MOV EDI, 00401000
005695FE > B0 E8
MOV AL, 0E8
00569600 > F2:AE
REPNE SCAS BYTE PTR ES:[
EDI]
00569602 . 83F9 00
CMP ECX, 0
00569605 . 74 2C
JE SHORT 00569633
00569607 . 8B1F
MOV EBX,
DWORD PTR DS:[
EDI]
00569609 . 8D5C3B 04
LEA EBX,
DWORD PTR DS:[
EBX+
EDI+4]
0056960D . 81FB 00104000
CMP EBX, 00401000
00569613 .^ 72 EB
JB SHORT 00569600
00569615 . 81FB C7955600
CMP EBX, 005695C7
; 判断是否符合修复条件
0056961B .^ 77 E3
JA SHORT 00569600
0056961D . 66:8B03
MOV AX,
WORD PTR DS:[
EBX]
00569620 . 66:3D FF15
CMP AX, 15FF
00569624 . 75 0B
JNZ SHORT 00569631
00569626 . 66:C703 FF25
MOV WORD PTR DS:[
EBX], 25FF
0056962B . 83C7 04
ADD EDI, 4
0056962E . 83E9 04
SUB ECX, 4
00569631 >^ EB CB
JMP SHORT 005695FE
00569633 > 61
POPAD
00569634 . 90
NOP
00569635 . 90
NOP
00569636 . 90
NOP
00569637 . 90
NOP
00569638 . 90
NOP
00569639 . 90
NOP
0056963A . 90
NOP
0056963B . 90
NOP
0056963C . 90
NOP
0056963D . 90
NOP
0056963E . 90
NOP
0056963F . 90
NOP
00569640 . 48965600
DD dumped_.00569648
00569644 00
DB 00
00569645 00
DB 00
00569646 00
DB 00
00569647 00
DB 00
00569648 90
NOP
00569649 . 60
PUSHAD
0056964A . BD 00916400
MOV EBP, 00649100
0056964F . 90
NOP
00569650 . 8B4D 04
MOV ECX,
DWORD PTR SS:[
EBP+4]
00569653 . 0BC9
OR ECX,
ECX
00569655 . 75 18
JNZ SHORT 0056966F
; 这里修复和上两篇有所不同,这篇里的iat是加密处理过的
00569657 . B9 C4E05700
MOV ECX, <&kernel32.GetFileType>
; 对于修复加密的输入表,我采用脚本+代码的方式
0056965C . 8911
MOV DWORD PTR DS:[
ECX],
EDX ; 来修复输入表
0056965E . 894D 08
MOV DWORD PTR SS:[
EBP+8],
ECX
00569661 . 83C1 04
ADD ECX, 4
00569664 . 894D 04
MOV DWORD PTR SS:[
EBP+4],
ECX
00569667 . 90
NOP
00569668 . 90
NOP
00569669 . 90
NOP
0056966A . 90
NOP
0056966B . 90
NOP
0056966C . 90
NOP
0056966D . EB 45
JMP SHORT 005696B4
0056966F > 8BF1
MOV ESI,
ECX
00569671 . 81E9 C4E05700
SUB ECX, <&kernel32.GetFileType>
00569677 . C1E9 02
SHR ECX, 2
0056967A . 8BC2
MOV EAX,
EDX ; ntdll.KiFastSystemCallRet
0056967C . BF C4E05700
MOV EDI, <&kernel32.GetFileType>
00569681 . F2:AF
REPNE SCAS DWORD PTR ES:[
EDI]
00569683 . 0BC9
OR ECX,
ECX
00569685 . 74 08
JE SHORT 0056968F
00569687 . 83EF 04
SUB EDI, 4
0056968A . 897D 08
MOV DWORD PTR SS:[
EBP+8],
EDI ; ntdll.7C930738
0056968D . EB 25
JMP SHORT 005696B4
0056968F > 90
NOP
00569690 90
NOP ; 写好脚本和这里的代码后,先在这里下f2断
00569691 . 90
NOP ; 用于脚本判断是否为相同的DLL
00569692 . 90
NOP
00569693 . 90
NOP
00569694 . 90
NOP
00569695 . 0BD2
OR EDX,
EDX ; 通过脚本判断是否为相同的DLL,如果相同edx=0不同edx=1
00569697 . 75 0D
JNZ SHORT 005696A6
00569699 . 8906
MOV DWORD PTR DS:[
ESI],
EAX
0056969B . 8975 08
MOV DWORD PTR SS:[
EBP+8],
ESI
0056969E . 83C6 04
ADD ESI, 4
005696A1 . 8975 04
MOV DWORD PTR SS:[
EBP+4],
ESI
005696A4 . EB 0E
JMP SHORT 005696B4
005696A6 > 83C6 04
ADD ESI, 4
005696A9 . 8906
MOV DWORD PTR DS:[
ESI],
EAX
005696AB . 8975 08
MOV DWORD PTR SS:[
EBP+8],
ESI
005696AE . 83C6 04
ADD ESI, 4
005696B1 . 8975 04
MOV DWORD PTR SS:[
EBP+4],
ESI
005696B4 > 61
POPAD
005696B5 . FF15 18900401
CALL DWORD PTR DS:[1049018]
; 执行原壳的代码
005696BB . C3
RETN
_____________________END_____________________________________
____________________相关脚本_________________________________
//fix1
var dll1
var dllnow
var
addr
start:
run
l1:
cmp eip,569690 //跳去处理是否为同一DLL
je l2
cmp eip,0012800c5 //判断是否为jmp [
esp-4]处
je l6
retl2:
gn
edx
mov dllnow,$RESULT_1
cmp dll1,0
jne l3
mov dll1,dllnow
l3:
cmp dll1,dllnow
jne l4
mov edx,0
jmp l5
l4:
mov dll1,dllnow
mov edx,1
l5:
sto
jmp start
l6:
mov addr,
esp
sub addr,4
mov [
addr],5695df //修改eip
jmp start
_____________________END_____________________________________
写好了上面的东西,运行脚本,用importrec修复输入表时,有一个是GetProcAddress:
00407784 - FF25 28B45700
JMP DWORD PTR DS:[57B428]
把这个API修复好,其它无效的直接cut掉,分两次就可以把iat获取并修复好。
修复好程序并不能够运行的。通过运行发现下面的地方,就是检测是否被壳的相关地址:
0055B03B . E8 7498FDFF
CALL 005348B4
; CreateFileA
0055B040 3D A66D0D00
CMP EAX, 0D6DA6
; 判断文件大小?
0055B045 0F8E 8B000000
JLE 0055B0D6
; 如果小于或等于则跳,正常这里是跳的
因为考虑到处理反脱壳检测可能会比较麻烦,所以我直接改CreateFileA为原来没有脱壳的文件名,这样就可以通过检测,操作好后,还有一个段被抽在程序里,直接用lordpe添加段进去。这样子程序就可以运行了,不过可惜的,按菜单功能的时间还是会异常退出:-(,唉不脱了,再脱真的是脱皮而不是脱壳了。
Greetz:
Fly.Jingulong,yock,tDasm.David.hexer,hmimys,ahao.UFO(brother).alan(sister).all of my
friends
and you!
By loveboom[DFCG][FCG][US]
http://blog.csdn.net/bmd2chen
Email:loveboom#163.com
[培训]《安卓高级研修班(网课)》月薪三万计划,掌握调试、分析还原ollvm、vmp的方法,定制art虚拟机自动化脱壳的方法