.data:0046B0FF
.data:0046B0FF public start
.data:0046B0FF start proc near
.data:0046B0FF
.data:0046B0FF ; FUNCTION CHUNK AT .data:0046B1C6 SIZE 000000DB BYTES
.data:0046B0FF
.data:0046B0FF pusha
.data:0046B100 push offset dword_46B054
.data:0046B105 mov eax, offset GetModuleHandleA
.data:0046B10A call dword ptr [eax]
.data:0046B10A
.data:0046B10C push offset s_Globalalloc ; "GlobalAlloc"
.data:0046B111 push eax ; 7C80000
.data:0046B112 mov eax, offset GetProcAddress
.data:0046B117 call dword ptr [eax] ; GetProcAddress()
.data:0046B117
.data:0046B119 push 49200h ; <suspicious> ; lpProcName
.data:0046B11E push 40h ; hModule
.data:0046B120 call eax ; GetProcAddress ; GlobalAlloc 返回一个指针
.data:0046B120
.data:0046B122 mov hModule, eax ; 以下是解压的部分!!
.data:0046B128 mov edi, eax ; 这是一个解压的地址
.data:0046B12A mov esi, offset dword_401000 ; 这个是区段地址 .text
.data:0046B12F pusha ; 压缩算法如下:
.data:0046B12F ;
.data:0046B12F ;
.data:0046B12F ;
.data:0046B12F ;
.data:0046B12F ;
.data:0046B130 cld
.data:0046B131 mov dl, 80h
.data:0046B133 xor ebx, ebx
.data:0046B133
.data:0046B135
.data:0046B135 literal: ; CODE XREF: start+3Ej
.data:0046B135 movsb ; 数据移动,将数据移动到一个地方
.data:0046B136 mov bl, 2 ; MOVS BYTE PTR ES:[edi], BYTE PTR DS:[esi]
.data:0046B136
.data:0046B138
.data:0046B138 nexttag: ; CODE XREF: start+63j
.data:0046B138 ; start+A9j
.data:0046B138 call getbit ; 作用?
.data:0046B138
.data:0046B13D jnb short literal ; 数据移动,将数据移动到一个地方
.data:0046B13D
.data:0046B13F xor ecx, ecx
.data:0046B141 call getbit ; 作用?
.data:0046B141
.data:0046B146 jnb short codepair
.data:0046B146
.data:0046B148 xor eax, eax
.data:0046B14A call getbit ; 作用?
.data:0046B14A
.data:0046B14F jnb short shortmatch
.data:0046B14F
.data:0046B151 mov bl, 2
.data:0046B153 inc ecx
.data:0046B154 mov al, 10h
.data:0046B154
.data:0046B156
.data:0046B156 getmorebits: ; CODE XREF: start+5Ej
.data:0046B156 call getbit ; 作用?
.data:0046B156
.data:0046B15B adc al, al
.data:0046B15D jnb short getmorebits
.data:0046B15D
.data:0046B15F jnz short domatch
.data:0046B15F
.data:0046B161 stosb
.data:0046B162 jmp short nexttag
.data:0046B162
.data:0046B164 ; ---------------------------------------------------------------------------
.data:0046B164
.data:0046B164 codepair: ; CODE XREF: start+47j
.data:0046B164 call getgamma_no_ecx
.data:0046B164
.data:0046B169 sub ecx, ebx
.data:0046B16B jnz short normalcodepair
.data:0046B16B
.data:0046B16D call getgamma
.data:0046B16D
.data:0046B172 jmp short domatch_lastpos
.data:0046B172
.data:0046B174 ; ---------------------------------------------------------------------------
.data:0046B174
.data:0046B174 shortmatch: ; CODE XREF: start+50j
.data:0046B174 lodsb
.data:0046B175 shr eax, 1
.data:0046B177 jz short loc_46B1C6
.data:0046B177
.data:0046B179 adc ecx, ecx
.data:0046B17B jmp short domatch_with_2inc
.data:0046B17B
.data:0046B17D ; ---------------------------------------------------------------------------
.data:0046B17D
.data:0046B17D normalcodepair: ; CODE XREF: start+6Cj
.data:0046B17D xchg eax, ecx
.data:0046B17E dec eax
.data:0046B17F shl eax, 8
.data:0046B182 lodsb
.data:0046B183 call getgamma
.data:0046B183
.data:0046B188 cmp eax, 7D00h ; 32000
.data:0046B18D jnb short domatch_with_2inc
.data:0046B18D
.data:0046B18F cmp ah, 5
.data:0046B192 jnb short domatch_with_inc
.data:0046B192
.data:0046B194 cmp eax, 7Fh
.data:0046B197 ja short domatch_new_lastpos
.data:0046B197
.data:0046B199
.data:0046B199 domatch_with_2inc: ; CODE XREF: start+7Cj
.data:0046B199 ; start+8Ej
.data:0046B199 inc ecx
.data:0046B199
.data:0046B19A
.data:0046B19A domatch_with_inc: ; CODE XREF: start+93j
.data:0046B19A inc ecx
.data:0046B19A
.data:0046B19B
.data:0046B19B domatch_new_lastpos: ; CODE XREF: start+98j
.data:0046B19B xchg eax, ebp
.data:0046B19B
.data:0046B19C
.data:0046B19C domatch_lastpos: ; CODE XREF: start+73j
.data:0046B19C mov eax, ebp
.data:0046B19E mov bl, 1
.data:0046B19E
.data:0046B1A0
.data:0046B1A0 domatch: ; CODE XREF: start+60j
.data:0046B1A0 push esi
.data:0046B1A1 mov esi, edi
.data:0046B1A3 sub esi, eax
.data:0046B1A5 rep movsb
.data:0046B1A7 pop esi
.data:0046B1A8 jmp short nexttag ; 这个是压缩算法的结束
.data:0046B1A8
.data:0046B1A8 start endp
.data:0046B1A8
.data:0046B1AA
.data:0046B1AA ; =============== S U B R O U T I N E =======================================
.data:0046B1AA
.data:0046B1AA ; 作用?
.data:0046B1AA
.data:0046B1AA getbit proc near ; CODE XREF: start:nexttagp
.data:0046B1AA ; start+42p start+4Bp
.data:0046B1AA ; start:getmorebitsp
.data:0046B1AA ; getgamma_no_ecx:getgammaloopp
.data:0046B1AA ; getgamma_no_ecx+8p
.data:0046B1AA add dl, dl
.data:0046B1AC jnz short stillbitsleft
.data:0046B1AC
.data:0046B1AE mov dl, [esi]
.data:0046B1B0 inc esi ; 移动到下一个数据中
.data:0046B1B1 adc dl, dl
.data:0046B1B1
.data:0046B1B3
.data:0046B1B3 stillbitsleft: ; CODE XREF: getbit+2j
.data:0046B1B3 retn
.data:0046B1B3
.data:0046B1B3 getbit endp
.data:0046B1B3
.data:0046B1B4
.data:0046B1B4 ; =============== S U B R O U T I N E =======================================
.data:0046B1B4
.data:0046B1B4
.data:0046B1B4 getgamma proc near ; CODE XREF: start+6Ep
.data:0046B1B4 ; start+84p
.data:0046B1B4 xor ecx, ecx
.data:0046B1B4
.data:0046B1B4 getgamma endp
.data:0046B1B4
.data:0046B1B6
.data:0046B1B6 ; =============== S U B R O U T I N E =======================================
.data:0046B1B6
.data:0046B1B6
.data:0046B1B6 getgamma_no_ecx proc near ; CODE XREF: start:codepairp
.data:0046B1B6 inc ecx
.data:0046B1B6
.data:0046B1B7
.data:0046B1B7 getgammaloop: ; CODE XREF: getgamma_no_ecx+Dj
.data:0046B1B7 call getbit ; 作用?
.data:0046B1B7
.data:0046B1BC adc ecx, ecx
.data:0046B1BE call getbit ; 作用?
.data:0046B1BE
.data:0046B1C3 jb short getgammaloop
.data:0046B1C3
.data:0046B1C5 retn
.data:0046B1C5
.data:0046B1C5 getgamma_no_ecx endp
.data:0046B1C5
.data:0046B1C6 ; ---------------------------------------------------------------------------
.data:0046B1C6 ; START OF FUNCTION CHUNK FOR start
.data:0046B1C6
.data:0046B1C6 loc_46B1C6: ; CODE XREF: start+78j
.data:0046B1C6 popa
.data:0046B1C7 mov ecx, 491FCh ; <suspicious>
.data:0046B1C7 ; <suspicious>
.data:0046B1CC
.data:0046B1CC loc_46B1CC: ; CODE XREF: start+D6j
.data:0046B1CC mov ebx, [eax+ecx]
.data:0046B1CF mov ds:dword_401000[ecx], ebx
.data:0046B1D5 loop loc_46B1CC
.data:0046B1D5
.data:0046B1D7 nop
.data:0046B1D8 nop
.data:0046B1D9 mov edx, 400000h ; <suspicious>
.data:0046B1DE mov esi, 60000h ; <suspicious>
.data:0046B1E3 add esi, edx ; esi = 460000h .idata 数据
.data:0046B1E3
.data:0046B1E5
.data:0046B1E5 loc_46B1E5: ; CODE XREF: start+173j
.data:0046B1E5 mov eax, [esi+0Ch]
.data:0046B1E8 test eax, eax
.data:0046B1EA jz loc_46B277 ; 不跳到46B277
.data:0046B1EA
.data:0046B1F0 add eax, edx ; 460f3Ah
.data:0046B1F2 mov ebx, eax
.data:0046B1F4 push eax
.data:0046B1F5 mov eax, offset GetModuleHandleA
.data:0046B1FA call dword ptr [eax] ; ?????????
.data:0046B1FA
.data:0046B1FC test eax, eax
.data:0046B1FE jnz short loc_46B208
.data:0046B1FE
.data:0046B200 push ebx
.data:0046B201 mov eax, offset LoadLibraryA
.data:0046B206 call dword ptr [eax]
.data:0046B206
.data:0046B208
.data:0046B208 loc_46B208: ; CODE XREF: start+FFj
.data:0046B208 mov dword_46B0CE, eax
.data:0046B20E mov dword_46B0D2, 0 ; eax 0
.data:0046B20E
.data:0046B218 ; <suspicious>
.data:0046B218 loc_46B218: ; <suspicious> ; CODE XREF: start+169j
.data:0046B218 mov edx, 400000h ; <suspicious> ; 跟踪这一段
.data:0046B21D mov eax, [esi]
.data:0046B21F test eax, eax
.data:0046B221 jnz short loc_46B226
.data:0046B221
.data:0046B223 mov eax, [esi+10h]
.data:0046B223
.data:0046B226
.data:0046B226 loc_46B226: ; CODE XREF: start+122j
.data:0046B226 add eax, edx
.data:0046B228 add eax, dword_46B0D2
.data:0046B22E mov ebx, [eax]
.data:0046B230 mov edi, [esi+10h]
.data:0046B233 add edi, edx
.data:0046B235 add edi, dword_46B0D2
.data:0046B23B test ebx, ebx
.data:0046B23D jz short loc_46B26A
.data:0046B23D
.data:0046B23F test ebx, 80000000h
.data:0046B245 jnz short loc_46B24B
.data:0046B245
.data:0046B247 add ebx, edx
.data:0046B249 inc ebx
.data:0046B24A inc ebx
.data:0046B24A
.data:0046B24B
.data:0046B24B loc_46B24B: ; CODE XREF: start+146j
.data:0046B24B and ebx, 0FFFFFFFh
.data:0046B251 push ebx
.data:0046B252 push dword_46B0CE
.data:0046B258 mov eax, offset GetProcAddress
.data:0046B25D call dword ptr [eax]
.data:0046B25D
.data:0046B25F mov [edi], eax ; 76b2a8bfh
.data:0046B261 add dword_46B0D2, 4
.data:0046B268 jmp short loc_46B218 ; 跟踪这一段
.data:0046B268
.data:0046B26A ; ---------------------------------------------------------------------------
.data:0046B26A
.data:0046B26A loc_46B26A: ; CODE XREF: start+13Ej
.data:0046B26A add esi, 14h
.data:0046B26D mov edx, 400000h ; <suspicious>
.data:0046B272 jmp loc_46B1E5
.data:0046B272
.data:0046B277 ; ---------------------------------------------------------------------------
.data:0046B277
.data:0046B277 loc_46B277: ; CODE XREF: start+EBj
.data:0046B277 push offset dword_46B054
.data:0046B27C mov eax, offset GetModuleHandleA
.data:0046B281 call dword ptr [eax]
.data:0046B281
.data:0046B283 push offset s_Globalfree ; "GlobalFree"
.data:0046B288 push eax ; lpProcName
.data:0046B289 mov eax, offset GetProcAddress
.data:0046B28E call dword ptr [eax]
.data:0046B28E
.data:0046B290 mov edx, hModule
.data:0046B296 push edx ; hModule
.data:0046B297 call eax ; GetProcAddress
.data:0046B297
.data:0046B299 popa
.data:0046B29A mov edx, offset dword_4271B0 ; 这个跳转到OEP
.data:0046B29F jmp edx
.data:0046B29F
.data:0046B29F ; END OF FUNCTION CHUNK FOR start
.data:0046B29F ; ---------------------------------------------------------------------------
.data:0046B2A1 align 2
.data:0046B2A2 retn
.data:0046B2A2
.data:0046B2A2 ; ---------------------------------------------------------------------------
.data:0046B2A3 db 44h
.data:0046B2A4 align 200h
.data:0046B2A4 _data ends
.data:0046B2A4
.data:0046B2A4
.data:0046B2A4 end start
解压核心算法如下 C版:
while (!done)
{
if (!aP_getbit_safe(&ud, &bit)) return APLIB_ERROR;
if (bit)
{
if (!aP_getbit_safe(&ud, &bit)) return APLIB_ERROR;
if (bit)
{
if (!aP_getbit_safe(&ud, &bit)) return APLIB_ERROR;
if (bit)
{
offs = 0;
for (i = 4; i; i--)
{
if (!aP_getbit_safe(&ud, &bit)) return APLIB_ERROR;
offs = (offs << 1) + bit;
}
if (offs)
{
if (offs > (dstlen - ud.dstlen)) return APLIB_ERROR;
if (!ud.dstlen--) return APLIB_ERROR;
*ud.destination = *(ud.destination - offs);
ud.destination++;
} else {
if (!ud.dstlen--) return APLIB_ERROR;
*ud.destination++ = 0x00;
}
LWM = 0;
} else {
if (!ud.srclen--) return APLIB_ERROR;
offs = *ud.source++;
len = 2 + (offs & 0x0001);
offs >>= 1;
if (offs)
{
if (offs > (dstlen - ud.dstlen)) return APLIB_ERROR;
if (len > ud.dstlen) return APLIB_ERROR;
ud.dstlen -= len;
for (; len; len--)
{
*ud.destination = *(ud.destination - offs);
ud.destination++;
}
} else done = 1;
R0 = offs;
LWM = 1;
}
} else {
if (!aP_getgamma_safe(&ud, &offs)) return APLIB_ERROR;
if ((LWM == 0) && (offs == 2))
{
offs = R0;
if (!aP_getgamma_safe(&ud, &len)) return APLIB_ERROR;
if (offs > (dstlen - ud.dstlen)) return APLIB_ERROR;
if (len > ud.dstlen) return APLIB_ERROR;
ud.dstlen -= len;
for (; len; len--)
{
*ud.destination = *(ud.destination - offs);
ud.destination++;
}
} else {
if (LWM == 0) offs -= 3; else offs -= 2;
if (!ud.srclen--) return APLIB_ERROR;
offs <<= 8;
offs += *ud.source++;
if (!aP_getgamma_safe(&ud, &len)) return APLIB_ERROR;
if (offs >= 32000) len++;
if (offs >= 1280) len++;
if (offs < 128) len += 2;
if (offs > (dstlen - ud.dstlen)) return APLIB_ERROR;
if (len > ud.dstlen) return APLIB_ERROR;
ud.dstlen -= len;
for (; len; len--)
{
*ud.destination = *(ud.destination - offs);
ud.destination++;
}
R0 = offs;
}
LWM = 1;
}
} else {
if (!ud.srclen-- || !ud.dstlen--) return APLIB_ERROR;
*ud.destination++ = *ud.source++;
LWM = 0;
}
}
本壳主要是对于数据的一个压缩的过程,数据进行压缩,然后存储,同样运行的时候,只要从头按照解压算法进行解压释放出来,处理好重定位就OK了
- 标 题:压缩壳之AHpack 分析
- 作 者:popeylj
- 时 间:2009-03-05 16:03:20
- 链 接:http://bbs.pediy.com/showthread.php?t=83260