全壳解剖二(Yoda 1.2)

搁置了很久的文章了。。最近在逆一个压缩壳,忽然又想起了这篇。。




目标程序:用Yoda1.2加壳的asm程序

目的:    全过程分析该程序解压的过程

时间:    最近时间比较紧,每天分析100行左右吧

已分析: 解压壳代码+检测SoftIce+获取壳所需函数

-------------------7月22日-------------------

因为此壳在数月前我已经完全看过代码,所以以这个开始逆壳旅程再好不过了,如果遇到不懂的直接看源码就明白了

说下我写的东西的格式:在一段代码之前可能会说一些跟代码意思没直接关系的话,代码之后会解释代码的意思
每一部分代码会有明显空行。


                
OD载入程序

00404060 a>  60                      pushad
00404061     E8 00000000             call asm.00404066
00404066     5D                      pop ebp
00404067     81ED F31D4000           sub ebp,asm.00401DF3               
正确找到壳数据起始位置,这个东西一般在加壳,感染PE时都会用到,详细参考:
http://blog.csdn.net/u010887709/article/details/9069511



接下来的代码单步走起来乱糟糟的,经常有很多无用的jmp,把花指令nop掉就清楚多了,方法是把jmp到的地址的前一个字节nop掉
例如 Jmp 401001,那你就把401000给nop掉,清楚的代码如下:
0040406D     B9 7B090000             mov ecx,97B
00404072     8DBD 3B1E4000           lea edi,dword ptr ss:[ebp+401E3B]
00404078     8BF7                    mov esi,edi
0040407A     AC                      lods byte ptr ds:[esi]
0040407B     C0C0 18                 rol al,18
0040407E     90                      nop
0040407F     02C1                    add al,cl
00404081     2AC1                    sub al,cl
00404083     90                      nop
00404084     02C1                    add al,cl
00404086     34 6C                   xor al,6C
00404088     EB 01                   jmp short asm.0040408B
0040408A     90                      nop
0040408B     C0C0 58                 rol al,58
0040408E     90                      nop
0040408F     2C 8C                   sub al,8C
00404091     2AC1                    sub al,cl
00404093     2C D3                   sub al,0D3
00404095     EB 01                   jmp short asm.00404098
00404097     90                      nop
00404098     2AC1                    sub al,cl
0040409A     FEC8                    dec al
0040409C     2C 9A                   sub al,9A
0040409E     C0C8 E9                 ror al,0E9
004040A1     C0C0 BD                 rol al,0BD
004040A4     04 40                   add al,40
004040A6     EB 01                   jmp short asm.004040A9
004040A8     90                      nop
004040A9     34 22                   xor al,22
004040AB     AA                      stos byte ptr es:[edi]
004040AC   ^ E2 CC                   loopd short asm.0040407A
观察0040407A的esi值和004040AB处的edi(等于4040AE,也就是loopd的下一行)值,以及结合所有代码可以看出是在解密壳的代码
现在可以估计这个壳是先用一小段代码把壳代码解密,再用壳代码解密原程序




004040AE    8B4424 20       mov     eax, dword ptr [esp+20]
004040B2    40              inc     eax
004040B3    78 0A           js      short 004040BF
004040B5    C785 78254000 0>mov     dword ptr [ebp+402578], 1
[esp+20]存放着一个kernel32库的地址,如果这个地址+1之后是负数则当前系统不是NT系列(不必深究)
如果不是NT系列则跳过下一行语句


004040BF    8D85 ED1D4000   lea     eax, dword ptr [ebp+401DED]      ; 壳的入口
004040C5    B9 2A060000     mov     ecx, 62A                         ; 大小
004040CA    E8 41020000     call    00404310
{
00404310    8BF8            mov     edi, eax
00404312    33C0            xor     eax, eax
00404314    33DB            xor     ebx, ebx
00404316    33D2            xor     edx, edx
00404318    8A07            mov     al, byte ptr [edi]
0040431A    F7E2            mul     edx
0040431C    03D8            add     ebx, eax
0040431E    42              inc     edx
0040431F    47              inc     edi
00404320  ^ E2 F6           loopd   short 00404318
00404322    93              xchg    eax, ebx
00404323    C3              retn
}
004040CF    8985 74254000   mov     dword ptr [ebp+402574], eax
将入口处的一些代码算成一个数,放在[ebp+402574],所谓的校验和吧






004040D5    8B85 6C254000   mov     eax, dword ptr [ebp+40256C]
004040DB    83E0 01         and     eax, 1
004040DE    74 40           je      short 00404120
004040E0    8DB5 E4264000   lea     esi, dword ptr [ebp+4026E4]
004040E6    8D85 9A1E4000   lea     eax, dword ptr [ebp+401E9A]
004040EC    8946 08         mov     dword ptr [esi+8], eax
004040EF    8BFD            mov     edi, ebp                         ; 保存下ebp以便还原
004040F1    8D85 02254000   lea     eax, dword ptr [ebp+402502]      ; SEH 处理程序
004040F7    33DB            xor     ebx, ebx
004040F9    50              push    eax
004040FA    64:FF33         push    dword ptr fs:[ebx]
004040FD    64:8923         mov     dword ptr fs:[ebx], esp
00404100    BD 4B484342     mov     ebp, 4243484B
00404105    66:B8 0400      mov     ax, 4
00404109    EB 01           jmp     short 0040410C
0040410B    90              nop                                      ; 本来是花指令
0040410C    CC              int3
0040410D    8BEF            mov     ebp, edi
0040410F    33DB            xor     ebx, ebx
00404111    64:8F03         pop     dword ptr fs:[ebx]
00404114    83C4 04         add     esp, 4
00404117    3C 04           cmp     al, 4
00404119    74 05           je      short 00404120                   ; 该指令后有5条花指令
开头三行在判断应不应该执行下面的代码(其实下面的代码如果真正自己去逆是逆不出什么意思的),如果你选了检测Softice的话
下面的代码就会执行,大体就是触发一个异常,在异常里面将eax置为4,出去异常之后(返回到异常指令的下一条指令)如果判断eax还是4的话就证明没有SoftIce
SoftIce检测原理详细参考:
http://blog.csdn.net/u010887709/article/details/9156285




00404120    8B85 64254000   mov     eax, dword ptr [ebp+402564]
00404126    0340 3C         add     eax, dword ptr [eax+3C]
00404129    05 80000000     add     eax, 80                          ; 定位到数据目录的输入表项
0040412E    8B08            mov     ecx, dword ptr [eax]
00404130    038D 64254000   add     ecx, dword ptr [ebp+402564]      ; 输入表的RVA+基址
00404136    83C1 10         add     ecx, 10                          ; 跳过IID结构的开头16字节,来到FirstThunk
00404139    8B01            mov     eax, dword ptr [ecx]
0040413B    0385 64254000   add     eax, dword ptr [ebp+402564]
00404141    8B18            mov     ebx, dword ptr [eax]
00404143    899D F0264000   mov     dword ptr [ebp+4026F0], ebx      ; 得到LoadLibrary地址
00404149    83C0 04         add     eax, 4                           ; 下一个ImageThunk,就是GetProcAddress咯
0040414C    8B18            mov     ebx, dword ptr [eax]
0040414E    899D F4264000   mov     dword ptr [ebp+4026F4], ebx      ; 得到LoadLibrary地址
00404154    8D85 F8264000   lea     eax, dword ptr [ebp+4026F8]
0040415A    50              push    eax
0040415B    FF95 F0264000   call    dword ptr [ebp+4026F0]           ; kernel32.LoadLibraryA
00404161    8BF0            mov     esi, eax
00404163    8985 05274000   mov     dword ptr [ebp+402705], eax
00404169    8D85 09274000   lea     eax, dword ptr [ebp+402709]
0040416F    E8 96000000     call    0040420A
00404174    8985 1A274000   mov     dword ptr [ebp+40271A], eax
0040417A    8D85 1E274000   lea     eax, dword ptr [ebp+40271E]
00404180    E8 85000000     call    0040420A
00404185    8985 2D274000   mov     dword ptr [ebp+40272D], eax
0040418B    8D85 31274000   lea     eax, dword ptr [ebp+402731]
00404191    E8 74000000     call    0040420A
00404196    8985 44274000   mov     dword ptr [ebp+402744], eax
0040419C    8D85 48274000   lea     eax, dword ptr [ebp+402748]
004041A2    E8 63000000     call    0040420A
004041A7    8985 54274000   mov     dword ptr [ebp+402754], eax
004041AD    8D85 58274000   lea     eax, dword ptr [ebp+402758]
004041B3    E8 52000000     call    0040420A
004041B8    8985 64274000   mov     dword ptr [ebp+402764], eax
004041BE    8D85 68274000   lea     eax, dword ptr [ebp+402768]
004041C4    E8 41000000     call    0040420A
004041C9    8985 73274000   mov     dword ptr [ebp+402773], eax
004041CF    8D85 77274000   lea     eax, dword ptr [ebp+402777]
004041D5    E8 30000000     call    0040420A
004041DA    8985 80274000   mov     dword ptr [ebp+402780], eax
004041E0    8D85 84274000   lea     eax, dword ptr [ebp+402784]
004041E6    E8 1F000000     call    0040420A
004041EB    8985 90274000   mov     dword ptr [ebp+402790], eax
004041F1    8D85 94274000   lea     eax, dword ptr [ebp+402794]
004041F7    E8 0E000000     call    0040420A
004041FC    8985 A0274000   mov     dword ptr [ebp+4027A0], eax
00404202    8D85 A01F4000   lea     eax, dword ptr [ebp+401FA0]
00404208    50              push    eax
00404209    C3              retn
将输入表中的函数LoadLibrary和GetProcAddress拿出来,然后再利用这两个函数获取更多壳需要用到的函数
这些函数的名字你在OD可以看到。在最后push了一个地址(eax)然后retn,相当于直接跳到这个地址了



接着跳到的这个地址来看:


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值