netsowell的壳的IAT简要分析的修复

原贴在这里
http://bbs.pediy.com/showthread.php?s=&threadid=22815
原程序下载:ennotepad.rar

由于没有花指令,分析起来好看多了,感谢netsowell大侠给我等菜鸟调试分析的机会


野猪力量 --- 注入!


      002C0264            8945 90           mov dword ptr ss:[ebp-70],eax
      002C0267            33C0              xor eax,eax
      002C0269            8945 8C           mov dword ptr ss:[ebp-74],eax
      002C026C            6A 2C             push 2C
      002C026E            8D85 D0FEFFFF     lea eax,dword ptr ss:[ebp-130]              //这里的ebp-130是每次处理时在堆栈中的数据结构的起始
      002C0274            50                push eax
      002C0275            53                push ebx
      002C0276            FFD6              call esi                                    //从这里到最后所有的esi都是memcpy(src, dst, size)
      002C0278            E9 CC020000       jmp       002C0549
这个是准备处理第一个调用输入表变形的地方, 也就是把call [IAT],变成call 2X0000
壳的思路就是,将一块一块关于变形call的数据结构copy到堆栈的局部变量中,根据
数据结构完成每一个变形

这个数据结构大致是这样的
struct ss
{
    BYTE      key;          //解密输入表dll和函数名字的密钥,算法是异或
    DWORD     IATRva;       //相关的在输入表(IAT)中的位置的RVA  
    DWORD     IsOrdinal;    //1= 通过Ordinal取导入函数, 0=通过名字取导入函数
    DWORD     Unknown1;
    DWORD     Ordinal;      //Ordinal的值,如果没有,这里是-1
    BYTE      code1[7];     //1个E8的call, 目的地址是处理输入表变形的公共部分
                              BYTE[7]的起始地址是IAT中的值
    WORD      temp1;        //临时写入E9
    DWORD     ff25addr;     //如果不为0,则这个值加上主代码段起始地址得到需要变形
                              的地址,且这个变形是FF25的变形
    WORD      temp2;        //临时写入90 E8
    DWORD     ff15addr;     //如果不为0,则这个值加上主代码段起始地址得到需要变形
                              的地址,且这个变形是FF15的变形
    DWORD     UnKnown2;

    //以上共0x2C长
    enum
    {
        BYTE      EnDllName[];  //加密的dll的名字,密钥是上面的key, 算法是异或
        DWORD     EnFunAddr;    //将* (LPDWORD)code1[1]和导入函数的地址异或
    }
    BYTE      EnFunName[];  //加密的导入函数的名字,密钥是上面的key, 算法是异或
     
}


      002C027D            8BC3              mov eax,ebx
      002C027F            0345 8C           add eax,dword ptr ss:[ebp-74]
      002C0282            83C0 11           add eax,11
      002C0285            8B55 90           mov edx,dword ptr ss:[ebp-70]
      002C0288            2BD0              sub edx,eax
      002C028A            83EA 05           sub edx,5
      002C028D            8955 88           mov dword ptr ss:[ebp-78],edx
      002C0290            C685 E1FEFFFF E8  mov byte ptr ss:[ebp-11F],0E8
      002C0297            8B45 88           mov eax,dword ptr ss:[ebp-78]
      002C029A            8985 E2FEFFFF     mov dword ptr ss:[ebp-11E],eax             //完成对数据结构ss中ss.code1的计算
      002C02A0            6A 2C             push 2C
      002C02A2            8BC3              mov eax,ebx
      002C02A4            0345 8C           add eax,dword ptr ss:[ebp-74]
      002C02A7            50                push eax
      002C02A8            8D85 D0FEFFFF     lea eax,dword ptr ss:[ebp-130]
      002C02AE            50                push eax
      002C02AF            FFD6              call esi                                   //将更新后的ss.code1部分写回原来的地方
      002C02B1            8BC3              mov eax,ebx
      002C02B3            0345 8C           add eax,dword ptr ss:[ebp-74]
      002C02B6            83C0 11           add eax,11
      002C02B9            8945 88           mov dword ptr ss:[ebp-78],eax
      002C02BC            6A 04             push 4
      002C02BE            8B45 AC           mov eax,dword ptr ss:[ebp-54]              //程序基址
      002C02C1            0385 D1FEFFFF     add eax,dword ptr ss:[ebp-12F]             //再加上ss.IATRva就是这个变形相关的IAT的地址
      002C02C7            50                push eax
      002C02C8            8D45 88           lea eax,dword ptr ss:[ebp-78]
      002C02CB            50                push eax
      002C02CC            FFD6              call esi                                   //将ss.code1的起始地址写入相关的IAT中
                                                                                       //这样以后每次call [IAT],相当于call ss.code1
                                                                                       //ss.code1再call入处理变形的公共代码部分
      002C02CE            8345 8C 2C        add dword ptr ss:[ebp-74],2C
      002C02D2            8B45 8C           mov eax,dword ptr ss:[ebp-74]
      002C02D5            03C3              add eax,ebx
      002C02D7            8945 A8           mov dword ptr ss:[ebp-58],eax
      002C02DA            83BD 54FFFFFF 00  cmp dword ptr ss:[ebp-AC],0
      002C02E1            0F85 F6010000     jnz       002C04DD
      002C02E7            8BFB              mov edi,ebx
      002C02E9            037D 8C           add edi,dword ptr ss:[ebp-74]              
      002C02EC            0FB685 D0FEFFFF   movzx eax,byte ptr ss:[ebp-130]           //取出ss.key密钥
      002C02F3            50                push eax
      002C02F4            57                push edi                                  //ss.EnDllName
      002C02F5            E8 6D020000       call       002C0567                       //解出dll的名字,返回名字的长度
      002C02FA            8945 80           mov dword ptr ss:[ebp-80],eax
      002C02FD            8B45 80           mov eax,dword ptr ss:[ebp-80]
      002C0300            0145 8C           add dword ptr ss:[ebp-74],eax
      002C0303            57                push edi
      002C0304            FF55 98           call dword ptr ss:[ebp-68]                //Call GetModuleHandle,取dll的基础
      002C0307            8945 84           mov dword ptr ss:[ebp-7C],eax
      002C030A            837D 84 00        cmp dword ptr ss:[ebp-7C],0
      002C030E            75 07             jnz short       002C0317
      002C0310            57                push edi
      002C0311            FF55 A0           call dword ptr ss:[ebp-60]                //如果dll不存在,则LoadLibrary这个dll
      002C0314            8945 84           mov dword ptr ss:[ebp-7C],eax
      002C0317            57                push edi
      002C0318            E8 96020000       call       002C05B3                       //取得dll基址后,将dll的名字加密回去
      002C031D            837D 84 00        cmp dword ptr ss:[ebp-7C],0
      002C0321            0F84 11020000     je       002C0538


      002C0327            83BD D5FEFFFF 00  cmp dword ptr ss:[ebp-12B],0              //ss.IsOrdinal是否为1
      002C032E            75 2F             jnz short       002C035F
      002C0330            8BFB              mov edi,ebx
      002C0332            037D 8C           add edi,dword ptr ss:[ebp-74]
      002C0335            0FB685 D0FEFFFF   movzx eax,byte ptr ss:[ebp-130]
      002C033C            50                push eax
      002C033D            57                push edi
      002C033E            E8 24020000       call       002C0567                       //ss.IsOrdinal为0则解密导入函数的名字
      002C0343            8945 80           mov dword ptr ss:[ebp-80],eax
      002C0346            57                push edi
      002C0347            8B45 84           mov eax,dword ptr ss:[ebp-7C]
      002C034A            50                push eax
      002C034B            FF55 9C           call dword ptr ss:[ebp-64]                //GetProcAddress取导入函数地址
      002C034E            8945 84           mov dword ptr ss:[ebp-7C],eax
      002C0351            57                push edi
      002C0352            E8 5C020000       call       002C05B3                       //将导入函数名字加密回去
      002C0357            8B45 80           mov eax,dword ptr ss:[ebp-80]
      002C035A            0145 8C           add dword ptr ss:[ebp-74],eax
      002C035D            EB 11             jmp short       002C0370

      002C035F            8BBD DDFEFFFF     mov edi,dword ptr ss:[ebp-123]            //ss.Ordinal
      002C0365            57                push edi
      002C0366            8B45 84           mov eax,dword ptr ss:[ebp-7C]
      002C0369            50                push eax
      002C036A            FF55 9C           call dword ptr ss:[ebp-64]                //ss.IsOrdinal为1则通过ss.Ordinal取导入函数
      002C036D            8945 84           mov dword ptr ss:[ebp-7C],eax
      002C0370            8B85 D9FEFFFF     mov eax,dword ptr ss:[ebp-127]
      002C0376            83E8 01           sub eax,1
      002C0379            72 1D             jb short       002C0398
      002C037B            0F84 EC000000     je       002C046D
      002C0381            2D FF0F0000       sub eax,0FFF
      002C0386            0F84 0D010000     je       002C0499
      002C038C            48                dec eax
      002C038D            0F84 28010000     je       002C04BB
      002C0393            E9 A0010000       jmp       002C0538

      002C0398            8B85 E2FEFFFF     mov eax,dword ptr ss:[ebp-11E]
      002C039E            3145 84           xor dword ptr ss:[ebp-7C],eax            //ss.EnFunAddr = ApiName ^ *(LPDWORD)ss.code1[1]     
      002C03A1            6A 04             push 4
      002C03A3            8B45 A8           mov eax,dword ptr ss:[ebp-58]
      002C03A6            50                push eax
      002C03A7            8D45 84           lea eax,dword ptr ss:[ebp-7C]
      002C03AA            50                push eax
      002C03AB            FFD6              call esi                                 //将更新后的ss.EnFunAddr写回原来的地方


      002C03AD            83BD EAFEFFFF 00  cmp dword ptr ss:[ebp-116],0             //检查ss.ff25addr是否为0
      002C03B4            76 51             jbe short       002C0407
      002C03B6            66:C785 EEFEFFFF >mov word ptr ss:[ebp-112],0E9            //ff25.addr不为0,则ss.temp1 写入e9
      002C03BF            8B45 A8           mov eax,dword ptr ss:[ebp-58]
      002C03C2            83E8 1B           sub eax,1B
      002C03C5            8B95 78FFFFFF     mov edx,dword ptr ss:[ebp-88]
      002C03CB            0395 EAFEFFFF     add edx,dword ptr ss:[ebp-116]
      002C03D1            2BC2              sub eax,edx
      002C03D3            83E8 05           sub eax,5                                //通过e9的目的地址ss.code1计算偏移地址
      002C03D6            8945 84           mov dword ptr ss:[ebp-7C],eax            
      002C03D9            6A 02             push 2
      002C03DB            8B85 78FFFFFF     mov eax,dword ptr ss:[ebp-88]
      002C03E1            0385 EAFEFFFF     add eax,dword ptr ss:[ebp-116]
      002C03E7            50                push eax
      002C03E8            8D85 EEFEFFFF     lea eax,dword ptr ss:[ebp-112]
      002C03EE            50                push eax
      002C03EF            FFD6              call esi                                 //写入e9
      002C03F1            6A 04             push 4
      002C03F3            8B85 78FFFFFF     mov eax,dword ptr ss:[ebp-88]
      002C03F9            0385 EAFEFFFF     add eax,dword ptr ss:[ebp-116]
      002C03FF            40                inc eax
      002C0400            50                push eax
      002C0401            8D45 84           lea eax,dword ptr ss:[ebp-7C]
      002C0404            50                push eax
      002C0405            FFD6              call esi                                 //写入e9的偏移地址


      002C0407            83BD F0FEFFFF 00  cmp dword ptr ss:[ebp-110],0             //检查ss.ff15addr是否为0
      002C040E            0F86 24010000     jbe       002C0538
      002C0414            66:C785 F4FEFFFF >mov word ptr ss:[ebp-10C],0E890          //ff15.addr不为0,则ss.temp1 写入90 e8
      002C041D            8B45 A8           mov eax,dword ptr ss:[ebp-58]
      002C0420            83E8 1B           sub eax,1B
      002C0423            8B95 78FFFFFF     mov edx,dword ptr ss:[ebp-88]
      002C0429            0395 F0FEFFFF     add edx,dword ptr ss:[ebp-110]
      002C042F            42                inc edx
      002C0430            2BC2              sub eax,edx
      002C0432            83E8 05           sub eax,5                                //通过e8的目的地址ss.code1计算偏移地址
      002C0435            8945 84           mov dword ptr ss:[ebp-7C],eax
      002C0438            6A 02             push 2
      002C043A            8B85 78FFFFFF     mov eax,dword ptr ss:[ebp-88]
      002C0440            0385 F0FEFFFF     add eax,dword ptr ss:[ebp-110]
      002C0446            50                push eax
      002C0447            8D85 F4FEFFFF     lea eax,dword ptr ss:[ebp-10C]
      002C044D            50                push eax
      002C044E            FFD6              call esi                                 //写入90 e8
      002C0450            6A 04             push 4
      002C0452            8B85 78FFFFFF     mov eax,dword ptr ss:[ebp-88]
      002C0458            0385 F0FEFFFF     add eax,dword ptr ss:[ebp-110]
      002C045E            83C0 02           add eax,2
      002C0461            50                push eax
      002C0462            8D45 84           lea eax,dword ptr ss:[ebp-7C]
      002C0465            50                push eax
      002C0466            FFD6              call esi                                 //写入e8的偏移地址
      002C0468            E9 CB000000       jmp       002C0538                       //当前变形的数据结构处理完毕

      002C046D            8B45 A8           mov eax,dword ptr ss:[ebp-58]
      002C0470            83E8 1B           sub eax,1B
      002C0473            8985 7CFFFFFF     mov dword ptr ss:[ebp-84],eax
      002C0479            6A 04             push 4
      002C047B            8D45 84           lea eax,dword ptr ss:[ebp-7C]
      002C047E            50                push eax
      002C047F            8B45 84           mov eax,dword ptr ss:[ebp-7C]
      002C0482            50                push eax
      002C0483            FFD6              call esi
      002C0485            6A 04             push 4
      002C0487            8B85 7CFFFFFF     mov eax,dword ptr ss:[ebp-84]
      002C048D            50                push eax
      002C048E            8D45 84           lea eax,dword ptr ss:[ebp-7C]
      002C0491            50                push eax
      002C0492            FFD6              call esi
      002C0494            E9 9F000000       jmp       002C0538
      002C0499            E8 B1030000       call       002C084F
      002C049E            8985 7CFFFFFF     mov dword ptr ss:[ebp-84],eax
      002C04A4            6A 04             push 4
      002C04A6            8B45 AC           mov eax,dword ptr ss:[ebp-54]
      002C04A9            0385 D1FEFFFF     add eax,dword ptr ss:[ebp-12F]
      002C04AF            50                push eax
      002C04B0            8D85 7CFFFFFF     lea eax,dword ptr ss:[ebp-84]
      002C04B6            50                push eax
      002C04B7            FFD6              call esi
      002C04B9            EB 7D             jmp short       002C0538
      002C04BB            E8 BF030000       call       002C087F
      002C04C0            8985 7CFFFFFF     mov dword ptr ss:[ebp-84],eax
      002C04C6            6A 04             push 4
      002C04C8            8B45 AC           mov eax,dword ptr ss:[ebp-54]
      002C04CB            0385 D1FEFFFF     add eax,dword ptr ss:[ebp-12F]
      002C04D1            50                push eax
      002C04D2            8D85 7CFFFFFF     lea eax,dword ptr ss:[ebp-84]
      002C04D8            50                push eax
      002C04D9            FFD6              call esi
      002C04DB            EB 5B             jmp short       002C0538
      002C04DD            8BFB              mov edi,ebx
      002C04DF            037D 8C           add edi,dword ptr ss:[ebp-74]
      002C04E2            0FB685 D0FEFFFF   movzx eax,byte ptr ss:[ebp-130]
      002C04E9            50                push eax
      002C04EA            57                push edi
      002C04EB            E8 9B000000       call       002C058B
      002C04F0            8945 80           mov dword ptr ss:[ebp-80],eax
      002C04F3            8B45 80           mov eax,dword ptr ss:[ebp-80]
      002C04F6            0145 8C           add dword ptr ss:[ebp-74],eax
      002C04F9            E8 D1000000       call       002C05CF
      002C04FE            8945 A8           mov dword ptr ss:[ebp-58],eax
      002C0501            50                push eax
      002C0502            8B45 A8           mov eax,dword ptr ss:[ebp-58]
      002C0505            C700 33C033C0     mov dword ptr ds:[eax],C033C033
      002C050B            C740 04 33C0C300  mov dword ptr ds:[eax+4],0C3C033
      002C0512            58                pop eax
      002C0513            83BD D5FEFFFF 00  cmp dword ptr ss:[ebp-12B],0
      002C051A            75 1C             jnz short       002C0538
      002C051C            8BFB              mov edi,ebx
      002C051E            037D 8C           add edi,dword ptr ss:[ebp-74]
      002C0521            0FB685 D0FEFFFF   movzx eax,byte ptr ss:[ebp-130]
      002C0528            50                push eax
      002C0529            57                push edi
      002C052A            E8 5C000000       call       002C058B
      002C052F            8945 80           mov dword ptr ss:[ebp-80],eax
      002C0532            8B45 80           mov eax,dword ptr ss:[ebp-80]
      002C0535            0145 8C           add dword ptr ss:[ebp-74],eax


      002C0538            6A 2C             push 2C                              
      002C053A            8D85 D0FEFFFF     lea eax,dword ptr ss:[ebp-130]
      002C0540            50                push eax
      002C0541            8BC3              mov eax,ebx
      002C0543            0345 8C           add eax,dword ptr ss:[ebp-74]
      002C0546            50                push eax
      002C0547            FFD6              call esi                                   //将下一个ss数据结构copy入堆栈

      002C0549            83BD D1FEFFFF 00  cmp dword ptr ss:[ebp-12F],0               //通过检测ss.IATRva看是否全部处理完毕
      002C0550          ^ 0F85 27FDFFFF     jnz       002C027D                         //ss.IATRva不为0则跳上去处理
      002C0556            8B85 40FFFFFF     mov eax,dword ptr ss:[ebp-C0]
      002C055C            0345 AC           add eax,dword ptr ss:[ebp-54]
      002C055F            5F                pop edi
      002C0560            5E                pop esi
      002C0561            5B                pop ebx
      002C0562            8BE5              mov esp,ebp
      002C0564            5D                pop ebp
      002C0565            C3                retn


经过分析后,修复起来很方便,因为数据结构我们需要的信息都有

1. 还原IAT的真实名字
      002C034B          /E9 B0060000       jmp 002C0A00                                 //跳到自己的空间
      002C0350          |90                nop

      002C0A00           FF55 9C           call dword ptr ss:[ebp-64]                   //取得导入函数的地址
      002C0A03           8945 84           mov dword ptr ss:[ebp-7C],eax                //原句照抄
      002C0A06           8B95 D1FEFFFF     mov edx,dword ptr ss:[ebp-12F]               //ss.IATRva取出
      002C0A0C           0355 AC           add edx,dword ptr ss:[ebp-54]                //加上基址得到IAT的地址
      002C0A0F           8902              mov dword ptr ds:[edx],eax                   //导入函数地址写入IAT
      002C0A11         ^ E9 3AF9FFFF       jmp 002C0350                                 //跳回去

2. 还原变形的代码

      002C0414           66:C785 F4FEFFFF F>mov word ptr ss:[ebp-10C],15FF              //原来的90 e8 改成ff 15
      002C041D           8B85 D1FEFFFF      mov eax,dword ptr ss:[ebp-12F]              //取出相应的ss.IATRva
      002C0423           0345 AC            add eax,dword ptr ss:[ebp-54]               //得到IAT地址
      002C0426           90                 nop
      002C0427           90                 nop
      002C0428           90                 nop
      002C0429           90                 nop
      002C042A           90                 nop
      002C042B           90                 nop
      002C042C           90                 nop
      002C042D           90                 nop
      002C042E           90                 nop
      002C042F           90                 nop
      002C0430           90                 nop
      002C0431           90                 nop
      002C0432           90                 nop
      002C0433           90                 nop
      002C0434           90                 nop


      002C03B6           66:C785 EEFEFFFF E>mov word ptr ss:[ebp-112], 25FF             //e9改成ff 25也是一样,不过要多动几行
                                                                                          因为后面是inc eax,我们需要eax+2


经过这样处理后,代码段都修复完成, 输入表只有一个未能识别,那个就是MessageBoxW
由于netwowell大侠没有把mov IAT的部分打开,所以这里就没有仔细分析

谢谢大家看完