简单壳的脱壳
壳本身比较简单只是简单的加密连压缩也没有比较适合我这样的新手样本在附件 注意 样本本身是个 木马运行后 会释放一个模拟键盘的驱动
有虚拟机的最好在虚拟机里调试 没有虚拟机的按照下文 一步一步跟
基本不会出现问题自我感觉这个壳分析的应该很详尽了
[ 本帖最后由 xhn1002 于 2008-9-22 18:11 编辑 ] 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 编辑 ] 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;
} 学习谢谢!
页:
[1]