-
-
ASPACK外壳一点分析
-
2004-8-12 20:15
6313
-
【目 标】:随便抓了个ASPACK2.12加的DLL来看看而已
【工 具】:Olydbg1.1,lordpe,imp.
【任 务】:ASPACK2.12的粗略反向(可惜压缩部分没有去反)
【操作平台】:WINXP pro sp1
【作 者】:loveboom[DFCG][FCG][US]
【相关链接】: 附件就是了
【简要说明】:这么久没写任何东西也不说什么好,烦人的事太多,也严重怀疑自己不懂怎么脱壳了?其它的东西也不想说太多,这篇文章也是断断继继写出来的。如有什么不足之处,请多指教。
【详细过程】:
也没什么特别的设置,因为是PACKER来的,所以不用担心你的OD挂的.用OD载入,然后分析之.
1001F001 > 60
PUSHAD ; 壳入口
1001F002 E8 03000000
CALL cesi.1001F00A
1001F007 90
NOP ; 花指令,nop掉
1001F008 EB 04
JMP SHORT cesi.1001F00E
1001F00A 5D
POP EBP
1001F00B 45
INC EBP
1001F00C 55
PUSH EBP
1001F00D C3
RETN
1001F00E E8 01000000
CALL cesi.1001F014
1001F013 90
NOP ; 花指令
1001F014 5D
POP EBP ; 这里就相关于mov ebp,[esp]
1001F015 BB EDFFFFFF
MOV EBX,-13
1001F01A 03DD
ADD EBX,
EBP
1001F01C 81EB 00F00100
SUB EBX,1F000
; 这几步运算就是计算当然段的IMAGEBASE
1001F022 83BD 22040000 0>
CMP DWORD PTR SS:[
EBP+422],0
; 比较[EBP+422]处有没有东西,如果有就掉去结束处
1001F029 899D 22040000
MOV DWORD PTR SS:[
EBP+422],
EBX ; 这里给[EBP+422]赋上当前段的CODEBASE
1001F02F 0F85 65030000
JNZ cesi.1001F39A
; 如果已经解压完毕就准备跳去oep处了
1001F035 8D85 2E040000
LEA EAX,
DWORD PTR SS:[
EBP+42E]
; 把kernel32.dll赋值给eax,用于后面的取API函数
1001F03B 50
PUSH EAX
1001F03C FF95 4D0F0000
CALL DWORD PTR SS:[
EBP+F4D]
; 这里就是GetModuleHandleA,用来取kernel32.dll的BASE
1001F042 8985 26040000
MOV DWORD PTR SS:[
EBP+426],
EAX ; 把Module Base放到[ebp+426]处
1001F048 8BF8
MOV EDI,
EAX ; 同时把BASE移入edi中,这里取出的BASE==77E40000
1001F04A 8D5D 5E
LEA EBX,
DWORD PTR SS:[
EBP+5E]
; [ebp+5E]处存放了VirtualAlloc
1001F04D 53
PUSH EBX ; 字符串地址入栈
1001F04E 50
PUSH EAX ; base入栈
1001F04F FF95 490F0000
CALL DWORD PTR SS:[
EBP+F49]
; 这里GetProcAddress取VirtualAlloc的地址
1001F055 8985 4D050000
MOV DWORD PTR SS:[
EBP+54D],
EAX ; 取出的地址入[EBP+54D]处
1001F05B 8D5D 6B
LEA EBX,
DWORD PTR SS:[
EBP+6B]
; 取VirtualFree字符串
1001F05E 53
PUSH EBX ; 字符串地址入栈
1001F05F 57
PUSH EDI ; BASE入栈,准备取VirtualFree的地址了
1001F060 FF95 490F0000
CALL DWORD PTR SS:[
EBP+F49]
; GetProcAddress取VirtualFree的地址
1001F066 8985 51050000
MOV DWORD PTR SS:[
EBP+551],
EAX ; 取到的地址入[EBP+551]处
1001F06C 8D45 77
LEA EAX,
DWORD PTR SS:[
EBP+77]
; 看到上面ebp的值了吧,也就eax=1001f013+77
1001F06F FFE0
JMP EAX ; 这里就是跳去1001f08A的说
1001F071 56
PUSH ESI
1001F072 6972 74 75616C4>
IMUL ESI,
DWORD PTR DS:[
EDX+74],416C6175
1001F079 6C
INS BYTE PTR ES:[
EDI],
DX ; I/O command
1001F07A 6C
INS BYTE PTR ES:[
EDI],
DX ; I/O command
1001F07B 6F
OUTS DX,
DWORD PTR ES:[
EDI]
; I/O command
1001F07C 6300
ARPL WORD PTR DS:[
EAX],
AX
1001F07E 56
PUSH ESI
1001F07F 6972 74 75616C4>
IMUL ESI,
DWORD PTR DS:[
EDX+74],466C6175
1001F086 72 65
JB SHORT cesi.1001F0ED
1001F088 90
NOP
1001F089 90
NOP
1001F08A 8B9D 31050000
MOV EBX,
DWORD PTR SS:[
EBP+531]
; 测试[EBP+531]处有没有数据
1001F090 0BDB
OR EBX,
EBX
1001F092 74 0A
JE SHORT cesi.1001F09E
; 如果还没有数据的话就跳
1001F094 8B03
MOV EAX,
DWORD PTR DS:[
EBX]
1001F096 8785 35050000
XCHG DWORD PTR SS:[
EBP+535],
EAX
1001F09C 8903
MOV DWORD PTR DS:[
EBX],
EAX
1001F09E 8DB5 69050000
LEA ESI,
DWORD PTR SS:[
EBP+569]
; 取text段的开始地址1000(Voffset)
1001F0A4 833E 00
CMP DWORD PTR DS:[
ESI],0
; 比较[EBP+569]这个地址中有没有数据,这个程序里为1000
1001F0A7 0F84 21010000
JE cesi.1001F1CE
; 如果没有数据就跳,下面准备申请空间了
1001F0AD 6A 04
PUSH 4
; /Protect = PAGE_READWRITE
1001F0AF 68 00100000
PUSH 1000
; |AllocationType = MEM_COMMIT
1001F0B4 68 00180000
PUSH 1800
; |Size = 1800 (6144.)
1001F0B9 6A 00
PUSH 0
; |Address = NULL
1001F0BB FF95 4D050000
CALL DWORD PTR SS:[
EBP+54D]
; \VirtualAlloc
1001F0C1 8985 56010000
MOV DWORD PTR SS:[
EBP+156],
EAX ; 上面自动分配后的地址为BC0000把这个地址保存在[EBP+156]
处
1001F0C7 8B46 04
MOV EAX,
DWORD PTR DS:[
ESI+4]
; 取text段的大小入EAX中
1001F0CA 05 0E010000
ADD EAX,10E
; 准备申请一个大小为text段大小+10E的空间(也就是申请一个
大小为A10E的空间)
1001F0CF 6A 04
PUSH 4
; /Protect = PAGE_READWRITE
1001F0D1 68 00100000
PUSH 1000
; |AllocationType = MEM_COMMIT
1001F0D6 50
PUSH EAX ; |Size = A10E (41230.)
1001F0D7 6A 00
PUSH 0
; |Address = NULL(也就是自动分配)
1001F0D9 FF95 4D050000
CALL DWORD PTR SS:[
EBP+54D]
; \VirtualAlloc
1001F0DF 8985 52010000
MOV DWORD PTR SS:[
EBP+152],
EAX ; 申请到的开始地址入[EBP+152]处(BD0000)
1001F0E5 56
PUSH ESI ; /Address = ESI的地址里保存了text段的开始Voffset和Size
1001F0E6 8B1E
MOV EBX,
DWORD PTR DS:[
ESI]
; | 把text段的Voffset入ebx
1001F0E8 039D 22040000
ADD EBX,
DWORD PTR SS:[
EBP+422]
; | 用text段的开始地址加上当前段的CODEBASE
(100000000)
1001F0EE FFB5 56010000
PUSH DWORD PTR SS:[
EBP+156]
; |VAddress1 = 第一次申请的空间开始地址入栈
1001F0F4 FF76 04
PUSH DWORD PTR DS:[
ESI+4]
; |Size1 = text段的Size入栈
1001F0F7 50
PUSH EAX ; |ViAddress2 = 第二次申请的空间地址入栈
1001F0F8 53
PUSH EBX ; |Size2 = EBX入栈(10001000)??
1001F0F9 E8 6E050000
CALL cesi.1001F66C
; \Function
1001F0F9 E8 6E050000
CALL cesi.1001F66C
; 这里进去就是解压代码的了
1001F0FE B3 01
MOV BL,1
1001F100 80FB 00
CMP BL,0
......
1001F189 5E
POP ESI
1001F18A 68 00800000
PUSH 8000
; 这里开始释放刚才申请的空间
1001F18F 6A 00
PUSH 0
1001F191 FFB5 52010000
PUSH DWORD PTR SS:[
EBP+152]
1001F197 FF95 51050000
CALL DWORD PTR SS:[
EBP+551]
; VirtualFree
1001F19D 83C6 08
ADD ESI,8
1001F1A0 833E 00
CMP DWORD PTR DS:[
ESI],0
1001F1A3 ^ 0F85 1EFFFFFF
JNZ cesi.1001F0C7
; 这里回去继续循环
1001F1A9 68 00800000
PUSH 8000
1001F1AE 6A 00
PUSH 0
1001F1B0 FFB5 56010000
PUSH DWORD PTR SS:[
EBP+156]
; 这里释放第一次申请的空间
1001F1B6 FF95 51050000
CALL DWORD PTR SS:[
EBP+551]
; VirtualFree
......
1001F1CE 8B95 22040000
MOV EDX,
DWORD PTR SS:[
EBP+422]
; 当前段的IMAGEBASE
1001F1D4 8B85 2D050000
MOV EAX,
DWORD PTR SS:[
EBP+52D]
; 程序原来的IMAGEBASE
1001F1DA 2BD0
SUB EDX,
EAX ; 相减
1001F1DC 74 79
JE SHORT cesi.1001F257
; 这里判断要不要重定位,如果不需要重定位就跳,
1001F1DE 8BC2
MOV EAX,
EDX ; 这里准备处理重定位
1001F1E0 C1E8 10
SHR EAX,10
1001F1E3 33DB
XOR EBX,
EBX
1001F1E5 8BB5 39050000
MOV ESI,
DWORD PTR SS:[
EBP+539]
; 重定位表段的开始地址1E000
1001F1EB 03B5 22040000
ADD ESI,
DWORD PTR SS:[
EBP+422]
; 转换成RVA
1001F1F1 833E 00
CMP DWORD PTR DS:[
ESI],0
; [ESI]里保存了Size,如果重定位表处理完毕就跳去处理输入
表
1001F1F4 74 61
JE SHORT cesi.1001F257
......
1001F24C 66:830E FF
OR WORD PTR DS:[
ESI],0FFFF
; 这里要处理了,NOP掉就不会处理
1001F250 83C6 02
ADD ESI,2
1001F253 ^ E2 B4 LOOPD SHORT cesi.1001F209
; 这里回去循环处理
1001F255 ^ EB 9A
JMP SHORT cesi.1001F1F1
1001F257 8B95 22040000
MOV EDX,
DWORD PTR SS:[
EBP+422]
1001F25D 8BB5 41050000
MOV ESI,
DWORD PTR SS:[
EBP+541]
; [EBP+541]记录了重定位表的结束位置
......
1001F278 BE 70C30000
MOV ESI,0C370
; 把输入表的VA入esi
1001F27D 8B95 22040000
MOV EDX,
DWORD PTR SS:[
EBP+422]
1001F283 03F2
ADD ESI,
EDX ; 输入表的VA转成RVA
1001F285 8B46 0C
MOV EAX,
DWORD PTR DS:[
ESI+C]
; 判断有没有输入表
1001F288 85C0
TEST EAX,
EAX
1001F28A 0F84 0A010000
JE cesi.1001F39A
; 如果没有找到就OVER了
1001F290 03C2
ADD EAX,
EDX
1001F292 8BD8
MOV EBX,
EAX ; 取到第一个DLL的的名称入ebx
1001F294 50
PUSH EAX ; /pModule = "SlsApi.dll"
1001F295 FF95 4D0F0000
CALL DWORD PTR SS:[
EBP+F4D]
; \GetModuleHandleA
1001F29B 85C0
TEST EAX,
EAX ; 取得BASE为3B0000
1001F29D 75 07
JNZ SHORT cesi.1001F2A6
; 如果已经获取成功就跳去下一步,如果失败就载入这个dll
1001F29F 53
PUSH EBX ; /FileName ="SlsApi.dll"
1001F2A0 FF95 510F0000
CALL DWORD PTR SS:[
EBP+F51]
; \LoadLibraryA
1001F2A6 8985 45050000
MOV DWORD PTR SS:[
EBP+545],
EAX ; 取出的值入[EBP+545]=(3B0000)
......
1001F2F5 53
PUSH EBX ; /ProcNameOrOrdinal = #11
1001F2F6 FFB5 45050000
PUSH DWORD PTR SS:[
EBP+545]
; |hModule = 003B0000 (slsapi)
1001F2FC FF95 490F0000
CALL DWORD PTR SS:[
EBP+F49]
; \GetProcAddress
1001F302 85C0
TEST EAX,
EAX
1001F304 5B
POP EBX
1001F305 75 6F
JNZ SHORT cesi.1001F376
; 获取成功就跳下去
上面跳到这里了:
1001F376 8907
MOV DWORD PTR DS:[
EDI],
EAX ; 这里把上面获取到的API填充进去
1001F378 8385 49050000 0>
ADD DWORD PTR SS:[
EBP+549],4
; 值加4
1001F37F ^ E9 32FFFFFF
JMP cesi.1001F2B6
; 这里循环回去继续取相关API
1001F384 8906
MOV DWORD PTR DS:[
ESI],
EAX
.......
1001F395 E9 EBFEFFFF
JMP cesi.1001F285
1001F39A B8 4BA00000
MOV EAX,0A04B
; 这里把OEP的VA传到EAX中
1001F39F 50
PUSH EAX
1001F3A0 0385 22040000
ADD EAX,
DWORD PTR SS:[
EBP+422]
1001F3A6 59
POP ECX ; 再把程序的OEP的VA传入ECX中
1001F3A7 0BC9
OR ECX,
ECX
1001F3A9 8985 A8030000
MOV DWORD PTR SS:[
EBP+3A8],
EAX ; 程序的OEP地址(RVA)入[ebp+3A8]
1001F3AF 61
POPAD
1001F3B0 75 08
JNZ SHORT cesi.1001F3BA
; 如果得到OEP的VA为空的就主不跳也就OVER了
1001F3B2 B8 01000000
MOV EAX,1
; 如果OEP为空就OVER了
1001F3B7 C2 0C00
RETN 0C
; 感觉有点多余上面都已经给EAX赋值了,这几步有必要吗?
1001F3BA 68 4BA00010
PUSH cesi.1000A04B
; 转去OEP
1001F3BF C3
RETN
分析出来了,怎么修复输入表和重定位表我也就不多说了,准备回家睡觉.
Greetz:
Fly,Jingulong,yock,tDasm,David,ahao,vcasm,UFO(brother),alan(sister),all of my friends
and you!
By loveboom[DFCG][FCG][US]
Email:bmd2chen@tom.com
本代码的着色效果由xTiNt自动完成
下载xTiNt
http://211.90.75.84/web/kanaun/download/xTiNt.rar
附件:packed.rar
[培训]内核驱动高级班,冲击BAT一流互联网大厂工
作,每周日13:00-18:00直播授课