【转载】一个最基本加密壳(ExeStealth)的完整分析

Eddy 发布于2010-2-25 8:39:0 分类: 加密解密 已浏览loading 网友评论0条 我要评论

文章作者: xiaobaozi49

刚刚开始 F7 加密壳,ExeStealth是个最基本的加密壳, 它有反调试反跟踪,IAT加密,花指令,文件校验,内存校验等手段,不过都是最基本方式
所以一开始拿它下手是在合适不过的了
OD载入
00423060 > /EB 58           jmp     short _ExeStea.004230BA
一开始就跳 - -!
004230BA    90              nop
004230BB    60              pushad
004230BC    90              nop
004230BD    E8 00000000     call    _ExeStea.004230C2                ; 自定位call
004230C2    5D              pop     ebp
004230C3    81ED F7274000   sub     ebp, _ExeStea.004027F7           ; 获取自定位偏移量
004230C9    B9 15000000     mov     ecx, 15
004230CE    83C1 04         add     ecx, 4
004230D1    83C1 01         add     ecx, 1
004230D4    EB 05           jmp     short _ExeStea.004230DB
004230D6  - EB FE           jmp     short _ExeStea.004230D6
004230D8    83C7 56         add     edi, 56
004230DB    EB 00           jmp     short _ExeStea.004230DD
004230DD    EB 00           jmp     short _ExeStea.004230DF
004230DF    83E9 02         sub     ecx, 2
004230E2    81C1 78432765   add     ecx, 65274378
004230E8    EB 00           jmp     short _ExeStea.004230EA
004230EA    81C1 10259400   add     ecx, 942510
004230F0    81E9 63850000   sub     ecx, 8563
004230F6    B9 960C0000     mov     ecx, 0C96
004230FB    90              nop
004230FC    8DBD 74284000   lea     edi, dword ptr ss:[ebp+402874]
00423102    8BF7            mov     esi, edi
00423104    AC              lods    byte ptr ds:[esi]
00423105    F8              clc
00423106    2C ED           sub     al, 0ED
00423108    F8              clc
00423109    2AC1            sub     al, cl
0042310B    F8              clc
0042310C    F9              stc
0042310D    2AC1            sub     al, cl
0042310F    F9              stc
00423110    04 4D           add     al, 4D
00423112    F8              clc
00423113    F8              clc
00423114    2AC1            sub     al, cl
00423116    04 D4           add     al, 0D4
00423118    F9              stc
00423119    2C B8           sub     al, 0B8
0042311B    F9              stc
0042311C    F9              stc
0042311D    F9              stc
0042311E    04 47           add     al, 47
00423120    02C1            add     al, cl
00423122    34 90           xor     al, 90
00423124    F8              clc
00423125    90              nop
00423126    F8              clc
00423127    F8              clc
00423128    04 50           add     al, 50
0042312A    2C ED           sub     al, 0ED
0042312C    F8              clc
0042312D    2AC1            sub     al, cl
0042312F    F8              clc
00423130    F9              stc
00423131    2AC1            sub     al, cl
00423133    F9              stc
00423134    04 4D           add     al, 4D
00423136    F8              clc
00423137    F8              clc
00423138    2AC1            sub     al, cl
0042313A    04 D4           add     al, 0D4
0042313C    AA              stos    byte ptr es:[edi]
0042313D  ^ E2 C5           loopd   short _ExeStea.00423104          ; 解压下面的代码
0042313F    C2 5631         retn    3156                             ; 解压这里到00423dd5的核心代码和数据
00423142    288E 421D3492   sub     byte ptr ds:[esi+92341D42], cl
00423148    CA 1383         retf    8313
0042314B    E3 04           jecxz   short _ExeStea.00423151
把壳的核心代码和数据解压出来,0042313F到00423dd5是壳的核心代码和数据,前面只是引导代码
在0042313F  F4。OK代码已经解压完毕
0042313F    8B4424 20       mov     eax, dword ptr ss:[esp+20]       ; kernel32.761C4911
00423143    8B4424 20       mov     eax, dword ptr ss:[esp+20]
00423147    83C0 0E         add     eax, 0E                          ; 废指令
0042314A    83E8 0E         sub     eax, 0E
0042314D    83C0 0E         add     eax, 0E
00423150    83E8 0E         sub     eax, 0E
00423153    40              inc     eax
00423154    78 1D           js      short _ExeStea.00423173
00423156    C785 FC2F4000 0>mov     dword ptr ss:[ebp+402FFC], 1
00423160    EB 11           jmp     short _ExeStea.00423173
00423162    8B4424 20       mov     eax, dword ptr ss:[esp+20]
00423166    83C0 0E         add     eax, 0E
00423169    83E8 0E         sub     eax, 0E
0042316C    83C0 0E         add     eax, 0E
0042316F    83E8 0E         sub     eax, 0E
00423172    40              inc     eax
00423173    8D85 95274000   lea     eax, dword ptr ss:[ebp+402795]
00423179    B9 06070000     mov     ecx, 706
0042317E    E8 41020000     call    _ExeStea.004233C4                ; 求壳入口之后的0x706个字节校验和
00423183    8985 F82F4000   mov     dword ptr ss:[ebp+402FF8], eax   ; 保存校验和
00423189    8B85 F02F4000   mov     eax, dword ptr ss:[ebp+402FF0]
0042318F    83E0 01         and     eax, 1
00423192    74 40           je      short _ExeStea.004231D4
00423194    8DB5 38344000   lea     esi, dword ptr ss:[ebp+403438]
0042319A    8D85 F6284000   lea     eax, dword ptr ss:[ebp+4028F6]   ; 新的EIP(异常的下一条指令)
004231A0    8946 08         mov     dword ptr ds:[esi+8], eax        ; 保存新的eip
004231A3    8BFD            mov     edi, ebp                         ; 保存ebp
004231A5    8D85 862F4000   lea     eax, dword ptr ss:[ebp+402F86]   ; 取异常处理Handle
004231AB    33DB            xor     ebx, ebx
004231AD    50              push    eax
004231AE    64:FF33         push    dword ptr fs:[ebx]
004231B1    64:8923         mov     dword ptr fs:[ebx], esp
004231B4    BD 4B484342     mov     ebp, 4243484B                    ; 清除ebp
004231B9    66:B8 0400      mov     ax, 4                            ; 清除ax
004231BD    EB 01           jmp     short _ExeStea.004231C0          ; 花指令
004231BF    FFCC            dec     esp                              ; int3异常触发异常
004231C1    8BEF            mov     ebp, edi
004231C3    33DB            xor     ebx, ebx
004231C5    64:8F03         pop     dword ptr fs:[ebx]
004231C8    83C4 04         add     esp, 4
004231CB    3C 04           cmp     al, 4
004231CD    74 05           je      short _ExeStea.004231D4
004231CF    EB 01           jmp     short _ExeStea.004231D2
开始执行壳的核心代码,首先求解压出来壳的核心代码求校验和并保存,在后面校验壳代码是否被修改过的时候使用
然后就是一个异常来反调试,通过int3来触发(没看到INT3?   看看004231BF这字节码为FFCC,FF是花指令),在异常前清除
Ebp,在异常Handle中恢复Ebp,并修改EIP到异常发生的下一条指令,就跳过了异常
在INT3的下一条指令004231C1下断,然后一直走
004231D4    8B85 E82F4000   mov     eax, dword ptr ss:[ebp+402FE8]   ; _ExeStea.00400000
004231DA    0340 3C         add     eax, dword ptr ds:[eax+3C]
004231DD    05 80000000     add     eax, 80
004231E2    8B08            mov     ecx, dword ptr ds:[eax]
004231E4    038D E82F4000   add     ecx, dword ptr ss:[ebp+402FE8]
004231EA    83C1 10         add     ecx, 10
004231ED    8B01            mov     eax, dword ptr ds:[ecx]
004231EF    0385 E82F4000   add     eax, dword ptr ss:[ebp+402FE8]
004231F5    8B18            mov     ebx, dword ptr ds:[eax]          ; 获取LoadLibrary地址
004231F7    899D 44344000   mov     dword ptr ss:[ebp+403444], ebx   ; 保存LoadLibrary地址
004231FD    83C0 04         add     eax, 4
00423200    8B18            mov     ebx, dword ptr ds:[eax]          ; 获取GetProcAddress地址
00423202    899D 48344000   mov     dword ptr ss:[ebp+403448], ebx   ; 保存GetProcAddress地址
00423208    8D85 4C344000   lea     eax, dword ptr ss:[ebp+40344C]
0042320E    50              push    eax
0042320F    FF95 44344000   call    dword ptr ss:[ebp+403444]        ; LoadLibrary加载kernel32
00423215    8BF0            mov     esi, eax
00423217    8985 59344000   mov     dword ptr ss:[ebp+403459], eax   ; 保存kernel32基址
0042321D    8D85 5D344000   lea     eax, dword ptr ss:[ebp+40345D]
00423223    E8 96000000     call    _ExeStea.004232BE                ; 获取GetModuleHandleA地址
00423228    8985 6E344000   mov     dword ptr ss:[ebp+40346E], eax   ; 保存GetModuleHandleA地址
0042322E    8D85 72344000   lea     eax, dword ptr ss:[ebp+403472]
00423234    E8 85000000     call    _ExeStea.004232BE                ; 获取VirtualProtect地址
00423239    8985 81344000   mov     dword ptr ss:[ebp+403481], eax   ; 保存VirtualProtect地址
0042323F    8D85 85344000   lea     eax, dword ptr ss:[ebp+403485]
00423245    E8 74000000     call    _ExeStea.004232BE                ; 保存GetModuleFileNameA地址
0042324A    8985 98344000   mov     dword ptr ss:[ebp+403498], eax
00423250    8D85 9C344000   lea     eax, dword ptr ss:[ebp+40349C]
00423256    E8 63000000     call    _ExeStea.004232BE                ; 保存CreateFileA地址
0042325B    8985 A8344000   mov     dword ptr ss:[ebp+4034A8], eax
00423261    8D85 AC344000   lea     eax, dword ptr ss:[ebp+4034AC]
00423267    E8 52000000     call    _ExeStea.004232BE                ; 保存GlobalAlloc地址
0042326C    8985 B8344000   mov     dword ptr ss:[ebp+4034B8], eax
00423272    8D85 BC344000   lea     eax, dword ptr ss:[ebp+4034BC]
00423278    E8 41000000     call    _ExeStea.004232BE                ; 保存GlobalFree地址
0042327D    8985 C7344000   mov     dword ptr ss:[ebp+4034C7], eax
00423283    8D85 CB344000   lea     eax, dword ptr ss:[ebp+4034CB]
00423289    E8 30000000     call    _ExeStea.004232BE                ; 保存ReadFile地址
0042328E    8985 D4344000   mov     dword ptr ss:[ebp+4034D4], eax
00423294    8D85 D8344000   lea     eax, dword ptr ss:[ebp+4034D8]
0042329A    E8 1F000000     call    _ExeStea.004232BE                ; 保存GetFileSize地址
0042329F    8985 E4344000   mov     dword ptr ss:[ebp+4034E4], eax
004232A5    8D85 E8344000   lea     eax, dword ptr ss:[ebp+4034E8]
004232AB    E8 0E000000     call    _ExeStea.004232BE                ; 保存CloseHandle地址
004232B0    8985 F4344000   mov     dword ptr ss:[ebp+4034F4], eax
004232B6    8D85 FC294000   lea     eax, dword ptr ss:[ebp+4029FC]
004232BC    50              push    eax
004232BD    C3              retn
这一段主要是获取一些壳所需API的地址,用于检验文件是否被修改和填充IAT的时候用
004232C7    F785 F02F4000 1>test    dword ptr ss:[ebp+402FF0], 10
004232D1    74 37           je      short _ExeStea.0042330A
004232D3    64:FF35 3000000>push    dword ptr fs:[30]                ; 获取PEB
004232DA    58              pop     eax
004232DB    85C0            test    eax, eax
004232DD    78 0F           js      short _ExeStea.004232EE
004232DF    8B40 0C         mov     eax, dword ptr ds:[eax+C]
004232E2    8B40 0C         mov     eax, dword ptr ds:[eax+C]
004232E5    C740 20 0010000>mov     dword ptr ds:[eax+20], 1000
004232EC    EB 1C           jmp     short _ExeStea.0042330A
004232EE    6A 00           push    0
004232F0    FF95 6E344000   call    dword ptr ss:[ebp+40346E]
004232F6    85D2            test    edx, edx
004232F8    79 10           jns     short _ExeStea.0042330A
004232FA    837A 08 FF      cmp     dword ptr ds:[edx+8], -1
004232FE    75 0A           jnz     short _ExeStea.0042330A
00423300    8B52 04         mov     edx, dword ptr ds:[edx+4]
00423303    C742 50 0010000>mov     dword ptr ds:[edx+50], 1000
0042330A    8BBD E82F4000   mov     edi, dword ptr ss:[ebp+402FE8]
00423310    037F 3C         add     edi, dword ptr ds:[edi+3C]       ; 定位到PE_NT_HEADER
00423313    8BB5 E82F4000   mov     esi, dword ptr ss:[ebp+402FE8]
00423319    8B4F 54         mov     ecx, dword ptr ds:[edi+54]       ; 获取DOS,PE,区块头的总大小
0042331C    8D85 26354000   lea     eax, dword ptr ss:[ebp+403526]
00423322    50              push    eax
00423323    6A 04           push    4
00423325    51              push    ecx
00423326    FFB5 E82F4000   push    dword ptr ss:[ebp+402FE8]
0042332C    FF95 81344000   call    dword ptr ss:[ebp+403481]        ; 修改PE头属性可写可拷贝
00423332    F785 F02F4000 0>test    dword ptr ss:[ebp+402FF0], 8
0042333C    0F84 A7000000   je      _ExeStea.004233E9
00423342    68 04010000     push    104
00423347    8DBD 26354000   lea     edi, dword ptr ss:[ebp+403526]
0042334D    57              push    edi
0042334E    6A 00           push    0
00423350    FF95 98344000   call    dword ptr ss:[ebp+403498]        ; GetModuleFileNameA获取自身文件名
00423356    6A 00           push    0
00423358    68 80000000     push    80
0042335D    6A 03           push    3
0042335F    6A 00           push    0
00423361    6A 01           push    1
00423363    68 00000080     push    80000000
00423368    57              push    edi
00423369    FF95 A8344000   call    dword ptr ss:[ebp+4034A8]        ; CreateFileA打开自身文件
0042336F    83F8 FF         cmp     eax, -1
00423372    75 04           jnz     short _ExeStea.00423378
00423374    33C0            xor     eax, eax
00423376    EB 71           jmp     short _ExeStea.004233E9
00423378    8BF8            mov     edi, eax
0042337A    6A 00           push    0
0042337C    57              push    edi
0042337D    FF95 E4344000   call    dword ptr ss:[ebp+4034E4]        ; GetFileSize获取文件大小
00423383    83E8 05         sub     eax, 5                           ; 文件大小-5
00423386    96              xchg    eax, esi
00423387    56              push    esi
00423388    6A 40           push    40
0042338A    FF95 B8344000   call    dword ptr ss:[ebp+4034B8]        ; GlobalAlloc分配文件大小的内存
00423390    0BC0            or      eax, eax
00423392    75 02           jnz     short _ExeStea.00423396
00423394    EB 4A           jmp     short _ExeStea.004233E0
00423396    93              xchg    eax, ebx
00423397    6A 00           push    0
00423399    8D85 26354000   lea     eax, dword ptr ss:[ebp+403526]
0042339F    50              push    eax
004233A0    56              push    esi
004233A1    53              push    ebx
004233A2    57              push    edi
004233A3    FF95 D4344000   call    dword ptr ss:[ebp+4034D4]        ; ReadFile读取整个自身文件到内存
004233A9    8BC3            mov     eax, ebx
004233AB    8BCE            mov     ecx, esi
004233AD    53              push    ebx
004233AE    57              push    edi
004233AF    E8 10000000     call    _ExeStea.004233C4                ; 求从文件中读出到内存的校验和
004233B4    8985 F42F4000   mov     dword ptr ss:[ebp+402FF4], eax   ; 保存校验和
004233BA    5F              pop     edi
004233BB    5B              pop     ebx
004233BC    8D85 0D2B4000   lea     eax, dword ptr ss:[ebp+402B0D]
004233C2    50              push    eax
004233C3    C3              retn
修改PE头属性为可写可拷贝,分配内存,读取整个文件到内存中求校验和并保存,在之后校验文件是否被修改的时候用
004233D8    53              push    ebx
004233D9    FF95 C7344000   call    dword ptr ss:[ebp+4034C7]        ; GlobalAlloc释放掉内存
004233DF    96              xchg    eax, esi
004233E0    50              push    eax
004233E1    57              push    edi
004233E2    FF95 F4344000   call    dword ptr ss:[ebp+4034F4]        ; CloseHandle关闭文件句柄
004233E8    58              pop     eax
004233E9    8B85 E82F4000   mov     eax, dword ptr ss:[ebp+402FE8]
004233EF    BB 01000000     mov     ebx, 1
004233F4    E8 08000000     call    _ExeStea.00423401                ; 解压原程序各个区段
004233F9    8D85 262C4000   lea     eax, dword ptr ss:[ebp+402C26]
004233FF    50              push    eax
00423400    C3              retn
开始解压原程序的各个区段。跟进CALL 00423401看看解压过程
00423401    8BF8            mov     edi, eax
00423403    037F 3C         add     edi, dword ptr ds:[edi+3C]       ; 获取PE_NT_HEADER
00423406    8BF7            mov     esi, edi
00423408    81C6 F8000000   add     esi, 0F8                         ; 获取一个区段表
0042340E    33D2            xor     edx, edx                         ; 对比区段名
00423410    813E 72737263   cmp     dword ptr ds:[esi], 63727372     ; 判断该区段是否需要解压
00423416    75 05           jnz     short _ExeStea.0042341D
00423418    E9 C5000000     jmp     _ExeStea.004234E2
0042341D    813E 2E727372   cmp     dword ptr ds:[esi], 7273722E
00423423    75 05           jnz     short _ExeStea.0042342A
00423425    E9 B8000000     jmp     _ExeStea.004234E2
0042342A    813E 2E726573   cmp     dword ptr ds:[esi], 7365722E
00423430    75 05           jnz     short _ExeStea.00423437
00423432    E9 AB000000     jmp     _ExeStea.004234E2
00423437    813E 2E656461   cmp     dword ptr ds:[esi], 6164652E
0042343D    75 05           jnz     short _ExeStea.00423444
0042343F    E9 9E000000     jmp     _ExeStea.004234E2
00423444    813E 72656C6F   cmp     dword ptr ds:[esi], 6F6C6572
0042344A    75 05           jnz     short _ExeStea.00423451
0042344C    E9 91000000     jmp     _ExeStea.004234E2
00423451    813E 2E72656C   cmp     dword ptr ds:[esi], 6C65722E
00423457    75 05           jnz     short _ExeStea.0042345E
00423459    E9 84000000     jmp     _ExeStea.004234E2
0042345E    813E 6E6F6573   cmp     dword ptr ds:[esi], 73656F6E
00423464    75 02           jnz     short _ExeStea.00423468
00423466    EB 7A           jmp     short _ExeStea.004234E2
00423468    813E 45786553   cmp     dword ptr ds:[esi], 53657845
0042346E    75 02           jnz     short _ExeStea.00423472
00423470    EB 70           jmp     short _ExeStea.004234E2
00423472    813E 2E656461   cmp     dword ptr ds:[esi], 6164652E
00423478    75 02           jnz     short _ExeStea.0042347C
0042347A    EB 66           jmp     short _ExeStea.004234E2
0042347C    837E 14 00      cmp     dword ptr ds:[esi+14], 0         ; 区段的文件偏移
00423480    74 06           je      short _ExeStea.00423488
00423482    837E 10 00      cmp     dword ptr ds:[esi+10], 0         ; 区段在文件中长度
00423486    75 02           jnz     short _ExeStea.0042348A
00423488    EB 58           jmp     short _ExeStea.004234E2
0042348A    60              pushad
0042348B    8B4E 10         mov     ecx, dword ptr ds:[esi+10]       ; 取区段的在文件中的大小
0042348E    0BDB            or      ebx, ebx
00423490    75 0C           jnz     short _ExeStea.0042349E
00423492    8B76 14         mov     esi, dword ptr ds:[esi+14]
00423495    03F0            add     esi, eax
00423497    E8 B0F8FFFF     call    _ExeStea.00422D4C
0042349C    EB 0A           jmp     short _ExeStea.004234A8
0042349E    8B76 0C         mov     esi, dword ptr ds:[esi+C]        ; 区段的RVA
004234A1    03F0            add     esi, eax                         ; 获取区段的基址VA
004234A3    E8 02000000     call    _ExeStea.004234AA                ; 解压原程序各个区段
004234A8    EB 37           jmp     short _ExeStea.004234E1
004234AA    8BFE            mov     edi, esi
004234AC    AC              lods    byte ptr ds:[esi]
004234AD    F9              stc
004234AE    2C B8           sub     al, 0B8
004234B0    F9              stc
004234B1    F9              stc
004234B2    F9              stc
004234B3    04 47           add     al, 47
004234B5    02C1            add     al, cl
004234B7    34 90           xor     al, 90
004234B9    F8              clc
004234BA    90              nop
004234BB    F8              clc
004234BC    F8              clc
004234BD    04 50           add     al, 50
004234BF    2C ED           sub     al, 0ED
004234C1    F8              clc
004234C2    2AC1            sub     al, cl
004234C4    F8              clc
004234C5    F9              stc
004234C6    2AC1            sub     al, cl
004234C8    F9              stc
004234C9    04 4D           add     al, 4D
004234CB    F8              clc
004234CC    F8              clc
004234CD    2AC1            sub     al, cl
004234CF    04 D4           add     al, 0D4
004234D1    F9              stc
004234D2    2C B8           sub     al, 0B8
004234D4    F9              stc
004234D5    F9              stc
004234D6    F9              stc
004234D7    04 47           add     al, 47
004234D9    02C1            add     al, cl
004234DB    34 90           xor     al, 90
004234DD    AA              stos    byte ptr es:[edi]
004234DE  ^ E2 CC           loopd   short _ExeStea.004234AC          ; 循环解压原程序的一个区段
004234E0    C3              retn
004234E1    61              popad
004234E2    83C6 28         add     esi, 28
004234E5    42              inc     edx
004234E6    66:3B57 06      cmp     dx, word ptr ds:[edi+6]          ; 是否所有区段都处理?
004234EA  ^ 0F85 20FFFFFF   jnz     _ExeStea.00423410                ; 继续处理下一个区段
004234F0    C3              retn
读取PE头来获取区段的属性,逐个区段解压。继续走
004234F1    8B9D E82F4000   mov     ebx, dword ptr ss:[ebp+402FE8]   ; _ExeStea.00400000
004234F7    90              nop
004234F8    039D EC2F4000   add     ebx, dword ptr ss:[ebp+402FEC]   ; 获取OEP
004234FE    C1CB 07         ror     ebx, 7                           ; 将OEP变形保存
00423501    895C24 10       mov     dword ptr ss:[esp+10], ebx
00423505    8D9D 1D2F4000   lea     ebx, dword ptr ss:[ebp+402F1D]
0042350B    895C24 1C       mov     dword ptr ss:[esp+1C], ebx
0042350F    8BBD E82F4000   mov     edi, dword ptr ss:[ebp+402FE8]
00423515    037F 3C         add     edi, dword ptr ds:[edi+3C]
00423518    8B9F C0000000   mov     ebx, dword ptr ds:[edi+C0]       ; 获取TLS
0042351E    83FB 00         cmp     ebx, 0
00423521    74 0F           je      short _ExeStea.00423532
00423523    039D E82F4000   add     ebx, dword ptr ss:[ebp+402FE8]
00423529    8B43 08         mov     eax, dword ptr ds:[ebx+8]
0042352C    C700 00000000   mov     dword ptr ds:[eax], 0
00423532    8B85 F42F4000   mov     eax, dword ptr ss:[ebp+402FF4]   ; 读取校验和
00423538    0BC0            or      eax, eax
0042353A    74 0D           je      short _ExeStea.00423549
0042353C    3B85 22354000   cmp     eax, dword ptr ss:[ebp+403522]   ; 比较校验和,判断文件是否被修改
00423542    74 05           je      short _ExeStea.00423549
00423544    E9 AF010000     jmp     _ExeStea.004236F8
00423549    8DB5 00304000   lea     esi, dword ptr ss:[ebp+403000]   ; 获取变形的输入表
0042354F    F785 F02F4000 2>test    dword ptr ss:[ebp+402FF0], 20
00423559    74 49           je      short _ExeStea.004235A4
0042355B    56              push    esi
0042355C    8DBD 26354000   lea     edi, dword ptr ss:[ebp+403526]
00423562    33C9            xor     ecx, ecx
00423564    EB 17           jmp     short _ExeStea.0042357D
00423566    8B56 04         mov     edx, dword ptr ds:[esi+4]        ; 获取该IID的IAT偏移
00423569    0395 E82F4000   add     edx, dword ptr ss:[ebp+402FE8]   ; 加上基址,得到IAT的RVA
0042356F    EB 04           jmp     short _ExeStea.00423575
00423571    41              inc     ecx
00423572    83C2 04         add     edx, 4
00423575    833A 00         cmp     dword ptr ds:[edx], 0            ; 计算IAT数组的元素个数
00423578  ^ 75 F7           jnz     short _ExeStea.00423571
0042357A    83C6 0C         add     esi, 0C                          ; 下一个IID结构(每个IID长度为C)
0042357D    837E 04 00      cmp     dword ptr ds:[esi+4], 0
00423581  ^ 75 E3           jnz     short _ExeStea.00423566          ; 是否所有Dll已经处理完
00423583    33D2            xor     edx, edx
00423585    B8 05000000     mov     eax, 5                           ; 所有IAT数组的元素总个数*5
0042358A    F7E1            mul     ecx
0042358C    50              push    eax
0042358D    6A 00           push    0
0042358F    FF95 B8344000   call    dword ptr ss:[ebp+4034B8]        ; GlobalAlloc分配相应大小的空间
00423595    0BC0            or      eax, eax
00423597    75 05           jnz     short _ExeStea.0042359E
00423599    83C4 04         add     esp, 4
0042359C    61              popad
0042359D    C3              retn
0042359E    8907            mov     dword ptr ds:[edi], eax
004235A0    8947 04         mov     dword ptr ds:[edi+4], eax
004235A3    5E              pop     esi
004235A4    E9 42010000     jmp     _ExeStea.004236EB
004235A9    8B1E            mov     ebx, dword ptr ds:[esi]          ; 获取加密的Dll名字的字符串
004235AB    039D E82F4000   add     ebx, dword ptr ss:[ebp+402FE8]
004235B1    8BC3            mov     eax, ebx
004235B3    E8 08000000     call    _ExeStea.004235C0                ; 解密导入Dll名字的字符串
004235B8    8D85 082D4000   lea     eax, dword ptr ss:[ebp+402D08]
004235BE    50              push    eax
004235BF    C3              retn
004235C0    56              push    esi
004235C1    57              push    edi
004235C2    8BF0            mov     esi, eax
004235C4    8BF8            mov     edi, eax
004235C6    AC              lods    byte ptr ds:[esi]
004235C7    C0C8 04         ror     al, 4
004235CA    AA              stos    byte ptr es:[edi]
004235CB    803F 00         cmp     byte ptr ds:[edi], 0             ; 清除字符串
004235CE  ^ 75 F6           jnz     short _ExeStea.004235C6
004235D0    5F              pop     edi
004235D1    5E              pop     esi
004235D2    C3              retn
004235D3    53              push    ebx
004235D4    FF95 44344000   call    dword ptr ss:[ebp+403444]        ; Loadlibrary加载导入的Dll
004235DA    85C0            test    eax, eax
004235DC    0F84 16010000   je      _ExeStea.004236F8
004235E2    50              push    eax                              ; 保存加载Dll的基址
004235E3    F785 F02F4000 0>test    dword ptr ss:[ebp+402FF0], 4
004235ED    74 0E           je      short _ExeStea.004235FD
004235EF    8D85 322D4000   lea     eax, dword ptr ss:[ebp+402D32]
004235F5    50              push    eax                              ; 压入返回地址
004235F6    8BC3            mov     eax, ebx
004235F8    E9 48020000     jmp     _ExeStea.00423845                ; 清空字符串函数,是一个call,改成jmp了
004235FD    5B              pop     ebx                              ; 取出Dll的基址
004235FE    8B4E 08         mov     ecx, dword ptr ds:[esi+8]
00423601    0BC9            or      ecx, ecx
00423603    75 03           jnz     short _ExeStea.00423608
00423605    8B4E 04         mov     ecx, dword ptr ds:[esi+4]
00423608    038D E82F4000   add     ecx, dword ptr ss:[ebp+402FE8]   ; 获取API名字字符串
0042360E    8B56 04         mov     edx, dword ptr ds:[esi+4]
00423611    0395 E82F4000   add     edx, dword ptr ss:[ebp+402FE8]   ; 获取IAT地址
00423617    E9 C3000000     jmp     _ExeStea.004236DF
0042361C    F701 00000080   test    dword ptr ds:[ecx], 80000000     ; 是否为序号输入
00423622    75 4B           jnz     short _ExeStea.0042366F
00423624    8B01            mov     eax, dword ptr ds:[ecx]
00423626    83C0 02         add     eax, 2
00423629    0385 E82F4000   add     eax, dword ptr ss:[ebp+402FE8]
0042362F    50              push    eax
00423630    E8 8BFFFFFF     call    _ExeStea.004235C0                ; 解密API的字符串
00423635    58              pop     eax
00423636    8BF8            mov     edi, eax
00423638    52              push    edx
00423639    51              push    ecx
0042363A    50              push    eax
0042363B    53              push    ebx
0042363C    FF95 48344000   call    dword ptr ss:[ebp+403448]        ; GetProcAddress获取API地址
00423642    0BC0            or      eax, eax
00423644    75 07           jnz     short _ExeStea.0042364D
00423646    59              pop     ecx
00423647    5A              pop     edx
00423648    E9 AB000000     jmp     _ExeStea.004236F8
0042364D    59              pop     ecx
0042364E    5A              pop     edx
0042364F    60              pushad
00423650    F785 F02F4000 0>test    dword ptr ss:[ebp+402FF0], 4
0042365A    74 0E           je      short _ExeStea.0042366A
0042365C    8D85 9F2D4000   lea     eax, dword ptr ss:[ebp+402D9F]   ; 需要清空的字符串
00423662    50              push    eax                              ; 压入返回地址
00423663    8BC7            mov     eax, edi
00423665    E9 DB010000     jmp     _ExeStea.00423845                ; call清空字符串,伪装成jmp了
0042366A    61              popad
0042366B    8902            mov     dword ptr ds:[edx], eax          ; 保存API地址到IAT
0042366D    EB 19           jmp     short _ExeStea.00423688
0042366F    52              push    edx
00423670    51              push    ecx
00423671    8B01            mov     eax, dword ptr ds:[ecx]
00423673    2D 00000080     sub     eax, 80000000
00423678    50              push    eax
00423679    53              push    ebx
0042367A    FF95 48344000   call    dword ptr ss:[ebp+403448]
00423680    85C0            test    eax, eax
00423682    74 74           je      short _ExeStea.004236F8
00423684    59              pop     ecx
00423685    5A              pop     edx
00423686    8902            mov     dword ptr ds:[edx], eax
00423688    F785 F02F4000 2>test    dword ptr ss:[ebp+402FF0], 20
00423692    74 45           je      short _ExeStea.004236D9
00423694    83BD FC2F4000 0>cmp     dword ptr ss:[ebp+402FFC], 0
0042369B    74 14           je      short _ExeStea.004236B1
0042369D    81FB 00000070   cmp     ebx, 70000000
004236A3    72 08           jb      short _ExeStea.004236AD
004236A5    81FB FFFFFF77   cmp     ebx, 77FFFFFF
004236AB    76 0E           jbe     short _ExeStea.004236BB
004236AD    EB 2A           jmp     short _ExeStea.004236D9
004236AF    EB 0A           jmp     short _ExeStea.004236BB
004236B1    81FB 00000080   cmp     ebx, 80000000
004236B7    73 02           jnb     short _ExeStea.004236BB
004236B9    EB 1E           jmp     short _ExeStea.004236D9
004236BB    57              push    edi
004236BC    56              push    esi
004236BD    8DBD 26354000   lea     edi, dword ptr ss:[ebp+403526]
004236C3    8B77 04         mov     esi, dword ptr ds:[edi+4]
004236C6    8932            mov     dword ptr ds:[edx], esi          ; 将IAT里地址改写分配的内存地址
004236C8    2BC6            sub     eax, esi
004236CA    83E8 05         sub     eax, 5
004236CD    C606 E9         mov     byte ptr ds:[esi], 0E9           ; 修改分配内存中的指令为jmp APIXX
004236D0    8946 01         mov     dword ptr ds:[esi+1], eax
004236D3    8347 04 05      add     dword ptr ds:[edi+4], 5          ; 下一个填充到IAT的地址
004236D7    5E              pop     esi
004236D8    5F              pop     edi
004236D9    83C1 04         add     ecx, 4                           ; 下一个API名字字符串
004236DC    83C2 04         add     edx, 4                           ; IAT数组下一个元素
004236DF    8339 00         cmp     dword ptr ds:[ecx], 0
004236E2  ^ 0F85 34FFFFFF   jnz     _ExeStea.0042361C                ; 继续下一个API的处理
004236E8    83C6 0C         add     esi, 0C
004236EB    837E 04 00      cmp     dword ptr ds:[esi+4], 0
004236EF  ^ 0F85 B4FEFFFF   jnz     _ExeStea.004235A9                ; 继续下一个Dll的处理
004236F5    33C0            xor     eax, eax
004236F7    40              inc     eax
004236F8    83F8 01         cmp     eax, 1
004236FB    74 02           je      short _ExeStea.004236FF
开始填充IAT了,首先获取变形的输入表,然后填充IAT,然后再将IAT简单加密。
变形的IAT的 IID结构是这样的
004238CB  00006630        Offset_DllName
004238CF  00006000        Offset_FirstThunk
004238D3  0000651C        Offset_OriginalFirstThunk
一个IID存放3个偏移
004238D7  000066A8        Offset_DllName
004238DB  000060C4        Offset_FirstThunk
004238DF  000065E0        Offset_OriginalFirstThunk
但是,DllName,OriginalFirstThunk中的字符串全部都是加密的。
在使用LoadLibrary和GetProcAddress的时候先解密出字符串,然后再调用函数,调用完成后清除字符串
填充IAT的过程如下:
首先GlobalAlloc分配一块内存地址
1.Loadlibrary加载导入的Dll
2.循环使用GetProcAddress获取API地址
3.填充API地址到IAT数组
4.将IAT中的API地址改成分配内存的中地址
5.在上述内存地址处写入  jmp  APIXX  的形式的指令
最后在IAT就是如下形式:
00406000  00253058
00406004  0025305D
00406008  00253062
0040600C  00253067
00406010  0025306C
00406014  00253071
而IAT中的地址的内容就是
00253058  - E9 59E2F575     jmp     kernel32.lstrcatA
0025305D  - E9 A9DBF775     jmp     kernel32.GetVolumeInformationA
00253062  - E9 DA64F775     jmp     kernel32.lstrlenA
00253067  - E9 E91EF775     jmp     kernel32.CompareStringW
0025306C  - E9 1260F775     jmp     kernel32.CompareStringA
00253071  - E9 EC2DF775     jmp     kernel32.GetStringTypeW
就是将IAT进行了重定向,这样便不能 一目了然IAT中的API地址
实现了最简单的IAT加密吧算是。
IAT填充完毕之后,开始检测调试和内存文件校验
00423723    8D85 95274000   lea     eax, dword ptr ss:[ebp+402795]
00423729    B9 06070000     mov     ecx, 706
0042372E    EB 01           jmp     short _ExeStea.00423731
00423730  - E9 E88EFCFF     jmp     003EC61D
00423735    FFEB            jmp     far ebx                          ; 非法使用寄存器
00423737    01C7            add     edi, eax
00423739    8B9D F82F4000   mov     ebx, dword ptr ss:[ebp+402FF8]
0042373F    33C3            xor     eax, ebx
00423741    74 08           je      short _ExeStea.0042374B
00423743    EB 01           jmp     short _ExeStea.00423746
00423745    2C 61           sub     al, 61
00423747    EB 01           jmp     short _ExeStea.0042374A
00423749    E8 C38DBD9B     call    9BFFC511
0042374E    2E:40           inc     eax
00423750    008B F7B9DF00   add     byte ptr ds:[ebx+DFB9F7], cl
00423756    0000            add     byte ptr ds:[eax], al
00423758    33DB            xor     ebx, ebx
花指令还是不少,慢慢跟
00423731    E8 8EFCFFFF     call    _ExeStea.004233C4                ; 求壳入口点之后0x706字节的校验和
00423736    EB 01           jmp     short _ExeStea.00423739
00423738    C7              ???                                      ; 未知命令
00423739    8B9D F82F4000   mov     ebx, dword ptr ss:[ebp+402FF8]
0042373F    33C3            xor     eax, ebx                             ; 判断是否壳代码是否被修改
0042373F    33C3            xor     eax, ebx                         ; 判断是否壳代码是否被修改
00423741    74 08           je      short _ExeStea.0042374B
00423743    EB 01           jmp     short _ExeStea.00423746
再次求壳代码的校验和,然后判断和先计算的校验和是否相等来判断壳代码是否被修改,接着走
0042374B    8DBD 9B2E4000   lea     edi, dword ptr ss:[ebp+402E9B]
00423751    8BF7            mov     esi, edi
00423753    B9 DF000000     mov     ecx, 0DF
00423758    33DB            xor     ebx, ebx
0042375A    AC              lods    byte ptr ds:[esi]
0042375B    34 77           xor     al, 77
0042375D    2AC3            sub     al, bl
0042375F    C0C0 02         rol     al, 2
00423762    AA              stos    byte ptr es:[edi]
00423763    43              inc     ebx
00423764  ^ E2 F4           loopd   short _ExeStea.0042375A          ; 循环解压下面一段代码
00423766    14 15           adc     al, 15                           
00423768    37              aaa
00423769    67:6372 6D      arpl    word ptr ss:[bp+si+6D], si
又是解压一段代码,  在00423766  F4  
00423766    8D85 F8344000   lea     eax, dword ptr ss:[ebp+4034F8]   ; 指向IsDebuggerPresent字符串
0042376C    50              push    eax
0042376D    FFB5 59344000   push    dword ptr ss:[ebp+403459]
00423773    FF95 48344000   call    dword ptr ss:[ebp+403448]        ; GetPorcAddress获取IsDebuggerPresent的地址
00423779    0BC0            or      eax, eax
0042377B    74 08           je      short _ExeStea.00423785
0042377D    FFD0            call    eax                              ; 调用IsDebuggerPresent检测调试器
0042377F    0BC0            or      eax, eax
00423781    74 02           je      short _ExeStea.00423785          ; 没有发现调试器则跳走
00423783    61              popad
00423784    C3              retn                                     ; 发现调试器返回到错误的地址造成程序异常结束
00423785    F785 F02F4000 0>test    dword ptr ss:[ebp+402FF0], 1
0042378F    74 4F           je      short _ExeStea.004237E0
通过IsDebuggerPresent检测调试器,发现调试器则跳到错误的地址使程序异常结束
00423785    F785 F02F4000 0>test    dword ptr ss:[ebp+402FF0], 1
0042378F    74 4F           je      short _ExeStea.004237E0
00423791    8DB5 38344000   lea     esi, dword ptr ss:[ebp+403438]
00423797    8D85 F02E4000   lea     eax, dword ptr ss:[ebp+402EF0]
0042379D    8946 08         mov     dword ptr ds:[esi+8], eax
004237A0    33DB            xor     ebx, ebx
004237A2    8D85 B72F4000   lea     eax, dword ptr ss:[ebp+402FB7]
004237A8    50              push    eax                              ; 异常处理Handle
004237A9    64:FF33         push    dword ptr fs:[ebx]
004237AC    64:8923         mov     dword ptr fs:[ebx], esp
004237AF    8BFD            mov     edi, ebp
004237B1    B8 00440000     mov     eax, 4400
004237B6    EB 01           jmp     short _ExeStea.004237B9
004237B8    C7              ???                                      ; 花指令
004237B9    CD 68           int     68                               ; 产生异常
004237BB    33DB            xor     ebx, ebx
004237BD    64:8F03         pop     dword ptr fs:[ebx]
004237C0    83C4 04         add     esp, 4
004237C3    66:81FF 9712    cmp     di, 1297
又是一个异常通过 INT68触发,异常Handle什么也没做,只是修改EIP为异常的下一条指令跳过异常
0042381A    32C0            xor     al, al
0042381C    8DBD 95274000   lea     edi, dword ptr ss:[ebp+402795]
00423822    B9 88070000     mov     ecx, 788
00423827    AA              stos    byte ptr es:[edi]
00423828  ^ E2 FD           loopd   short _ExeStea.00423827          ; 清除壳代码
0042382A    8DBD 7A2F4000   lea     edi, dword ptr ss:[ebp+402F7A]
00423830    B9 90050000     mov     ecx, 590
00423835    AA              stos    byte ptr es:[edi]
00423836  ^ E2 FD           loopd   short _ExeStea.00423835          ; 清除壳代码
00423838    61              popad
00423839    50              push    eax                              ; 异常Handle
0042383A    33C0            xor     eax, eax
0042383C    64:FF30         push    dword ptr fs:[eax]
0042383F    64:8920         mov     dword ptr fs:[eax], esp
00423842    EB 01           jmp     short _ExeStea.00423845          ; 跳到内容为全0的地址去执行触发异常
最后清除壳代码,再次引发异常来修改EIP为OEP
异常Handle如下
004237EB    57              push    edi
004237EC    8B45 10         mov     eax, dword ptr ss:[ebp+10]
004237EF    8BB8 C4000000   mov     edi, dword ptr ds:[eax+C4]       ; 获取esp
004237F5    FF37            push    dword ptr ds:[edi]
004237F7    33FF            xor     edi, edi
004237F9    64:8F07         pop     dword ptr fs:[edi]               ; 恢复异常链
004237FC    8380 C4000000 0>add     dword ptr ds:[eax+C4], 8         ; 恢复堆栈
00423803    8BB8 A4000000   mov     edi, dword ptr ds:[eax+A4]
00423809    C1C7 07         rol     edi, 7                           ; 还原变形的OEP
0042380C    89B8 B8000000   mov     dword ptr ds:[eax+B8], edi       ; 更改EIP到OEP
00423812    B8 00000000     mov     eax, 0
00423817    5F              pop     edi
00423818    C9              leave
00423819    C3              retn
恢复了异常链并且修改EIP到OEP
总结:
加壳之后程序大小没有很大变化,只是增加了一个壳的区段,因为壳没有对原程序进行压缩,而
只是对原程序进行了一些xor和sar等运算而已
壳的运行流程:
1.解压出壳的核心代码和数据
2.求出壳代码和文件的校验和
3.解压原程序
4.校验文件是否被修改
5.填充并加密IAT
6.通过IsDebuggerPresent检测调试
7.校验壳代码是否被修改
8.清除壳的代码和数据
9.通过异常修改EIP到OEP
最基本的加密壳就分析完了,脱壳也非常简单,DUMP后修复下IAT就可以了

已经有(0)位网友发表了评论,你也评一评吧!
原创文章如转载,请注明:转载自Eddy Blog
原文地址:http://www.rrgod.com/decryption/371.html     欢迎订阅Eddy Blog

关于 ExeStealth  的相关文章

记住我的信息,下次不用再输入 欢迎给Eddy Blog留言