首页
社区
课程
招聘
AsProtect 2.x stolen code 完全档案(1)
发表于: 2007-4-9 14:40 4866

AsProtect 2.x stolen code 完全档案(1)

2007-4-9 14:40
4866
终于有天被asprotect给 , 于是操起ollydbg 和 IDA 来个大卸八块.

与此之前很多大虾已经给出了手脱的方法.如.

http://bbs.pediy.com/showthread.php?threadid=24007

本文用的也是上面这个链接中的目标程序.

这里主要对壳的代码进行详细的分析. 本人分析壳喜欢在分析到脑中能浮现出C代码为止

call XXXX的修复 是这个壳的难点. 正如很多大虾指出,这个 call有3层,我们具体看看每层究竟干了什么.

                push    ebx
seg000:00DA0004                 pushf
seg000:00DA0005                 mov     ebx, 4283E2h
seg000:00DA000A                 jmp     short loc_DA000D
seg000:00DA000A ; seg000:00DA000C                 db  9Ah ; ?
seg000:00DA000D ;
seg000:00DA000D
seg000:00DA000D loc_DA000D:                             ; CODE XREF: seg000:00DA000Aj
seg000:00DA000D                 add     ebx, [esp+18h]
seg000:00DA0011                 jmp     short loc_DA0015 ; allocate 20h bytes to save registers
seg000:00DA0011 ;
seg000:00DA0013                 db 0CDh ; ?
seg000:00DA0014                 db  20h
seg000:00DA0015 ;
seg000:00DA0015
seg000:00DA0015 loc_DA0015:                             ; CODE XREF: seg000:00DA0011j
seg000:00DA0015                 sub     esp, 20h        ; old esp = fp
seg000:00DA0018                 jmp     short loc_DA001B ; junk
seg000:00DA0018 ;
seg000:00DA001A                 db 0C7h ; ?
seg000:00DA001B ; seg000:00DA001B
seg000:00DA001B loc_DA001B:                             ; CODE XREF: seg000:00DA0018j
seg000:00DA001B                 xor     ebx, [esp+8]    ; junk
seg000:00DA001F                 xor     ebx, [esp+28h]  ; junk
seg000:00DA0023                 mov     ebx, 42BD2Ah    ; junk
seg000:00DA0028                 db      65h
seg000:00DA0028                 jmp     short loc_DA002C
seg000:00DA0028 ; seg000:00DA002B                 db 0F2h ; ò
seg000:00DA002C ; seg000:00DA002C
seg000:00DA002C loc_DA002C:                             ; CODE XREF: seg000:00DA0028j
seg000:00DA002C                 and     ebx, 0FFFFFFA8h
seg000:00DA002F                 jmp     short loc_DA0032
seg000:00DA002F ;
seg000:00DA0031                 db  9Ah ; ?
seg000:00DA0032 ; seg000:00DA0032
seg000:00DA0032 loc_DA0032:                             ; CODE XREF: seg000:00DA002Fj
seg000:00DA0032                 rep jmp short loc_DA0037
seg000:00DA0032 ; seg000:00DA0035                 db 0CDh ; ?
seg000:00DA0036                 db  20h
seg000:00DA0037 ;
seg000:00DA0037
seg000:00DA0037 loc_DA0037:                             ; CODE XREF: seg000:loc_DA0032j
seg000:00DA0037                 lea     ebx, [esi+ebx*2+0Ch]
seg000:00DA003B                 lea     ebx, [esp+ecx+7Ch] ; ebx = esp + ecx + 7c
seg000:00DA003F                 jmp     short loc_DA0042 ; ebx = esp + 7c
seg000:00DA003F ;

seg000:00DA0042 ; seg000:00DA0042
seg000:00DA0042 loc_DA0042:                             ; CODE XREF: seg000:00DA003Fj
seg000:00DA0042                 sub     ebx, ecx        ; ebx = esp + 7c
seg000:00DA0044                 repne jmp short loc_DA0048
seg000:00DA0044 ;
seg000:00DA0047                 db 0E8h ; è
seg000:00DA0048 ; seg000:00DA0048
seg000:00DA0048 loc_DA0048:                             ; CODE XREF: seg000:00DA0044j
seg000:00DA0048                 jmp     short loc_DA004B ; ebx = fp
seg000:00DA0048 ; seg000:00DA004A                 db 0E8h ; è
seg000:00DA004B ; seg000:00DA004B
seg000:00DA004B loc_DA004B:                             ; CODE XREF: seg000:loc_DA0048j
seg000:00DA004B                 lea     ebx, [ebx-7Ch]  ; ebx = fp
seg000:00DA004E                 mov     [ebx+4], ecx    ; ecx ->fp + 4
seg000:00DA0051                 xor     ecx, [esp+8]
seg000:00DA0055                 xor     ecx, [esp+28h]
seg000:00DA0059                 push    edx
seg000:00DA005A                 pop     dword ptr [ebx+8] ; edx -> fp + 8
seg000:00DA005D                 jmp     short loc_DA0061
seg000:00DA005D ; seg000:00DA005F                 db 0CDh ; ?
seg000:00DA0060                 db  20h
seg000:00DA0061 ; seg000:00DA0061
seg000:00DA0061 loc_DA0061:                             ; CODE XREF: seg000:00DA005Dj
seg000:00DA0061                 xor     edx, ecx
seg000:00DA0063                 mov     [ebx+1Ch], edi  ; save edi
seg000:00DA0066                 mov     edi, 493522h
seg000:00DA006B                 rcl     edi, 0Dh
seg000:00DA006E                 push    eax
seg000:00DA006F                 rep jmp short loc_DA0074 ; eax -> fp
seg000:00DA006F ;seg000:00DA0072                 db 0CDh ; ?
seg000:00DA0073                 db  20h
seg000:00DA0074 ;seg000:00DA0074
seg000:00DA0074 loc_DA0074:                             ; CODE XREF: seg000:00DA006Fj
seg000:00DA0074                 pop     dword ptr [ebx+0] ; eax -> fp
seg000:00DA0078                 mov     eax, 41A402h
seg000:00DA007D                 mov     eax, 475EFAh
seg000:00DA0082                 jmp     short loc_DA0086 ; save ebp
seg000:00DA0082 ; seg000:00DA0084                 db 0CDh ; ?
seg000:00DA0085                 db  20h
seg000:00DA0086 ;
seg000:00DA0086
seg000:00DA0086 loc_DA0086:                             ; CODE XREF: seg000:00DA0082j
seg000:00DA0086                 mov     [ebx+14h], ebp  ; save ebp
seg000:00DA0089                 xor     ebp, [esp+28h]
seg000:00DA008D                 mov     ebp, 485AE2h
seg000:00DA0092                 push    esi
seg000:00DA0093                 pop     dword ptr [ebx+18h] ; esi -> fp + 18
seg000:00DA0096                 db      64h
seg000:00DA0096                 jmp     short loc_DA009B
seg000:00DA0096 ; seg000:00DA0099                 db 0CDh ; ?
seg000:00DA009A                 db  20h
seg000:00DA009B ;
seg000:00DA009B
seg000:00DA009B loc_DA009B:                             ; CODE XREF: seg000:00DA0096j
seg000:00DA009B                 lea     esi, [ebp+esi+447058h]
seg000:00DA00A2                 db      65h
seg000:00DA00A2                 jmp     short loc_DA00A6
seg000:00DA00A2 ;seg000:00DA00A5                 db  69h ; i
seg000:00DA00A6 ;
seg000:00DA00A6
seg000:00DA00A6 loc_DA00A6:                             ; CODE XREF: seg000:00DA00A2j
seg000:00DA00A6                 adc     ecx, 0FFFFFFD0h
seg000:00DA00A9                 or      ecx, ebx
seg000:00DA00AB                 jmp     short loc_DA00AE
seg000:00DA00AB ; seg000:00DA00AD                 db 0F3h ; ó
seg000:00DA00AE ;
seg000:00DA00AE
seg000:00DA00AE loc_DA00AE:                             ; CODE XREF: seg000:00DA00ABj
seg000:00DA00AE                 lea     ecx, [ebx+ecx+4Eh]
seg000:00DA00B2                 lea     ecx, [esp+74h]  ; ecx=esp+74
seg000:00DA00B6                 rep jmp short loc_DA00BB ; ecx=esp+ebp
seg000:00DA00B6 ;
seg000:00DA00B9                 db 0CDh ; ?
seg000:00DA00BA                 db  20h
seg000:00DA00BB ;
seg000:00DA00BB
seg000:00DA00BB loc_DA00BB:                             ; CODE XREF: seg000:00DA00B6j
seg000:00DA00BB                 lea     ecx, [ecx+ebp-74h] ; ecx=esp+ebp
seg000:00DA00BF                 jmp     short loc_DA00C2 ; ecx=fp
seg000:00DA00BF ;
seg000:00DA00C1                 db 0C7h ; ?
seg000:00DA00C2 ;
seg000:00DA00C2
seg000:00DA00C2 loc_DA00C2:                             ; CODE XREF: seg000:00DA00BFj
seg000:00DA00C2                 sub     ecx, ebp        ; ecx=fp
seg000:00DA00C4                 rep jmp short loc_DA00C9 ; ecx = fp + ebx + 2c;
seg000:00DA00C4 ;
seg000:00DA00C7                 db 0CDh ; ?
seg000:00DA00C8                 db  20h
seg000:00DA00C9 ;
seg000:00DA00C9
seg000:00DA00C9 loc_DA00C9:                             ; CODE XREF: seg000:00DA00C4j
seg000:00DA00C9                 lea     ecx, [ecx+ebx+2Ch] ; ecx = fp + ebx + 2c;
seg000:00DA00CD                 sub     ecx, ebx        ; ecx = ecx + 2c = fp +2c
seg000:00DA00CF                 push    ecx             ; save ecx
seg000:00DA00D0                 mov     ecx, 45ACD2h
seg000:00DA00D5                 sub     ecx, 65h ; 'e'
seg000:00DA00D8                 push    ebx             ; save ebx
seg000:00DA00D9                 and     ecx, ecx
seg000:00DA00DB                 jmp     short loc_DA00DF
seg000:00DA00DB ;
seg000:00DA00DD                 db 0CDh ; ?
seg000:00DA00DE                 db  20h
seg000:00DA00DF ;
seg000:00DA00DF
seg000:00DA00DF loc_DA00DF:                             ; CODE XREF: seg000:00DA00DBj
seg000:00DA00DF                 xor     ecx, 742A204Fh
seg000:00DA00E5                 lea     ecx, [ebx+37h]  ; ecx = fp + 37
seg000:00DA00E9                 lea     ecx, [ecx-37h]  ; ecx = fp  
seg000:00DA00ED                 add     ecx, 20h ; ' '  ; ecx = fp + 20
seg000:00DA00F0                 db      3Eh
seg000:00DA00F0                 jmp     short loc_DA00F5
seg000:00DA00F0 ;
seg000:00DA00F3                 db 0CDh ; ?
seg000:00DA00F4                 db  20h
seg000:00DA00F5 ;
seg000:00DA00F5
seg000:00DA00F5 loc_DA00F5:                             ; CODE XREF: seg000:00DA00F0j
seg000:00DA00F5                 mov     ecx, [ecx]
seg000:00DA00F7                 push    ecx
seg000:00DA00F8                 db      26h
seg000:00DA00F8                 jmp     short loc_DA00FD
seg000:00DA00F8 ;
seg000:00DA00FB                 db 0CDh ; ?
seg000:00DA00FC                 db  20h
seg000:00DA00FD ;
seg000:00DA00FD
seg000:00DA00FD loc_DA00FD:                             ; CODE XREF: seg000:00DA00F8j
seg000:00DA00FD                 lea     ecx, [ebp+esi+2]
seg000:00DA0101                 lea     ecx, [ecx-2]
seg000:00DA0104                 rep jmp short loc_DA0109
seg000:00DA0104 ;
seg000:00DA0107                 db 0CDh ; ?
seg000:00DA0108                 db  20h
seg000:00DA0109 ;
seg000:00DA0109
seg000:00DA0109 loc_DA0109:                             ; CODE XREF: seg000:00DA0104j
seg000:00DA0109                 add     ecx, ecx
seg000:00DA010B                 xor     ecx, 647084D2h
seg000:00DA0111                 jmp     short loc_DA0115
seg000:00DA0111 ;
seg000:00DA0113                 db 0CDh ; ?
seg000:00DA0114                 db  20h
seg000:00DA0115 ;
seg000:00DA0115
seg000:00DA0115 loc_DA0115:                             ; CODE XREF: seg000:00DA0111j
seg000:00DA0115                 sub     ecx, 66510D97h
seg000:00DA011B                 jmp     short loc_DA011F
seg000:00DA011B ;
seg000:00DA011D                 db 0CDh ; ?
seg000:00DA011E                 db  20h
seg000:00DA011F ;
seg000:00DA011F
seg000:00DA011F loc_DA011F:                             ; CODE XREF: seg000:00DA011Bj
seg000:00DA011F                 lea     ecx, [ebx+ebp+3Eh]
seg000:00DA0123                 sub     ecx, ebp
seg000:00DA0125                 sub     ecx, 3Eh ; '>'
seg000:00DA0128                 lea     ecx, [ecx+28h]  ; ecx = fp + 28
seg000:00DA012B                 push    dword ptr [ecx]
seg000:00DA012D                 mov     ecx, 403F46h
seg000:00DA0132                 repne jmp short loc_DA0136
seg000:00DA0132 ;
seg000:00DA0135                 db 0F3h ; ó
seg000:00DA0136 ;
seg000:00DA0136
seg000:00DA0136 loc_DA0136:                             ; CODE XREF: seg000:00DA0132j
seg000:00DA0136                 mov     ecx, 49B80Ah
seg000:00DA013B                 pop     ecx
seg000:00DA013C                 lea     ecx, [ecx-5]
seg000:00DA0140                 add     ecx, 5D4h
seg000:00DA0146                 push    ecx
seg000:00DA0147                 sbb     ecx, ebx
seg000:00DA0149                 mov     ecx, 41ECEAh
seg000:00DA014E                 xor     ecx, [esp+8]
seg000:00DA0152                 push    0B704B8h
seg000:00DA0157                 and     ecx, 53711992h
seg000:00DA015D                 pop     ecx
seg000:00DA015E                 push    ecx
seg000:00DA015F                 rcl     ecx, 7Bh
seg000:00DA0162                 sbb     ecx, 57h ; 'W'
seg000:00DA0165                 xor     ebx, ebx
seg000:00DA0167                 sbb     ebx, ebx
seg000:00DA0169                 db      36h
seg000:00DA0169                 jmp     short loc_DA016D
seg000:00DA0169 ;
seg000:00DA016C                 db  0Fh
seg000:00DA016D ;
seg000:00DA016D
seg000:00DA016D loc_DA016D:                             ; CODE XREF: seg000:00DA0169j
seg000:00DA016D                 lea     ebx, [edi+0B64BC0h]
seg000:00DA0174                 sub     ebx, edi
seg000:00DA0176                 call    ebx     (call B64BC0)

注段代码的主要功能是将寄存器入栈. (我顶你个肺,pushad,不就行了, 还费这个劲,里面不少填充的junk code,且好像是随机的).

在 00DA0176 进入 call ebx 之前,堆栈如下

0012FF54  00B704B8  const
0012FF58  00B10C84  call + <process id>
0012FF5C  00000282  flag word
0012FF60  0012FF68  esp?
0012FF64  0012FF94  指针, 存放调用DA0000 时传入的参数.
0012FF68 0  0055BA88  eax
0012FF6C 4  00A3FD78  ecx
0012FF70 8  00B102D0  edx
0012FF74 0c 00B10000        
0012FF78 10 00B58D88
0012FF7C 14 0012FFA4  ebp
0012FF80 18 005B58AA  esi
0012FF84 1c 0012FFA8  edi
0012FF88 20 00000282
0012FF8C 24 00B703EC  ebx
0012FF90 28 00B106B5  

请注意,0012FF58处的值, call 0DA0000 是在 B106B0 发生的, 这里的值是  B106b0+5d4.(参看代码DA013C-DA0146).

12FF54 的值在 00DA0152                 push    0B704B8h 压入

上篇说到通过call ebx 进入 B64BC0, 这篇主要分析这个call.

sub_B64BC0      proc near               ; DATA XREF: seg001:loc_DA00164r
seg000:00B64BC0
seg000:00B64BC0 var_p           = dword ptr -8
seg000:00B64BC0 var_4           = dword ptr -4
seg000:00B64BC0 arg_0           = dword ptr  8
seg000:00B64BC0 arg_4           = dword ptr  0Ch
seg000:00B64BC0 arg_8           = dword ptr  10h
seg000:00B64BC0 arg_C           = dword ptr  14h
seg000:00B64BC0 arg_10          = dword ptr  18h
seg000:00B64BC0
seg000:00B64BC0                 push    ebp
seg000:00B64BC1                 mov     ebp, esp
seg000:00B64BC3                 add     esp, 0FFFFFFF8h
seg000:00B64BC6                 push    ebx
seg000:00B64BC7                 push    esi
seg000:00B64BC8                 push    edi
seg000:00B64BC9                 mov     ebx, [ebp+arg_0] ; ebx = pushed constan 0b704b8
seg000:00B64BCC                 jmp     short loc_B64BCF
seg000:00B64BCC ;
seg000:00B64BCE                 db  9Ah ; ?
seg000:00B64BCF ;
seg000:00B64BCF
seg000:00B64BCF loc_B64BCF:                             ; CODE XREF: sub_B64BC0+Cj
seg000:00B64BCF                 mov     eax, [ebp+arg_10]
seg000:00B64BD2                 sub     eax, 8
seg000:00B64BD5                 mov     eax, [eax]      ; saved ebx in stack
seg000:00B64BD7                 push    eax
seg000:00B64BD8                 mov     cl, [ebx+8Eh]
seg000:00B64BDE                 mov     edx, [ebp+arg_C] ; edx = esp?
seg000:00B64BE1                 mov     eax, ebx
seg000:00B64BE3                 call    set_array_val   ; ebx -> fp + 0c
seg000:00B64BE8                 mov     eax, [ebp+arg_10]
seg000:00B64BEB                 push    eax
seg000:00B64BEC                 mov     cl, 4
seg000:00B64BEE                 mov     edx, [ebp+arg_C]
seg000:00B64BF1                 mov     eax, ebx
seg000:00B64BF3                 call    set_array_val   ; old esp => fp + 10
seg000:00B64BF8                 jmp     short loc_B64BFB ; esi = [ebx + 30]
seg000:00B64BF8 ;
seg000:00B64BFA                 db  69h ; i
seg000:00B64BFB ;
seg000:00B64BFB
seg000:00B64BFB loc_B64BFB:                             ; CODE XREF: sub_B64BC0+38j
seg000:00B64BFB                 mov     esi, [ebx+30h]  ; esi = [ebx + 30]
seg000:00B64BFE                 mov     edi, [ebx+14h]  ; edi = [ebx + 14]
seg000:00B64C01                 mov     eax, ds:g_iat?
seg000:00B64C06                 mov     eax, [eax+34h]
seg000:00B64C09                 call    eax             ; GetCurrentProcessId
seg000:00B64C0B                 sub     [ebp+0Ch], eax  ; restore the call address

参看(1) 00DA0136-00DA0140, 存放的是call DA0000发生的地址 + 当前 process id, 这里恢复

seg000:00B64C0E                 mov     eax, [ebp+0Ch]
seg000:00B64C11                 sub     eax, [ebx+18h]  ; ebx + 18 holds the OEP address
seg000:00B64C14                 sub     eax, [ebx+68h]
seg000:00B64C17                 mov     [ebp+var_4], eax ; var_4 = call address relative to OEP - [ebx + 68]

注意这里的var_4 是根据 DA00000 调用发生的地址 - OEP 再 减去一个 数算出来的

seg000:00B64C1A                 lea     eax, [ebx+24h]
seg000:00B64C1D                 mov     [ebp+var_p], eax ; ebx + 24 -> var_p
seg000:00B64C20                 test    edi, edi        ; [ebx + 14 ] == 0
seg000:00B64C22                 jbe     short loc_B64C5C
seg000:00B64C24                 jmp     short loc_B64C27
seg000:00B64C24 ;
seg000:00B64C26                 db 0C7h ; ?
seg000:00B64C27 ;
seg000:00B64C27
seg000:00B64C27 loc_B64C27:                             ; CODE XREF: sub_B64BC0+64j
seg000:00B64C27                                         ; sub_B64BC0+9Aj
seg000:00B64C27                 mov     eax, [ebp+var_p]
seg000:00B64C2A                 movzx   eax, byte ptr [eax]
seg000:00B64C2D                 mov     edx, [ebx+eax*4+40h]
seg000:00B64C31                 mov     eax, esi        ; eax = esi = [ ebx + 30]
seg000:00B64C33                 call    edx             ; return [eax + 28h]

这个call edx 进去是一堆垃圾指令, 作用就是 返回 [eax+28h],再顶你个肺
seg000:00B64C35                 cmp     eax, [ebp+var_4]
seg000:00B64C38                 jnz     short loc_B64C54
seg000:00B64C3A                 mov     eax, [ebp+10h]
seg000:00B64C3D                 push    eax
seg000:00B64C3E                 mov     eax, [ebp+14h]
seg000:00B64C41                 push    eax
seg000:00B64C42                 call    sub_B648BC
seg000:00B64C47                 push    eax             ; SEH header
seg000:00B64C48                 mov     ecx, esi
seg000:00B64C4A                 mov     edx, [ebp+18h]
seg000:00B64C4D                 mov     eax, ebx
seg000:00B64C4F                 call    sub_B64668
seg000:00B64C54
seg000:00B64C54 loc_B64C54:                             ; CODE XREF: sub_B64BC0+78j
seg000:00B64C54                 dec     edi
seg000:00B64C55                 add     esi, [ebx+6Ch]
seg000:00B64C58                 test    edi, edi
seg000:00B64C5A                 ja      short loc_B64C27

对于每个call DA00000, 都存放了一个表,这个循环其实就是根据call发生的地址来搜寻这张表.
seg000:00B64C5C
seg000:00B64C5C loc_B64C5C:                             ; CODE XREF: sub_B64BC0+62j
seg000:00B64C5C                 push    0B64C78h
seg000:00B64C61                 call    sub_B551E4
seg000:00B64C66                 pop     edi
seg000:00B64C67                 pop     esi
seg000:00B64C68                 pop     ebx
seg000:00B64C69                 pop     ecx
seg000:00B64C6A                 pop     ecx
seg000:00B64C6B                 pop     ebp
seg000:00B64C6C                 retn    14h
seg000:00B64C6C sub_B64BC0      endp ; sp = -10h

写到这里, 想问一下,他明白了,你明白了没有? 如果没有,不要紧, 看下下面的总结:
对于每个变形的call DA0000. 请注意2样东西,这两样东西决定了这个call的具体行为.

1)call DA0000发生的地址,
2)压入的参数 (这个参数目前好像还没用到),在后续的分析中应该会用到.

在内存中存放了2张表, 第一张表是存放每个call DA00000的 具体属性,另外还有一张全局的表, 存放着一些函数指针, 偏移常数.

第一层
在进入call DA00000后, 将寄存器压栈,
第二层 然后根据call DA0000的地址,查找第一张表,得到一个当前call DA0000的表项.
(参看指令B64C17-B64C5A),然后将这个表项作为参数调用 B64668.

进入B646688后干什么呢, 坐好了,演出开始了.
seg000:00B64668                 push    ebp
seg000:00B64669                 mov     ebp, esp
seg000:00B6466B                 add     esp, 0FFFFFFF4h
seg000:00B6466E                 push    ebx
seg000:00B6466F                 push    esi
seg000:00B64670                 push    edi
seg000:00B64671                 mov     esi, ecx
seg000:00B64673                 mov     [ebp+var_parg], edx
seg000:00B64676                 mov     [ebp+var_g_table], eax
seg000:00B64679                 mov     eax, [ebp+var_g_table] ; faint, junk code or stupid code?
seg000:00B6467C                 lea     ebx, [eax+24h]  ; ebx = eax+24
seg000:00B6467F                 xor     eax, eax
seg000:00B64681                 mov     al, [ebx+2]     ; al = var_g_table + 26h
seg000:00B64684                 mov     edx, [ebp+var_g_table]
seg000:00B64687                 mov     edi, [edx+eax*4+40h]
seg000:00B6468B                 mov     eax, esi
seg000:00B6468D                 call    edi
seg000:00B6468F                 mov     edi, eax        ; save result in edi
seg000:00B64691                 xor     eax, eax
seg000:00B64693                 mov     al, [ebx+3]
seg000:00B64696                 mov     edx, [ebp+var_g_table]
seg000:00B64699                 mov     edx, [edx+eax*4+40h]
seg000:00B6469D                 mov     eax, esi
seg000:00B6469F                 call    edx
seg000:00B646A1                 mov     [ebp+var_itemoff17], eax
seg000:00B646A4                 xor     eax, eax
seg000:00B646A6                 mov     al, [ebx+1]
seg000:00B646A9                 mov     edx, [ebp+var_g_table]
seg000:00B646AC                 mov     edx, [edx+eax*4+40h] ; edx = var_g_table + 40 + (var_g_table + 26 ) *4
seg000:00B646B0                 mov     eax, esi
seg000:00B646B2                 call    edx
seg000:00B646B4                 sub     al, 2

这里, 针对不同的表项里的数据,会走向不同的分支.

seg000:00B646B6                 jb      short loc_B646C3
seg000:00B646B8                 jz      short loc_B646ED
seg000:00B646BA                 dec     al
seg000:00B646BC                 jz      short loc_B64731
seg000:00B646BE                 jmp     loc_B64785
seg000:00B646C3 ;
seg000:00B646C3
seg000:00B646C3 loc_B646C3:                             ; CODE XREF: sub_B64668+4Ej
seg000:00B646C3                 mov     eax, [ebp+var_g_table]
seg000:00B646C6                 mov     edx, [eax+68h]  ; edx = g_table + 68
seg000:00B646C9                 mov     eax, edx
seg000:00B646CB                 add     eax, edi        ; eax = [g_table + 68] + [item + 1d], assume it's off
seg000:00B646CD                 cmp     eax, 0FFFFFFFFh
seg000:00B646D0                 jnz     short loc_B646E2
seg000:00B646D2                 mov     eax, edx
seg000:00B646D4                 add     eax, [ebp+var_itemoff17]
seg000:00B646D7                 mov     edx, [ebp+var_g_table]
seg000:00B646DA                 add     eax, [edx+10h]
seg000:00B646DD                 jmp     loc_B6478A
seg000:00B646E2 ;
seg000:00B646E2
seg000:00B646E2 loc_B646E2:                             ; CODE XREF: sub_B64668+68j
seg000:00B646E2                 mov     edx, [ebp+var_g_table]
seg000:00B646E5                 add     eax, [edx+18h]
seg000:00B646E8                 jmp     loc_B6478A
seg000:00B646ED ;
seg000:00B646ED
seg000:00B646ED loc_B646ED:                             ; CODE XREF: sub_B64668+50j
seg000:00B646ED                 xor     eax, eax
seg000:00B646EF                 mov     al, [ebx+4]
seg000:00B646F2                 mov     edx, [ebp+var_g_table]
seg000:00B646F5                 mov     edx, [edx+eax*4+40h]
seg000:00B646F9                 mov     eax, esi
seg000:00B646FB                 call    edx
seg000:00B646FD                 mov     ebx, eax
seg000:00B646FF                 mov     ecx, [ebp+arg_8]
seg000:00B64702                 mov     edx, ebx
seg000:00B64704                 mov     eax, [ebp+var_g_table]
seg000:00B64707                 call    sub_B6490C
seg000:00B6470C                 test    al, al
seg000:00B6470E                 jz      short loc_B64721
seg000:00B64710                 mov     eax, [ebp+var_g_table]
seg000:00B64713                 mov     eax, [eax+18h]
seg000:00B64716                 add     eax, [ebp+var_itemoff17]
seg000:00B64719                 mov     edx, [ebp+var_g_table]
seg000:00B6471C                 add     eax, [edx+68h]
seg000:00B6471F                 jmp     short loc_B6478A
seg000:00B64721 ;
seg000:00B64721
seg000:00B64721 loc_B64721:                             ; CODE XREF: sub_B64668+A6j
seg000:00B64721                 mov     eax, [ebp+var_g_table]
seg000:00B64724                 mov     eax, [eax+18h]
seg000:00B64727                 add     eax, edi
seg000:00B64729                 mov     edx, [ebp+var_g_table]
seg000:00B6472C                 add     eax, [edx+68h]
seg000:00B6472F                 jmp     short loc_B6478A
seg000:00B64731 ;
seg000:00B64731
seg000:00B64731 loc_B64731:                             ; CODE XREF: sub_B64668+54j
seg000:00B64731                 mov     ecx, esi
seg000:00B64733                 mov     edx, [ebp+arg_4]
seg000:00B64736                 mov     eax, [ebp+var_g_table]
seg000:00B64739                 call    sub_B64544
seg000:00B6473E                 mov     [ebp+arg_8], eax
seg000:00B64741                 xor     eax, eax
seg000:00B64743                 mov     al, [ebx+4]
seg000:00B64746                 mov     edx, [ebp+var_g_table]
seg000:00B64749                 mov     edx, [edx+eax*4+40h]
seg000:00B6474D                 mov     eax, esi
seg000:00B6474F                 call    edx
seg000:00B64751                 mov     ebx, eax
seg000:00B64753                 mov     ecx, [ebp+arg_8]
seg000:00B64756                 mov     edx, ebx
seg000:00B64758                 mov     eax, [ebp+var_g_table]
seg000:00B6475B                 call    sub_B6490C
seg000:00B64760                 test    al, al
seg000:00B64762                 jz      short loc_B64775
seg000:00B64764                 mov     eax, [ebp+var_g_table]
seg000:00B64767                 mov     eax, [eax+18h]
seg000:00B6476A                 add     eax, [ebp+var_itemoff17]
seg000:00B6476D                 mov     edx, [ebp+var_g_table]
seg000:00B64770                 add     eax, [edx+68h]
seg000:00B64773                 jmp     short loc_B6478A
seg000:00B64775 ;
seg000:00B64775
seg000:00B64775 loc_B64775:                             ; CODE XREF: sub_B64668+FAj
seg000:00B64775                 mov     eax, [ebp+var_g_table]
seg000:00B64778                 mov     eax, [eax+18h]
seg000:00B6477B                 add     eax, edi
seg000:00B6477D                 mov     edx, [ebp+var_g_table]
seg000:00B64780                 add     eax, [edx+68h]  ; eax = g_table[18] + off
seg000:00B64783                 jmp     short loc_B6478A
seg000:00B64785 ;
seg000:00B64785
seg000:00B64785 loc_B64785:                             ; CODE XREF: sub_B64668+56j
seg000:00B64785                 mov     eax, 0B551E4h
seg000:00B6478A
seg000:00B6478A loc_B6478A:                             ; CODE XREF: sub_B64668+75j
seg000:00B6478A                                         ; sub_B64668+80j ...
seg000:00B6478A                 mov     edx, [ebp+var_parg]
seg000:00B6478D                 sub     edx, 4
seg000:00B64790                 mov     [edx], eax      ; modify return address = eax = g_table[18] + off
注意这里, 在干什么? 修改 栈里的call DA00000 的返回地址!!!!!
seg000:00B64792                 mov     eax, [ebp+arg_0]
seg000:00B64795                 call    getSEH
seg000:00B6479A                 push    [ebp+var_parg]
seg000:00B6479D                 push    [ebp+arg_8]
seg000:00B647A0                 push    [ebp+arg_4]
seg000:00B647A3                 mov     eax, [ebp+var_g_table]
seg000:00B647A6                 jmp     dword ptr [eax+20h]
seg000:00B647A6 sub_B64668      endp

这里的var_g_table 就是前面所说的第二张表,也就是全局表. b6474f中存的 call edx 最终的地址是查这张表获得的!
先来看看走到 B647A6的这个分支,(到达OEP后第一个call DA0000会走到这里) 其它分支在续文中继续介绍.
jump 的地址是全局表中偏移20h的地址. 这里是 DB0000 也就是 jump 到DB0000.
调来调去, 跳来跳去, 好玩吧.
来到 DB0000

看看DB0000的代码
Þt
seg000:00DB0000 ;
seg000:00DB0000
seg000:00DB0000 ; Segment type: Pure code
seg000:00DB0000 seg000          segment byte public 'CODE' use32
seg000:00DB0000                 assume cs:seg000
seg000:00DB0000                 ;org 0DB0000h
seg000:00DB0000                 assume es:nothing, ss:nothing, ds:nothing, fs:nothing, gs:nothing
seg000:00DB0000                 jmp     short loc_DB0003
seg000:00DB0002 ;
seg000:00DB0002                 nop
seg000:00DB0003
seg000:00DB0003 loc_DB0003:                             ; CODE XREF: seg000:00DB0000j
seg000:00DB0003                 nop
seg000:00DB0004                 jmp     short loc_DB0008
seg000:00DB0004 ;
seg000:00DB0006                 db  90h ; 
seg000:00DB0007                 db  90h ; 
seg000:00DB0008 ;
seg000:00DB0008
seg000:00DB0008 loc_DB0008:                             ; CODE XREF: seg000:00DB0004j
seg000:00DB0008                 lea     ebx, [ecx+edx+451F90h]
seg000:00DB000F                 pop     ebx             ; ebx = stack location of saved eax
seg000:00DB0010                 db      2Eh
seg000:00DB0010                 jmp     short loc_DB0014
seg000:00DB0010 ;
seg000:00DB0013                 db  90h ; 
seg000:00DB0014 ;
seg000:00DB0014
seg000:00DB0014 loc_DB0014:                             ; CODE XREF: seg000:00DB0010j
seg000:00DB0014                 nop
seg000:00DB0015                 nop
seg000:00DB0016                 nop
seg000:00DB0017                 nop
seg000:00DB0018                 nop
seg000:00DB0019                 nop
seg000:00DB001A                 nop
seg000:00DB001B                 nop
seg000:00DB001C                 nop
seg000:00DB001D                 nop
seg000:00DB001E                 nop
seg000:00DB001F                 nop
seg000:00DB0020                 nop
seg000:00DB0021                 nop
seg000:00DB0022                 jmp     short loc_DB0025
seg000:00DB0022 ;
seg000:00DB0024                 db  90h ; 
seg000:00DB0025 ;
seg000:00DB0025
seg000:00DB0025 loc_DB0025:                             ; CODE XREF: seg000:00DB0022j
seg000:00DB0025                 nop
seg000:00DB0026                 nop
seg000:00DB0027                 nop
seg000:00DB0028                 nop
seg000:00DB0029                 nop
seg000:00DB002A                 nop
seg000:00DB002B                 nop
seg000:00DB002C                 nop
seg000:00DB002D                 db      64h
seg000:00DB002D                 jmp     short loc_DB0032
seg000:00DB002D ;
seg000:00DB0030                 db  90h ; 
seg000:00DB0031                 db  90h ; 
seg000:00DB0032 ;
seg000:00DB0032
seg000:00DB0032 loc_DB0032:                             ; CODE XREF: seg000:00DB002Dj
seg000:00DB0032                 lea     ecx, [ebx+4]
seg000:00DB0035                 mov     ecx, [ecx]      ; saved ecx -> ecx
seg000:00DB0037                 nop
seg000:00DB0038                 nop
seg000:00DB0039                 nop
seg000:00DB003A                 nop
seg000:00DB003B                 nop
seg000:00DB003C                 nop
seg000:00DB003D                 push    dword ptr [ebx+8]
seg000:00DB0040                 jmp     short loc_DB0043
seg000:00DB0040 ;
seg000:00DB0042                 db 0C7h ; Ç
seg000:00DB0043 ;
seg000:00DB0043
seg000:00DB0043 loc_DB0043:                             ; CODE XREF: seg000:00DB0040j
seg000:00DB0043                 nop
seg000:00DB0044                 nop
seg000:00DB0045                 nop
seg000:00DB0046                 nop
seg000:00DB0047                 nop
seg000:00DB0048                 nop
seg000:00DB0049                 nop
seg000:00DB004A                 nop
seg000:00DB004B                 nop
seg000:00DB004C                 nop
seg000:00DB004D                 pop     edx             ; saved edx -> edx
seg000:00DB004E                 jmp     short loc_DB0051
seg000:00DB004E ;
seg000:00DB0050                 db  90h ; 
seg000:00DB0051 ;
seg000:00DB0051
seg000:00DB0051 loc_DB0051:                             ; CODE XREF: seg000:00DB004Ej
seg000:00DB0051                 lea     edi, [ebp+esi-3]
seg000:00DB0055                 push    dword ptr [ebx+1Ch]
seg000:00DB0058                 nop
seg000:00DB0059                 nop
seg000:00DB005A                 nop
seg000:00DB005B                 nop
seg000:00DB005C                 nop
seg000:00DB005D                 nop
seg000:00DB005E                 pop     edi             ; saved edi -> edi
seg000:00DB005F                 lea     eax, [ebx+5Ah]
seg000:00DB0062                 push    dword ptr [ebx+0]
seg000:00DB0066                 nop
seg000:00DB0067                 nop
seg000:00DB0068                 pop     eax             ; saved eax -> eax
seg000:00DB0069                 nop
seg000:00DB006A                 nop
seg000:00DB006B                 nop
seg000:00DB006C                 nop
seg000:00DB006D                 nop
seg000:00DB006E                 nop
seg000:00DB006F                 nop
seg000:00DB0070                 nop
seg000:00DB0071                 lea     ebp, [ebx+14h]
seg000:00DB0074                 lea     ebp, [ebp+ecx+6Fh]
seg000:00DB0078                 nop
seg000:00DB0079                 jmp     short loc_DB007D
seg000:00DB0079 ;
seg000:00DB007B                 db  90h ; 
seg000:00DB007C                 db  90h ; 
seg000:00DB007D ;
seg000:00DB007D
seg000:00DB007D loc_DB007D:                             ; CODE XREF: seg000:00DB0079j
seg000:00DB007D                 sub     ebp, ecx
seg000:00DB007F                 lea     ebp, [ebp-6Fh]
seg000:00DB0082                 jmp     short loc_DB0085
seg000:00DB0082 ;
seg000:00DB0084                 db 0C7h ; Ç
seg000:00DB0085 ;
seg000:00DB0085
seg000:00DB0085 loc_DB0085:                             ; CODE XREF: seg000:00DB0082j
seg000:00DB0085                 lea     ebp, [ebp+66h]
seg000:00DB0088  
seg000:00DB008A                 db  90h ; 
seg000:00DB008B ;
seg000:00DB008B
seg000:00DB008B loc_DB008B:                             ; CODE XREF: seg000:00DB0088j
seg000:00DB008B                 db      36h
seg000:00DB008B                 jmp     short loc_DB008F
seg000:00DB008B ;
seg000:00DB008E                 db  90h ; 
seg000:00DB008F ;
seg000:00DB008F
seg000:00DB008F loc_DB008F:                             ; CODE XREF: seg000:loc_DB008Bj
seg000:00DB008F                 lea     ebp, [ebp-66h]
seg000:00DB0092                 db      2Eh
seg000:00DB0092                 jmp     short loc_DB0096
seg000:00DB0092 ;
seg000:00DB0095                 db 0F3h ; ó
seg000:00DB0096 ;
seg000:00DB0096
seg000:00DB0096 loc_DB0096:                             ; CODE XREF: seg000:00DB0092j
seg000:00DB0096                 lea     ebp, [ebp+esi+3Eh]
seg000:00DB009A                 jmp     short loc_DB009D
seg000:00DB009A ;
seg000:00DB009C                 db  90h ; 
seg000:00DB009D ;
seg000:00DB009D
seg000:00DB009D loc_DB009D:                             ; CODE XREF: seg000:00DB009Aj
seg000:00DB009D                 sub     ebp, esi
seg000:00DB009F                 sub     ebp, 3Eh ; '>'
seg000:00DB00A2                 db      36h
seg000:00DB00A2                 jmp     short loc_DB00A6
seg000:00DB00A2 ;
seg000:00DB00A5                 db  90h ; 
seg000:00DB00A6 ;
seg000:00DB00A6
seg000:00DB00A6 loc_DB00A6:                             ; CODE XREF: seg000:00DB00A2j
seg000:00DB00A6                 mov     ebp, [ebp+0]
seg000:00DB00A9                 nop
seg000:00DB00AA                 nop
seg000:00DB00AB                 nop
seg000:00DB00AC                 nop
seg000:00DB00AD                 nop
seg000:00DB00AE                 nop
seg000:00DB00AF                 nop
seg000:00DB00B0                 nop
seg000:00DB00B1                 nop
seg000:00DB00B2                 jmp     short loc_DB00B5
seg000:00DB00B2 ;
seg000:00DB00B4                 db  90h ; 
seg000:00DB00B5 ;
seg000:00DB00B5
seg000:00DB00B5 loc_DB00B5:                             ; CODE XREF: seg000:00DB00B2j
seg000:00DB00B5                 lea     esi, [edi+eax+1Bh]
seg000:00DB00B9                 lea     esi, [ebx+18h]
seg000:00DB00BC                 nop
seg000:00DB00BD                 jmp     short loc_DB00C0
seg000:00DB00BD ;
seg000:00DB00BF                 db  90h ; 
seg000:00DB00C0 ;
seg000:00DB00C0
seg000:00DB00C0 loc_DB00C0:                             ; CODE XREF: seg000:00DB00BDj
seg000:00DB00C0                 push    dword ptr [esi]
seg000:00DB00C2                 sbb     esi, 0FFFFFF91h
seg000:00DB00C5                 xor     esi, [esp+28h]
seg000:00DB00C9                 pop     esi             ; saved esi -> esi
seg000:00DB00CA                 nop
seg000:00DB00CB                 jmp     short loc_DB00CE
seg000:00DB00CB ;
seg000:00DB00CD                 db  90h ; 
seg000:00DB00CE ;
seg000:00DB00CE
seg000:00DB00CE loc_DB00CE:                             ; CODE XREF: seg000:00DB00CBj
seg000:00DB00CE                 push    dword ptr [ebx+0Ch]
seg000:00DB00D1                 nop
seg000:00DB00D2                 nop
seg000:00DB00D3                 nop
seg000:00DB00D4                 nop
seg000:00DB00D5                 nop
seg000:00DB00D6                 nop
seg000:00DB00D7                 nop
seg000:00DB00D8                 nop
seg000:00DB00D9                 pop     ebx             ; saved ebx -> ebx
seg000:00DB00DA                 popf
seg000:00DB00DB                 nop
seg000:00DB00DC                 jmp     short loc_DB00DF ; saved esp
seg000:00DB00DC ;
seg000:00DB00DE                 db  90h ; 
seg000:00DB00DF ;
seg000:00DB00DF
seg000:00DB00DF loc_DB00DF:                             ; CODE XREF: seg000:00DB00DCj
seg000:00DB00DF                 pop     esp             ; saved esp
seg000:00DB00E0                 jmp     dword ptr [esp-4] ; return

DB0000的代码其实异常简单, 所有恢复所有寄存器,返回. 注意了,前面提到栈中的返回地址被修改了. 所以,返回是返回到这个被修改的地址上.

[培训]《安卓高级研修班(网课)》月薪三万计划,掌握调试、分析还原ollvm、vmp的方法,定制art虚拟机自动化脱壳的方法

收藏
免费 0
支持
分享
最新回复 (3)
雪    币: 443
活跃值: (200)
能力值: ( LV9,RANK:1140 )
在线值:
发帖
回帖
粉丝
2
好文章啊~~学习
2007-4-10 01:18
0
雪    币: 236
活跃值: (59)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
3
好 文,继续
2007-4-10 16:55
0
雪    币: 200
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
4
学习
好东西我喜欢
2007-5-6 12:00
0
游客
登录 | 注册 方可回帖
返回
//