【文章标题】: AHpack分析
【文章作者】: witkey
【下载地址】: 自己搜索下载
【加壳方式】: Ahpack
【保护方式】: Ahpack
【编写语言】: Asm
【使用工具】: OD LoadPe
【操作平台】: winxp
【作者声明】: 只是感兴趣,没有其他目的。失误之处敬请诸位大侠赐教!
--------------------------------------------------------------------------------
【详细过程】
  夜雨无眠,特来简单分析简单压缩壳流程,简单但分析和写脚本过程,堪称痛苦,因为老是给小问题阻挡。.. 因此也增添了兴趣,学到了很多思路。
  以及熟练脚本写法,脚本测试的是已加壳程序,未测试其他语言加此壳是否通过!~~~~~

  OD载入:

代码:
  004040FF >  60              pushad                                   ; 保存FPU寄存器
  00404100    68 54404000     push    00404054                         ; 直接硬件地址
  00404105    B8 48404000     mov     eax, <&KERNEL32.GetModuleHandleA>
  0040410A    FF10            call    dword ptr [eax]                  ; ; kernel32.GetModuleHandleA
  0040410C    68 B3404000     push    004040B3                         ; 硬件编码,GlobalAlloc
  00404111    50              push    eax
  00404112    B8 44404000     mov     eax, <&KERNEL32.GetProcAddress>
  00404117    FF10            call    dword ptr [eax]                  ; 获取函数后,直接调用
  00404119    68 00080000     push    800                              ; 分配Size
  0040411E    6A 40           push    40                               ; 分配属性
  00404120    FFD0            call    eax
  00404122    8905 CA404000   mov     dword ptr [4040CA], eax          ; Bak Flags
  00404128    89C7            mov     edi, eax                         ; Edi作目的地址
  0040412A    BE 00104000     mov     esi, 00401000                    ; 源地址
  0040412F    60              pushad                                   ; 这里就是Aplib压缩算法
  00404130    FC              cld
  00404131    B2 80           mov     dl, 80
  00404133    31DB            xor     ebx, ebx
  00404135    A4              movs    byte ptr es:[edi], byte ptr [esi>
  00404136    B3 02           mov     bl, 2
  00404138    E8 6D000000     call    004041AA
  0040413D  ^ 73 F6           jnb     short 00404135
  0040413F    31C9            xor     ecx, ecx
  00404141    E8 64000000     call    004041AA
  00404146    73 1C           jnb     short 00404164
  00404148    31C0            xor     eax, eax
  0040414A    E8 5B000000     call    004041AA
  0040414F    73 23           jnb     short 00404174
  00404151    B3 02           mov     bl, 2
  00404153    41              inc     ecx
  00404154    B0 10           mov     al, 10
  00404156    E8 4F000000     call    004041AA
  0040415B    10C0            adc     al, al
  0040415D  ^ 73 F7           jnb     short 00404156
  0040415F    75 3F           jnz     short 004041A0
  00404161    AA              stos    byte ptr es:[edi]
  00404162  ^ EB D4           jmp     short 00404138
  00404164    E8 4D000000     call    004041B6
  00404169    29D9            sub     ecx, ebx
  0040416B    75 10           jnz     short 0040417D
  0040416D    E8 42000000     call    004041B4
  00404172    EB 28           jmp     short 0040419C
  00404174    AC              lods    byte ptr [esi]
  00404175    D1E8            shr     eax, 1
  00404177    74 4D           je      short 004041C6
  00404179    11C9            adc     ecx, ecx
  0040417B    EB 1C           jmp     short 00404199
  0040417D    91              xchg    eax, ecx
  0040417E    48              dec     eax
  0040417F    C1E0 08         shl     eax, 8
  00404182    AC              lods    byte ptr [esi]
  00404183    E8 2C000000     call    004041B4
  00404188    3D 007D0000     cmp     eax, 7D00
  0040418D    73 0A           jnb     short 00404199
  0040418F    80FC 05         cmp     ah, 5
  00404192    73 06           jnb     short 0040419A
  00404194    83F8 7F         cmp     eax, 7F
  00404197    77 02           ja      short 0040419B
  00404199    41              inc     ecx
  0040419A    41              inc     ecx
  0040419B    95              xchg    eax, ebp
  0040419C    89E8            mov     eax, ebp
  0040419E    B3 01           mov     bl, 1
  004041A0    56              push    esi
  004041A1    89FE            mov     esi, edi
  004041A3    29C6            sub     esi, eax
  004041A5    F3:A4           rep     movs byte ptr es:[edi], byte ptr>
  004041A7    5E              pop     esi
  004041A8  ^ EB 8E           jmp     short 00404138
  004041AA    00D2            add     dl, dl
  004041AC    75 05           jnz     short 004041B3
  004041AE    8A16            mov     dl, byte ptr [esi]
  004041B0    46              inc     esi
  004041B1    10D2            adc     dl, dl
  004041B3    C3              retn
  004041B4    31C9            xor     ecx, ecx
  004041B6    41              inc     ecx
  004041B7    E8 EEFFFFFF     call    004041AA
  004041BC    11C9            adc     ecx, ecx
  004041BE    E8 E7FFFFFF     call    004041AA
  004041C3  ^ 72 F2           jb      short 004041B7
  004041C5    C3              retn
  004041C6    61              popad
  004041C7    B9 FC070000     mov     ecx, 7FC                         ; 直接赋值硬件Size
  004041CC    8B1C08          mov     ebx, dword ptr [eax+ecx]
  004041CF    8999 00104000   mov     dword ptr [ecx+401000], ebx
  004041D5  ^ E2 F5           loopd   short 004041CC                   ; 解码
  004041D7    90              nop
  004041D8    90              nop
  004041D9    BA 00004000     mov     edx, 00400000
  004041DE    BE 70200000     mov     esi, 2070                        ; 直接引用IAT地址
  004041E3    01D6            add     esi, edx
  004041E5    8B46 0C         mov     eax, dword ptr [esi+C]           ; 获取IID NAME
  004041E8    85C0            test    eax, eax
  004041EA    0F84 87000000   je      00404277
  004041F0    01D0            add     eax, edx
  004041F2    89C3            mov     ebx, eax
  004041F4    50              push    eax
  004041F5    B8 48404000     mov     eax, <&KERNEL32.GetModuleHandleA>
  004041FA    FF10            call    dword ptr [eax]                  ; 获取NAME模块句柄
  004041FC    85C0            test    eax, eax
  004041FE    75 08           jnz     short 00404208                   ; 获取不到调用LoadLibraryA
  00404200    53              push    ebx
  00404201    B8 4C404000     mov     eax, <&KERNEL32.LoadLibraryA>
  00404206    FF10            call    dword ptr [eax]
  00404208    8905 CE404000   mov     dword ptr [4040CE], eax          ; 作者作一次判断就决定LoadLibraryA肯定获取得到!当前作Flags
  0040420E    C705 D2404000 0>mov     dword ptr [4040D2], 0            ; 将模块句柄作标志Flags区分
  00404218    BA 00004000     mov     edx, 00400000
  0040421D    8B06            mov     eax, dword ptr [esi]             ; 获取OriginalFirstThunk
  0040421F    85C0            test    eax, eax
  00404221    75 03           jnz     short 00404226                   ; 如果获取不到就获取FirstThunk
  00404223    8B46 10         mov     eax, dword ptr [esi+10]
  00404226    01D0            add     eax, edx
  00404228    0305 D2404000   add     eax, dword ptr [4040D2]          ; 加上模块句柄的Flags
  0040422E    8B18            mov     ebx, dword ptr [eax]             ; 取这个是作判断
  00404230    8B7E 10         mov     edi, dword ptr [esi+10]          ; 最后还是使用FirstThunk
  00404233    01D7            add     edi, edx
  00404235    033D D2404000   add     edi, dword ptr [4040D2]
  0040423B    85DB            test    ebx, ebx                         ; 奇怪???? 呵呵 (判断DLL)
  0040423D    74 2B           je      short 0040426A
  0040423F    F7C3 00000080   test    ebx, 80000000                    ; 判断高位
  00404245    75 04           jnz     short 0040424B
  00404247    01D3            add     ebx, edx
  00404249    43              inc     ebx
  0040424A    43              inc     ebx
  0040424B    81E3 FFFFFF0F   and     ebx, 0FFFFFFF                    ; 与是否符合位
  00404251    53              push    ebx
  00404252    FF35 CE404000   push    dword ptr [4040CE]
  00404258    B8 44404000     mov     eax, <&KERNEL32.GetProcAddress>
  0040425D    FF10            call    dword ptr [eax]
  0040425F    8907            mov     dword ptr [edi], eax
  00404261    8305 D2404000 0>add     dword ptr [4040D2], 4
  00404268  ^ EB AE           jmp     short 00404218
  0040426A    83C6 14         add     esi, 14
  0040426D    BA 00004000     mov     edx, 00400000
  00404272  ^ E9 6EFFFFFF     jmp     004041E5
  00404277    68 54404000     push    00404054                         ; ASCII "KERNEL32.DLL"
  0040427C    B8 48404000     mov     eax, <&KERNEL32.GetModuleHandleA>
  00404281    FF10            call    dword ptr [eax]
  00404283    68 BF404000     push    004040BF                         ; ASCII "GlobalFree"
  00404288    50              push    eax
  00404289    B8 44404000     mov     eax, <&KERNEL32.GetProcAddress>
  0040428E    FF10            call    dword ptr [eax]
  00404290    8B15 CA404000   mov     edx, dword ptr [4040CA]
  00404296    52              push    edx
  00404297    FFD0            call    eax                              ; GlobalFree
  00404299    61              popad
  0040429A    BA 00104000     mov     edx, 00401000
  0040429F    FFE2            jmp     edx
  一、壳采用固定编码来调用壳所需要用到的函数。..
  
  二、采用aplib压缩,通过固定Size解码到原程序。..
  
  三、获取IID Name -- GetModuleHandleA --> Jnz <--LoadLibraryA -- Save
      设置Flags判断 -- 获取OriginalFirstThunk --> jnz <-- 获取TirstThunk 无论结果如何还是选择TirstThunk -- 填充

个人理解可能有误,希望路过的看过的指点,因为接触并不多~~~ (*^__^*) 嘻嘻……

简单脚本:

代码:
  Var Oep
  Var IatRva
  Var Iatva
  Var ImageBase
  
  Strat:
    BPHWCALL
    Find eip,#BE????????#
    mov ImageBase,[$RESULT+1]
    sub ImageBase,1000
    Find eip,#BA????????BE????0000#
    go $RESULT
    mov IatRva,[$RESULT+6]
    mov Iatva,ImageBase+IatRva
    cmt eip,"IatRva"
    Find eip,#61BA????????FFE2#
    go $RESULT
    Sto
    Sto
    Sto
    mov Oep,eip
    cmt eip,"查看LOG的IATRVA使用LoadPe修改IatRVA即可运行"
    an eip
    DPE "Dump.exe",eip
  Log:
    LOG ImageBase,"ImageBase="
    LOG IatRva,"IatRva="
    LOG Oep,"Oep="
    
    
  End:
    ret
                                                                                       2011年07月28日 23:21:01