xhn1002 发表于 2008-9-22 17:48:22

简单壳的脱壳

壳本身比较简单只是简单的加密连压缩也没有比较适合我这样的新手
样本在附件 注意 样本本身是个 木马运行后 会释放一个模拟键盘的驱动
有虚拟机的最好在虚拟机里调试 没有虚拟机的按照下文 一步一步跟
基本不会出现问题自我感觉这个壳分析的应该很详尽了

[ 本帖最后由 xhn1002 于 2008-9-22 18:11 编辑 ]

xhn1002 发表于 2008-9-22 17:54:14

00401000 > $64:A1 3000000>MOV EAX,DWORD PTR FS:            ; ptr PEB
00401006   .8B40 0C       MOV EAX,DWORD PTR DS:                               ;ptr _PEB_LDR_DATA
00401009   .8B70 1C       MOV ESI,DWORD PTR DS:      ;InInitializationOrderModuleList
0040100C   .AD            LODS DWORD PTR DS:            得到ntdll节点
0040100D   .8B58 08       MOV EBX,DWORD PTR DS:         得到kernel32的基址
00401010   .B9 FC304000   MOV ECX,8fc59a80.004030FC                ;ASCII "CloseHandle"
00401015   .E8 45000000   CALL 8fc59a80.0040105F               ;得到函数地址

00401071   > \FF35 00304000 PUSH DWORD PTR DS:               ; /MemSize = 1800 (6144.)
00401077   .6A 40         PUSH 40                                  ; |Flags = GPTR
00401079   .E8 B0010000   CALL <JMP.&kernel32.GlobalAlloc>         ; \GlobalAlloc   ;分配内存
0040107E   .85C0          TEST EAX,EAX
00401080   .0F84 90010000 JE 8fc59a80.00401216

00401087   .BE 70404000   MOV ESI,8fc59a80.00404070
0040108C   .8BF8          MOV EDI,EAX
0040108E   .8B0D 00304000 MOV ECX,DWORD PTR DS:
00401094   .F3:A4         REP MOVS BYTE PTR ES:,BYTE PTR DS:第4节 1800h字节的数据拷到新分配的内存

004010DE   .8B3424      MOV ESI,DWORD PTR SS:               
004010E1   .8B3C24      MOV EDI,DWORD PTR SS:
004010E4   .8B0D 00304000 MOV ECX,DWORD PTR DS:
004010EA   .D1E9          SHR ECX,1
004010EC   .66:832D 04304>SUB WORD PTR DS:,3A
004010F4   >66:AD         LODS WORD PTR DS:
004010F6   .86C4          XCHG AH,AL
004010F8   .66:3305 04304>XOR AX,WORD PTR DS:
004010FF   .66:FF05 04304>INC WORD PTR DS:
00401106   .66:AB         STOS WORD PTR ES:                  
00401108   .^ E2 EA         LOOPD SHORT 8fc59a80.004010F4            解密完后 得到一个新的PE
/////////////////////////////////////////////////////////////////////////////////////
//        00142BD84D 5A 90 00 03 00 00 00 04 00 00 00 FF FF 00 00MZ?......
有些字符敏感?被截了?

[ 本帖最后由 xhn1002 于 2008-9-22 18:08 编辑 ]

xhn1002 发表于 2008-9-22 17:55:05

00401117   .85C0          TEST EAX,EAX
00401119   .0F84 F7000000 JE 8fc59a80.00401216
0040111F   .BE 2F114000   MOV ESI,8fc59a80.0040112F
00401124   .8BF8          MOV EDI,EAX
00401126   .B9 E7000000   MOV ECX,0E7
0040112B   .F3:A4         REP MOVS BYTE PTR ES:,BYTE PTR DS:;将JMP EAX后的指令拷到内存中去
0040112D   .FFE0          JMP EAX

00144608    8B3C24          MOV EDI,DWORD PTR SS:                  ;DOS header
0014460B    037F 3C         ADD EDI,DWORD PTR DS:               ;PE header
0014460E    8BF7            MOV ESI,EDI
00144610    8B7F 34         MOV EDI,DWORD PTR DS:               ;IMAGEBASE
00144613    8B76 50         MOV ESI,DWORD PTR DS:               ;SizeOfImage               
00144616    03F7            ADD ESI,EDI

0014464C    8B3424          MOV ESI,DWORD PTR SS:                                                                        ;DOS header
0014464F    8BFE            MOV EDI,ESI                        
00144651    037F 3C         ADD EDI,DWORD PTR DS:               ;PE header
00144654    8BCF            MOV ECX,EDI
00144656    8B7F 34         MOV EDI,DWORD PTR DS:               ;IMAGEBASE
00144659    8B49 54         MOV ECX,DWORD PTR DS:               ;SizeOfHeaders
0014465C    F3:A4         REP MOVS BYTE PTR ES:,BYTE PTR DS:;将头和节表 复制到IMAGEBASE 一般为400000H
0014465E    8B0C24          MOV ECX,DWORD PTR SS:                  ;DOS header
00144661    0349 3C         ADD ECX,DWORD PTR DS:               ;PE header
00144664    8BD9            MOV EBX,ECX
00144666    8BD1            MOV EDX,ECX
00144668    8B0424          MOV EAX,DWORD PTR SS:                  ;DOS header
0014466B    8B5B 34         MOV EBX,DWORD PTR DS:               ;IMAGEBASE
0014466E    66:8B49 06      MOV CX,WORD PTR DS:                  ;NumberOfSections
00144672    81C2 F8000000   ADD EDX,0F8                                 定位到节表处

00144678    51            PUSH ECX
00144679    8B72 14         MOV ESI,DWORD PTR DS:               PointerToRawData
0014467C    03F0            ADD ESI,EAX                                 文件中节的偏移
0014467E    8B7A 0C         MOV EDI,DWORD PTR DS:                VirtualAddress
00144681    03FB            ADD EDI,EBX                                 IMAGEBASE+VirtualAddress= 节的VA
00144683    8B4A 10         MOV ECX,DWORD PTR DS:               SizeOfRawData
00144686    F3:A4         REP MOVS BYTE PTR ES:,BYTE PTR DS: 依次复制节
00144688    83C2 28         ADD EDX,28
0014468B    59            POP ECX
0014468C    66:49         DEC CX
0014468E^ 75 E8         JNZ SHORT 00144678

00144690    8BFB            MOV EDI,EBX                                 ;IMAGEBASE   
00144692    037F 3C         ADD EDI,DWORD PTR DS:               ;PE header
00144695    8BBF 80000000   MOV EDI,DWORD PTR DS:               ;IMAGE_DIRECTORY_ENTRY_IMPORT
0014469B    03FB            ADD EDI,EBX                                 ;导入表的VA
0014469D    8B4F 0C         MOV ECX,DWORD PTR DS:                ;IMAGE_IMPORT_DESCRIPTOR.Name1
001446A0    83F9 00         CMP ECX,0
001446A3    74 34         JE SHORT 001446D9                                             
001446A5    03CB            ADD ECX,EBX                                 得到Dll名
001446A7    51            PUSH ECX
001446A8    FF5424 18       CALL DWORD PTR SS:                  LoadLibraryA
001446AC    85C0            TEST EAX,EAX
001446AE    74 39         JE SHORT 001446E9
001446B0    8BE8            MOV EBP,EAX                                 
001446B2    8B77 10         MOV ESI,DWORD PTR DS:               IMAGE_IMPORT_DESCRIPTOR.FirstThunk
001446B5    03F3            ADD ESI,EBX                                 ptr IMAGE_THUNK_DATA
001446B7    83C7 14         ADD EDI,14                                  ptr next IMAGE_IMPORT_DESCRIPTOR
001446BA    8B06            MOV EAX,DWORD PTR DS:                  这里忽略了 以符号名导出的情况
001446BC    03C3            ADD EAX,EBX                                 ptr IMAGE_IMPORT_BY_NAME
001446BE    83C0 02         ADD EAX,2
001446C1    50            PUSH EAX
001446C2    55            PUSH EBP
001446C3    FF5424 20       CALL DWORD PTR SS:                  GetProAddress
001446C7    85C0            TEST EAX,EAX
001446C9    74 1E         JE SHORT 001446E9
001446CB    8906            MOV DWORD PTR DS:,EAX
001446CD    83C6 04         ADD ESI,4
001446D0    8B06            MOV EAX,DWORD PTR DS:                  esi ptr next IMAGE_THUNK_DATA
001446D2    83F8 00         CMP EAX,0
001446D5^ 74 C6         JE SHORT 0014469D
001446D7^ EB E1         JMP SHORT 001446BA

001446D9    8B0424          MOV EAX,DWORD PTR SS:
001446DC    0340 3C         ADD EAX,DWORD PTR DS:
001446DF    8B40 28         MOV EAX,DWORD PTR DS:
001446E2    03C3            ADD EAX,EBX
001446E4    83C4 28         ADD ESP,28
001446E7    FFE0            JMP EAX                                     Entrypoint


根据整个壳的分析 脱壳只需要把第4节共1800H的字节解密出来就可以了



#include        <stdio.h>
#include        <stdlib.h>
#include        <windows.h>

#define        SIZE        0x1800
#define KEY                0x5a4d

BOOL decode(WORD* mem, DWORD key);
void main()
{
        char cFileName;
        HANDLE hFile, hNewFile;
        HGLOBAL        hGlobal;
        DWORD        dwRet;
        DWORD        dwLen;

        hGlobal = GlobalAlloc(GPTR,SIZE);
        printf("file name: ");
        scanf("%s",cFileName);
        hFile = CreateFile(cFileName, GENERIC_READ, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
        if (hFile == NULL)
        {
                printf("open error\n");
                return;
        }
        dwRet = SetFilePointer(hFile,0xc70,NULL,FILE_BEGIN);
        if (dwRet == -1)
        {
                printf("%d\n", GetLastError());
                return;
        }
        ReadFile(hFile, hGlobal, SIZE, &dwLen, NULL);
        //解密例程
        decode((WORD*)hGlobal,KEY);
        hNewFile = CreateFile("unpack.exe", GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
        WriteFile(hNewFile, (PVOID)hGlobal, SIZE, &dwLen, NULL);
        CloseHandle(hNewFile);
        GlobalFree(hGlobal);
        CloseHandle(hFile);
}

BOOL decode(WORD* mem, DWORD key)
{
        int i;
        key -= 0x3A;
        for (i = 0;i < SIZE/2; i++)
        {
                *mem = *mem >> 8 | *mem << 8;
                *mem ^= key;
                key++;
                mem++;
        }
        return TRUE;
}

buganxin 发表于 2008-9-23 13:13:59

学习谢谢!
页: [1]
查看完整版本: 简单壳的脱壳