└文章标题┐:Obsidium 1.0.0.69标准方式加壳 ->脱壳修复
└破文作者┐:大菜一号
└破解对象┐:hello world
└下载地址┐:附件
└对象大小┐:不知
└加壳方式┐:Obsidium 1.0.0
└保护方式┐:Obsidium 1.0.0
└编写语言┐:vc
└使用工具┐:od,REC
└破解平台┐:xp
└破解声明┐:`
----------------------------------------------------------------------------------
└破解过程┐:
闲来无事,脱个壳!
突然发现,脱壳也挺好玩的,呵~去看雪主页上看了看,选择了Obsidium这个壳,因为介绍上写着“强度中等” - - 
还是一个自己写的hello world,本来不打算拿它来加壳的,不过这款壳的兼容好像有点问题,拿一些其他工具进行加壳,都无法运行!

好了,加壳之后,正常运行,不过比hello world多了一个对话框,因为这款壳我没有注册!- -

用od载入,还是老方法,用最后一次异常找oep!忽略掉除了“非法访问内存异常”之外的所有异常,f9运行!

.....

程序13次异常之后运行,ctrl+f2重新载入,到达第12次异常时,堆栈说:

代码:

0012FE54   009053D9  SE处理程序  <-脱壳者,请去9053d9这个地址上下断
shift+f9运行,断这上面那句了,f2取消断点(壳有自校验)
要进行最后一次让程序运行的异常,则我们alt+m在第一块的code节上下断,f9运行,来到这种地方
代码:

00401046      FF            db      FF
00401047      15            db      15
00401048      14            db      14
00401049      50            db      50                               ;  CHAR 'P'
0040104A      40            db      40                               ;  CHAR '@'
0040104B      00            db      00
0040104C      33            db      33                               ;  CHAR '3'
0040104D      D2            db      D2

ctrl+a让od重新分析一下程序,往上翻看,可以看到:
代码:

00401007   .  68 30 60 40 0>ascii   "h0`@",0
0040100C   .  6A 00         push    0
0040100E   .  FF15 9C504000 call    dword ptr [40509C]
00401014   .  33C0          xor     eax, eax
00401016   .  EB FF         jmp     short 00401017
00401018   .  15 B0A04000   adc     eax, 0040A0B0
0040101D   .  C2 1000       retn    10
00401020      E1            db      E1                  <-这里开始的Stolen Code
00401021      8B            db      8B
00401022      69            db      69                               ;  CHAR 'i'
00401023      C7            db      C7
00401024      FD            db      FD
00401025      56            db      56                               ;  CHAR 'V'
00401026      03            db      03
00401027      89            db      89
00401028      CF            db      CF
00401029      DB            db      DB
0040102A      83            db      83
0040102B      E2            db      E2
0040102C      AD            db      AD
0040102D      60            db      60                               ;  CHAR '`'
0040102E      D6            db      D6
0040102F      32            db      32                               ;  CHAR '2'
00401030      17            db      17
00401031      0B            db      0B
00401032      B8            db      B8
00401033      69            db      69                               ;  CHAR 'i'
00401034      D8            db      D8
00401035      09            db      09
00401036      97            db      97
00401037      EC            db      EC
00401038      4C            db      4C                               ;  CHAR 'L'
00401039      9F            db      9F
0040103A      DE            db      DE
0040103B      A0            db      A0
0040103C      A0            db      A0
0040103D      6D            db      6D                               ;  CHAR 'm'
0040103E      3E            db      3E                               ;  CHAR '>'
0040103F      8C            db      8C
00401040   .  394B 8A       cmp     dword ptr [ebx-76], ecx
00401043   .  B5 9B         mov     ch, 9B
00401045   .  8BFF          mov     edi, edi
00401047   .  15 14504000   adc     eax, 00405014
0040104C   .  33D2          xor     edx, edx
0040104E   .  8AD4          mov     dl, ah
00401050   .  8915 F4844000 mov     dword ptr [4084F4], edx
00401056   .  8BC8          mov     ecx, eax


Stolen Code,把oep抽掉了!可以确定的是,oep在00401020处,为了修补oep,往下翻看

代码:

00401058   .  81E1 FF000000 and     ecx, 0FF
0040105E   .  890D F0844000 mov     dword ptr [4084F0], ecx
00401064   .  C1E1 08       shl     ecx, 8
00401067   .  03CA          add     ecx, edx
00401069   .  890D EC844000 mov     dword ptr [4084EC], ecx
0040106F   .  C1E8 10       shr     eax, 10
00401072   .  A3 E8844000   mov     dword ptr [4084E8], eax
00401077   .  33F6          xor     esi, esi
00401079   .  56            push    esi
0040107A   .  E8 160B0000   call    00401B95
0040107F   .  59            pop     ecx
00401080   .  85C0          test    eax, eax
00401082   .  75 08         jnz     short 0040108C
00401084   .  6A 1C         push    1C
00401086   .  E8 B0000000   call    0040113B
0040108B   .  59            pop     ecx
0040108C   >  8975 FC       mov     dword ptr [ebp-4], esi
0040108F   .  E8 E1070000   call    00401875
00401094   .  FF15 10504000 call    dword ptr [405010]
<-这边,vc程序的GetVersion一般都在这里,机器码为FF 15,从这里以上的到oep处的字节全被抽掉了!


随便找一个标准的vc程序,od载入,下面代码
代码:

004013FB >/$  55            push    ebp
004013FC  |.  8BEC          mov     ebp, esp
004013FE  |.  6A FF         push    -1
00401400  |.  68 B8404000   push    004040B8
00401405  |.  68 301F4000   push    00401F30                         ;  SE 处理程序安装
0040140A  |.  64:A1 0000000>mov     eax, dword ptr fs:[0]
00401410  |.  50            push    eax
00401411  |.  64:8925 00000>mov     dword ptr fs:[0], esp
00401418  |.  83EC 58       sub     esp, 58
0040141B  |.  53            push    ebx
0040141C  |.  56            push    esi
0040141D  |.  57            push    edi
0040141E  |.  8965 E8       mov     dword ptr [ebp-18], esp
00401421  |.  FF15 2C404000 call    dword ptr [<&KERNEL32.GetVersion>;<-这句以上的,

命令行下d 004013fb,把从字节55 8B开始到 FF 15之间的38个字节二进制粘贴到被抽掉的oep处,看到以下正常的代码:
代码:

00401020      55            push    ebp
00401021      8BEC          mov     ebp, esp
00401023      6A FF         push    -1
00401025      68 B8404000   push    004040B8
0040102A      68 301F4000   push    00401F30
0040102F      64:A1 0000000>mov     eax, dword ptr fs:[0]
00401035      50            push    eax
00401036      64:8925 00000>mov     dword ptr fs:[0], esp
0040103D      83EC 58       sub     esp, 58
00401040      53            push    ebx
00401041      56            push    esi
00401042      57            push    edi
00401043      8965 E8       mov     dword ptr [ebp-18], esp
00401046   ?  FF15 14504000 call    dword ptr [405014]  <-这句以上的都是修复后的oep

现在可dump了,od插件,修改modify为1020,dump出来一个"1.exe"

当然无法运行了!打开rec,选择这个带壳进程,oep为1020,发现无法修复无效指针n个!IAT被加密了!

看一下这句
代码:

00401046   ?  FF15 14504000 call    dword ptr [405014]<-GetVersion函数调用,证明程序调用系统里的一个函数,可以确定一个iat的地址
命令行上下d 00405014,向上翻一下下!都是0x0090xxxx的dword,说起来正确的应该是0x7xxxxxx才对的!

引用:

00404FF4                                      F4 4A 90 00           ?
00405004  00 4B 90 00 0C 4B 90 00 18 4B 90 00 07 4D 90 00  .K?.K?K?M?
00405014  11 4D 90 00 3C 4B 90 00 48 4B 90 00 1B 4D 90 00  M?<K?HK?M?
00405024  60 4B 90 00 6C 4B 90 00 78 4B 90 00 84 4B 90 00  `K?lK?xK??
00405034  90 4B 90 00 9C 4B 90 00 A8 4B 90 00 B4 4B 90 00  ????
00405044  C0 4B 90 00 CC 4B 90 00 D8 4B 90 00 E4 4B 90 00  ????
00405054  F0 4B 90 00 FC 4B 90 00 08 4C 90 00 14 4C 90 00  ??L?L?
00405064  20 4C 90 00 2C 4C 90 00 38 4C 90 00 44 4C 90 00   L?,L?8L?DL?
00405074  50 4C 90 00 5C 4C 90 00 68 4C 90 00 74 4C 90 00  PL?\L?hL?tL?
00405084  80 4C 90 00 8C 4C 90 00 98 4C 90 00 A4 4C 90 00  L????
00405094  B0 4C 90 00 BC 4C 90 00 DC 4A 90 00 E8 4A 90 00  ????
iat地始地址为405000,结束地址为4050a4,则大小为0xa4!
Ctrl+f2重新载入带壳程序,看程序加密iat
命令行上下,d 00405000,可以看到地址里都是空的,证明壳还没填充IAT
shift+f9运行到第11次异常之后,看到IAT里的数据都填充了!则我们在第10次异常时
在00405000处下内存写入断点,让壳往IAT里填充的数据时断下来
shift+f9运行

代码:

00904700    893E            mov     dword ptr [esi], edi <-断在这里
00904702    EB 01           jmp     short 00904705

这里esi指向00405000,而edi则为0x009xxxx之类的,翻看下面代码,小狗阿花还真不少的说!

代码:

00904700    893E            mov     dword ptr [esi], edi
00904702    EB 01           jmp     short 00904705
00904704    0A83 C70CEB02   or      al, byte ptr [ebx+2EB0CC7]
0090470A    A3 0B83C604     mov     dword ptr [4C6830B], eax
0090470F    EB 01           jmp     short 00904712
00904711    6B41 EB 01      imul    eax, dword ptr [ecx-15], 1
00904715    8E3B            mov     seg?, word ptr [ebx]             ; 未定义的段寄存器
00904717    4D              dec     ebp
00904718    0C EB           or      al, 0EB
0090471A    0311            add     edx, dword ptr [ecx]
0090471C    9D              popfd
0090471D    0E              push    cs
0090471E  ^ 72 8B           jb      short 009046AB

用插件去掉花指令,突然发现,人生原来可以这么爽。
代码:

00904700    893E            mov     dword ptr [esi], edi    <-填充iat
00904702    90              nop
00904703    90              nop
00904704    90              nop
00904705    83C7 0C         add     edi, 0C
00904708    90              nop
00904709    90              nop
0090470A    90              nop
0090470B    90              nop
0090470C    83C6 04         add     esi, 4
0090470F    90              nop
00904710    90              nop
00904711    90              nop
00904712    41              inc     ecx                    <-循环计数器
00904713    90              nop
00904714    90              nop
00904715    90              nop
00904716    3B4D 0C         cmp     ecx, dword ptr [ebp+C]
00904719    90              nop
0090471A    90              nop
0090471B    90              nop
0090471C    90              nop
0090471D    90              nop
0090471E  ^ 72 8B           jb      short 009046AB         <-没循环填充完加密数据IAT则跳上去
00904720    90              nop                            <-f4到这里,让壳填充完iat
00904721    90              nop
00904722    90              nop
00904723    90              nop
00904724    90              nop
00904725    90              nop
00904726    90              nop
00904727    90              nop
00904728    833E 00         cmp     dword ptr [esi], 0     <-esi指向00405098,这里还没填充
0090472B    90              nop
0090472C    90              nop
0090472D    90              nop
0090472E    90              nop
0090472F    75 64           jnz     short 00904795         <-如果填充了,就跳
00904731    90              nop
00904732    90              nop
00904733    90              nop
00904734    893E            mov     dword ptr [esi], edi   <-否则这里进行填充
00904736    90              nop
00904737    90              nop
00904738    90              nop
00904739    90              nop
0090473A    90              nop
0090473B    C607 60         mov     byte ptr [edi], 60
0090473E    90              nop
0090473F    90              nop
00904740    90              nop
00904741    90              nop
00904742    90              nop
00904743    90              nop
00904744    66:C747 01 66B8 mov     word ptr [edi+1], 0B866
0090474A    90              nop
0090474B    90              nop
0090474C    90              nop
0090474D    90              nop
0090474E    90              nop
0090474F    90              nop
00904750    66:894F 03      mov     word ptr [edi+3], cx
00904754    90              nop
00904755    90              nop
00904756    90              nop
00904757    90              nop
00904758    90              nop
00904759    90              nop
0090475A    C647 05 B2      mov     byte ptr [edi+5], 0B2
0090475E    90              nop
0090475F    90              nop
00904760    90              nop
00904761    90              nop
00904762    90              nop
00904763    90              nop
00904764    8857 06         mov     byte ptr [edi+6], dl
00904767    90              nop
00904768    90              nop
00904769    90              nop
0090476A    90              nop
0090476B    90              nop
0090476C    C647 07 E9      mov     byte ptr [edi+7], 0E9
00904770    90              nop
00904771    90              nop
00904772    90              nop
00904773    90              nop
00904774    8B45 14         mov     eax, dword ptr [ebp+14]
00904777    2BC7            sub     eax, edi
00904779    90              nop
0090477A    90              nop
0090477B    90              nop
0090477C    90              nop
0090477D    90              nop
0090477E    83E8 0C         sub     eax, 0C
00904781    90              nop
00904782    90              nop
00904783    90              nop
00904784    90              nop
00904785    90              nop
00904786    90              nop
00904787    8947 08         mov     dword ptr [edi+8], eax
0090478A    90              nop
0090478B    90              nop
0090478C    90              nop
0090478D    90              nop
0090478E    90              nop
0090478F    83C7 0C         add     edi, 0C
00904792    90              nop
00904793    90              nop
00904794    90              nop
00904795    90              nop
00904796    90              nop
00904797    90              nop
00904798    90              nop
00904799    90              nop
0090479A    8BC7            mov     eax, edi
0090479C    90              nop
0090479D    90              nop
0090479E    90              nop
0090479F    2B45 18         sub     eax, dword ptr [ebp+18]
009047A2    90              nop
009047A3    90              nop
009047A4    90              nop
009047A5    90              nop
009047A6    90              nop
009047A7    5F              pop     edi
009047A8    5E              pop     esi
009047A9    5B              pop     ebx
009047AA    C9              leave
009047AB    C2 1400         retn    14                 <-返回吧

返回后又看到小花,再次去掉, 下面是去掉小花后的指令
代码:

00904382    90              nop
00904383    90              nop
00904384    90              nop
00904385    90              nop
00904386    90              nop
00904387    0143 04         add     dword ptr [ebx+4], eax
0090438A    90              nop
0090438B    90              nop
0090438C    90              nop
0090438D    90              nop
0090438E    90              nop
0090438F    90              nop
00904390    90              nop
00904391    90              nop
00904392    90              nop
00904393    90              nop
00904394    90              nop
00904395    90              nop
00904396    8B46 14         mov     eax, dword ptr [esi+14]  <-IAT偏移传到eax
00904399    90              nop
0090439A    90              nop
0090439B    90              nop
0090439C    90              nop
0090439D    90              nop
0090439E    8B56 10         mov     edx, dword ptr [esi+10]
009043A1    90              nop
009043A2    90              nop
009043A3    90              nop
009043A4    90              nop
009043A5    90              nop
009043A6    0303            add     eax, dword ptr [ebx]     <-偏移加基址,形成IAT实际地址,为405000
009043A8    90              nop
009043A9    90              nop
009043AA    90              nop
009043AB    0353 28         add     edx, dword ptr [ebx+28]
009043AE    90              nop
009043AF    90              nop
009043B0    90              nop
009043B1    90              nop
009043B2    90              nop
009043B3    FF76 04         push    dword ptr [esi+4]        <-dll基址进栈
009043B6    53              push    ebx
009043B7    52              push    edx
009043B8    50              push    eax                      <-IAT实际地址进栈
009043B9    FF76 0C         push    dword ptr [esi+C]
009043BC    E8 6D010000     call    0090452E                 <-这个call,很可疑!跟进

       
代码:

       
[  解密函数call   ]
将修改下面代码,(修改方法是辉仔yock的文章里提到了,也是看后有感才脱这个壳,大家可以去搜一搜)
0090452E    C8 000000       enter   0, 0
00904532    53              push    ebx
00904533    56              push    esi
00904534    57              push    edi
00904535    8B5D 14         mov     ebx, dword ptr [ebp+14]
00904538    8B75 10         mov     esi, dword ptr [ebp+10]
0090453B    8B7D 0C         mov     edi, dword ptr [ebp+C]
0090453E    8B5B 04         mov     ebx, dword ptr [ebx+4]
00904541    66:F706 2000    test    word ptr [esi], 20      <-改为test word ptr[esi],8
00904546    74 46           je      short 0090458E          <-改为jne 0090458e,记住0090458e这个地址
00904548    66:F706 0200    test    word ptr [esi], 2
0090454D    75 1F           jnz     short 0090456E
0090454F    66:C706 0400    mov     word ptr [esi], 4
00904554    8B45 14         mov     eax, dword ptr [ebp+14]
00904557    6A 01           push    1
00904559    6A 00           push    0
0090455B    FF76 04         push    dword ptr [esi+4]
0090455E    6A 00           push    0
00904560    FF75 18         push    dword ptr [ebp+18]
00904563    FF50 40         call    dword ptr [eax+40]
00904566    85C0            test    eax, eax
00904568    74 39           je      short 009045A3         <-改为je 0090458e
0090456A    8907            mov     dword ptr [edi], eax
0090456C    EB 20           jmp     short 0090458E
0090456E    66:C706 0400    mov     word ptr [esi], 4
00904573    8B45 14         mov     eax, dword ptr [ebp+14]
00904576    0FB756 02       movzx   edx, word ptr [esi+2]
0090457A    6A 01           push    1
0090457C    52              push    edx
0090457D    6A 00           push    0
0090457F    FF76 04         push    dword ptr [esi+4]
00904582    FF75 18         push    dword ptr [ebp+18]
00904585    FF50 40         call    dword ptr [eax+40]
00904588    85C0            test    eax, eax
0090458A    74 17           je      short 009045A3        <-改为je 0090458e
0090458C    8907            mov     dword ptr [edi], eax
0090458E    83C6 08         add     esi, 8
00904591    83C7 04         add     edi, 4
00904594    FF4D 08         dec     dword ptr [ebp+8]
00904597  ^ 75 A8           jnz     short 00904541
00904599    33C0            xor     eax, eax
0090459B    40              inc     eax
0090459C    5F              pop     edi
0090459D    5E              pop     esi
0090459E    5B              pop     ebx
0090459F    C9              leave
009045A0    C2 1400         retn    14



解释一下为什么这么改:
就像那篇文章所说,此壳标志一个函数为普通函数还是特殊函数!用08表示特殊函数,02表示普通函数,则,没改代码之前

test    word ptr [esi], 20<-这句比较是否为普通函数
je      short 0090458E    <-是普通函数,则不进行处理

改为
test    word ptr[esi],  08<-则,比较是否为特殊函数
jnz     short 0090458e    <-不是特殊函数,则不进行处理

好了`改了之后,程序就会把正确的普通函数的正确地址填充进IAT里!当然还有特殊函数!

所谓特殊函数,仔细看了一下几个未填充的IAT地址,可以确认为几个重要的启动函数,比如像GetCommandLine之类的,不解密,则程序无法运行了!处理完普通函数,返回到这里:

代码:

009043C1    90              nop      < -返回到这里
009043C2    90              nop
009043C3    90              nop
009043C4    85C0            test    eax, eax
009043C6    90              nop
009043C7    90              nop
009043C8    90              nop
009043C9    0F84 BB000000   je      0090448A
009043CF    90              nop
009043D0    90              nop
009043D1    90              nop
009043D2    90              nop
009043D3    90              nop
009043D4    90              nop
009043D5    90              nop
009043D6    90              nop
009043D7    837D F0 00      cmp     dword ptr [ebp-10], 0
009043DB    90              nop
009043DC    90              nop
009043DD    90              nop
009043DE    90              nop
009043DF    90              nop
009043E0    90              nop
009043E1    74 37           je      short 0090441A
009043E3    90              nop
009043E4    90              nop
009043E5    90              nop
009043E6    90              nop
009043E7    90              nop
009043E8    90              nop
009043E9    90              nop
009043EA    8B46 14         mov     eax, dword ptr [esi+14]
009043ED    90              nop
009043EE    90              nop
009043EF    90              nop
009043F0    90              nop
009043F1    90              nop
009043F2    90              nop
009043F3    8B56 10         mov     edx, dword ptr [esi+10]
009043F6    90              nop
009043F7    90              nop
009043F8    90              nop
009043F9    90              nop
009043FA    90              nop
009043FB    90              nop
009043FC    0303            add     eax, dword ptr [ebx]
009043FE    90              nop
009043FF    90              nop
00904400    90              nop
00904401    90              nop
00904402    90              nop
00904403    90              nop
00904404    0353 28         add     edx, dword ptr [ebx+28]
00904407    90              nop
00904408    90              nop
00904409    90              nop
0090440A    90              nop
0090440B    90              nop
0090440C    FF75 F4         push    dword ptr [ebp-C]
0090440F    53              push    ebx
00904410    52              push    edx
00904411    50              push    eax
00904412    FF76 0C         push    dword ptr [esi+C]
00904415    E8 92010000     call    009045AC           <-这个call,跟进


来到这里


       
代码:

       
009045AC    C8 000000       enter   0, 0
009045B0    53              push    ebx
009045B1    56              push    esi
009045B2    57              push    edi
009045B3    8B5D 14         mov     ebx, dword ptr [ebp+14]
009045B6    8B75 10         mov     esi, dword ptr [ebp+10]
009045B9    8B7D 0C         mov     edi, dword ptr [ebp+C]
009045BC    8B5B 04         mov     ebx, dword ptr [ebx+4]
009045BF    66:833E 08      cmp     word ptr [esi], 8     <-比较是否为特殊函数
009045C3    0F85 97000000   jnz     00904660              <-不是则不处理
009045C9    8B46 04         mov     eax, dword ptr [esi+4]
009045CC    83F8 00         cmp     eax, 0
009045CF    74 44           je      short 00904615
009045D1    83F8 01         cmp     eax, 1
009045D4    74 4E           je      short 00904624
009045D6    83F8 02         cmp     eax, 2
009045D9    74 58           je      short 00904633
009045DB    83F8 03         cmp     eax, 3
009045DE    74 11           je      short 009045F1
009045E0    83F8 04         cmp     eax, 4
009045E3    75 7B           jnz     short 00904660
009045E5    8B45 18         mov     eax, dword ptr [ebp+18]
009045E8    05 EE1DB300     add     eax, 0B31DEE
009045ED    8907            mov     dword ptr [edi], eax
009045EF    EB 6F           jmp     short 00904660
009045F1    8B45 14         mov     eax, dword ptr [ebp+14]
009045F4    68 C5B1662D     push    2D66B1C5
009045F9    6A 00           push    0
009045FB    FF50 20         call    dword ptr [eax+20]   <-这里进行处理.跟进

跟进后来到这里,下面是去掉小花后的指令

       
代码:

       
004144DE    90              nop
004144DF    90              nop
004144E0    90              nop
004144E1    90              nop
004144E2    90              nop
004144E3    60              pushad
004144E4    90              nop
004144E5    90              nop
004144E6    90              nop
004144E7    90              nop
004144E8    E8 00000000     call    004144ED
004144ED    90              nop
004144EE    90              nop
004144EF    90              nop
004144F0    90              nop
004144F1    5B              pop     ebx
004144F2    90              nop
004144F3    90              nop
004144F4    90              nop
004144F5    90              nop
004144F6    90              nop
004144F7    90              nop
004144F8    81EB C85AB300   sub     ebx, 0B35AC8
004144FE    90              nop
004144FF    90              nop
00414500    90              nop
00414501    90              nop
00414502    8B9B B45AB300   mov     ebx, dword ptr [ebx+B35AB4]
00414508    90              nop
00414509    90              nop
0041450A    90              nop
0041450B    90              nop
0041450C    90              nop
0041450D    90              nop
0041450E    90              nop
0041450F    90              nop
00414510    8B4424 24       mov     eax, dword ptr [esp+24]
00414514    90              nop
00414515    90              nop
00414516    90              nop
00414517    90              nop
00414518    90              nop
00414519    90              nop
0041451A    90              nop
0041451B    90              nop
0041451C    90              nop
0041451D    90              nop
0041451E    33C9            xor     ecx, ecx
00414520    90              nop
00414521    90              nop
00414522    90              nop
00414523    90              nop
00414524    90              nop
00414525    90              nop
00414526    8B4483 48       mov     eax, dword ptr [ebx+eax*4+48]
0041452A    90              nop
0041452B    90              nop
0041452C    90              nop
0041452D    90              nop
0041452E    90              nop
0041452F    8B5424 28       mov     edx, dword ptr [esp+28]
00414533    90              nop
00414534    90              nop
00414535    90              nop
00414536    90              nop
00414537    90              nop
00414538    51              push    ecx
00414539    51              push    ecx
0041453A    51              push    ecx
0041453B    52              push    edx
0041453C    50              push    eax
0041453D    FF53 40         call    dword ptr [ebx+40]   <-解密的call
00414540    90              nop
00414541    90              nop
00414542    90              nop
00414543    90              nop
00414544    90              nop
00414545    85C0            test    eax, eax
00414547    90              nop
00414548    90              nop
00414549    90              nop
0041454A    90              nop
0041454B    0F84 DE010000   je      0041472F
00414551    90              nop   





<-解密后,到这里,此时edi指0x405010,hex窗口中看到一下0x405010,可以看到数据是0x009xxxx
,说明是到这里未解密的函数,到这里还没解密的,就是特殊函数,看一下eax,第一次是GetCommandLineA的正确地址。我们得把这个地址填充到IAT里去,也就是此时的edi,

00414551    90              nop   <-所以,应该把这句,改为mov [edi],eax

代码:

009045FE    50              push    eax       <-返回之后,到达这里
009045FF    53              push    ebx
00904600    E8 D7030000     call    009049DC
00904605    53              push    ebx
00904606    E8 46030000     call    00904951
0090460B    8BCB            mov     ecx, ebx
0090460D    8D5C03 01       lea     ebx, dword ptr [ebx+eax+1]
00904611    8BC1            mov     eax, ecx
00904613    EB 2B           jmp     short 00904640
00904615    8B45 14         mov     eax, dword ptr [ebp+14]
00904618    68 0F1ACF4C     push    4CCF1A0F
0090461D    6A 00           push    0
0090461F    FF50 20         call    dword ptr [eax+20]
00904622    EB 1C           jmp     short 00904640
00904624    8B45 14         mov     eax, dword ptr [ebp+14]
00904627    68 A41A86D0     push    D0861AA4
0090462C    6A 00           push    0
0090462E    FF50 20         call    dword ptr [eax+20]
00904631    EB 0D           jmp     short 00904640
00904633    8B45 14         mov     eax, dword ptr [ebp+14]
00904636    68 E313B41D     push    1DB413E3
0090463B    6A 00           push    0
0090463D    FF50 20         call    dword ptr [eax+20]
00904640    C603 B8         mov     byte ptr [ebx], 0B8
00904643    8943 01         mov     dword ptr [ebx+1], eax
00904646    8B55 18         mov     edx, dword ptr [ebp+18]
00904649    81C2 511CB300   add     edx, 0B31C51
0090464F    8D43 0A         lea     eax, dword ptr [ebx+A]
00904652    2BD0            sub     edx, eax
00904654    C643 05 E9      mov     byte ptr [ebx+5], 0E9
00904658    8953 06         mov     dword ptr [ebx+6], edx
0090465B    891F            mov     dword ptr [edi], ebx   <-nop

//到达上面那句的时候,ebx又还原成加密数据了,而edi此时还是指向刚刚的401050,则壳想把加密数据填充到IAT!所以,这里我们得nop

代码:

0090465D    83C3 0A         add     ebx, 0A
00904660    83C6 08         add     esi, 8
00904663    83C7 04         add     edi, 4
00904666    8B45 14         mov     eax, dword ptr [ebp+14]
00904669    8958 04         mov     dword ptr [eax+4], ebx
0090466C    FF4D 08         dec     dword ptr [ebp+8]
0090466F  ^ 0F85 4AFFFFFF   jnz     009045BF
00904675    5F              pop     edi
00904676    5E              pop     esi
00904677    5B              pop     ebx
00904678    C9              leave
00904679    C2 1400         retn    14   <-返回

代码:

0090465D    83C3 0A         add     ebx, 0A
00904660    83C6 08         add     esi, 8
00904663    83C7 04         add     edi, 4
00904666    8B45 14         mov     eax, dword ptr [ebp+14]
00904669    8958 04         mov     dword ptr [eax+4], ebx
0090466C    FF4D 08         dec     dword ptr [ebp+8]
0090466F  ^ 0F85 4AFFFFFF   jnz     009045BF
00904675    5F              pop     edi
00904676    5E              pop     esi
00904677    5B              pop     ebx
00904678    C9              leave
00904679    C2 1400         retn    14   <-返回

0090441A    90              nop          <-返回之后到达这里
0090441B    90              nop
0090441C    90              nop
0090441D    90              nop
0090441E    90              nop
0090441F    90              nop
00904420    83C6 18         add     esi, 18
00904423    90              nop
00904424    90              nop
00904425    90              nop
00904426    90              nop
00904427    90              nop
00904428    90              nop
00904429    FF45 F8         inc     dword ptr [ebp-8]
0090442C    90              nop
0090442D    90              nop
0090442E    90              nop
0090442F    90              nop
00904430    FF4D FC         dec     dword ptr [ebp-4]
00904433    90              nop
00904434    90              nop
00904435    90              nop
00904436    90              nop
00904437    90              nop
00904438    90              nop
00904439  ^ 0F85 1CFDFFFF   jnz     0090415B        <-[ebp-4]是计数器,没处理完iat就跳上去
0090443F    90              nop
00904440    90              nop
00904441    90              nop
00904442    33C0            xor     eax, eax        <-要改的都改完了,这里f2下断,f9运行,断下后壳已经处理完iat了!记住f2取消断点
00904444    90              nop
00904445    90              nop
00904446    90              nop
00904447    90              nop
00904448    90              nop
00904449    90              nop
0090444A    5F              pop     edi
0090444B    5E              pop     esi
0090444C    5B              pop     ebx
0090444D    C9              leave
0090444E    C3              retn                   <-从这里返回


0040BEE2   /EB 02           jmp     short 0040BEE6 <-到达这里
0040BEE4   |6BF6 F7         imul    esi, esi, -9

可以用rec修复iat了,虽然翻看一下iat表,末尾还是有未解密的指针,可以看到,大部份指针都解密完了
引用:

FThunk: 00005000  NbFunc: 00000029
1  00005000  kernel32.dll  0207  HeapDestroy
1  00005004  kernel32.dll  01B3  GetStringTypeW
1  00005008  kernel32.dll  0176  GetModuleHandleA
1  0000500C  kernel32.dll  01AD  GetStartupInfoA
1  00005010  kernel32.dll  010A  GetCommandLineA
1  00005014  kernel32.dll  01DB  GetVersion
1  00005018  kernel32.dll  00B7  ExitProcess
1  0000501C  kernel32.dll  0347  TerminateProcess
1  00005020  kernel32.dll  013C  GetCurrentProcess
1  00005024  kernel32.dll  0358  UnhandledExceptionFilter
1  00005028  kernel32.dll  0174  GetModuleFileNameA
1  0000502C  kernel32.dll  00EF  FreeEnvironmentStringsA
1  00005030  kernel32.dll  00F0  FreeEnvironmentStringsW
1  00005034  kernel32.dll  037F  WideCharToMultiByte
1  00005038  kernel32.dll  014E  GetEnvironmentStrings
1  0000503C  kernel32.dll  0150  GetEnvironmentStringsW
1  00005040  kernel32.dll  0255  LockResource
1  00005044  kernel32.dll  01AF  GetStdHandle
1  00005048  kernel32.dll  015F  GetFileType
1  0000504C  kernel32.dll  0151  GetEnvironmentVariableA
1  00005050  kernel32.dll  01DC  GetVersionExA
1  00005054  kernel32.dll  0205  HeapCreate
1  00005058  kernel32.dll  036E  VirtualFree
1  0000505C  kernel32.dll  0209  HeapFree
1  00005060  kernel32.dll  02C5  RtlUnwind
1  00005064  kernel32.dll  038C  WriteFile
1  00005068  kernel32.dll  00FE  GetCPInfo
1  0000506C  kernel32.dll  00F7  GetACP
1  00005070  kernel32.dll  018B  GetOEMCP
1  00005074  kernel32.dll  0203  HeapAlloc
1  00005078  kernel32.dll  036B  VirtualAlloc
1  0000507C  kernel32.dll  020D  HeapReAlloc
1  00005080  kernel32.dll  0198  GetProcAddress
1  00005084  kernel32.dll  0242  LoadLibraryA
1  00005088  kernel32.dll  0265  MultiByteToWideChar
1  0000508C  kernel32.dll  0234  LCMapStringA
1  00005090  kernel32.dll  0235  LCMapStringW
1  00005094  kernel32.dll  01B0  GetStringTypeA
0  00005098  ?  0000  00904CBC     <-这个还没有
0  0000509C  ?  0000  00904ADC     <-这个还没有
0  000050A0  ?  0000  00904AE8     <-这个还没有

按照脱壳高手们的职业病,先全部改为MessageBox函数,发现这三个都改为MessageBox之后,5098这个会总是无效,并把其上面一个指针拖下水!则MessageBox为user32.dll,5098作为其kernel32.dll与user32.dll的分界,这个就剪掉!

全部指针有效之后,修复抓取文件,抓出一个"1_.exe"

还是无法运行的!od载入这个"1_.exe",忽略掉所有的异常,f9运行时,出现一个错误对话框“不知如何继续,因为内存地址0090162b......”之类的,

重新载入,hex窗口看查找0090162b

0040A0B4  2B 16 90 00 00 00 00 00 00 00 00 00 00 00 00 00  <-在这个地方
我们在0040a0b4这个地方下内存访问断点,f9运行,断在这里

00402581   . /EB FF         jmp     short 00402582    <-垃圾东西,nop
00402583   .  15 B4A04000   adc     eax, 0040A0B4     <-垃圾东西,也nop
00402588   .  C3            retn

保存后运行程序,程序是可以运行了,不过结束时还有一个错误

od再载入,不忽略内存访问异常!f9运行,程序要退出的时候,堆栈说:

0012FF34   0040101D  返回到 1_.0040101D 来自 0090162A<-要修复程序者,就去40101d那里吧

我们听堆栈的话,来到40101d,发现了和上面一模一样的垃圾代码:
00401016   . /EB FF          jmp     short 00401017
00401018   .  15 B0A04000    adc     eax, 0040A0B0

都nop掉!程序可以运行了!

----------------------------------------------------------------------------------
└经验总结┐:

壳盲的经验还是不分享的好~ 
----------------------------------------------------------------------------------
└版权声明┐ 本文原创于看雪软件安全论坛, 转载请注明作者并保持文章的完整, 谢谢!

                                                           2007年9月20日  11:37:51