它的解碼過程比較清晰:將存放在數據段中的文件數據進行解碼,然後構建PE。(需要樣本可以留言)
#include <stdio.h>
#include <Windows.h>
void Decode(char * data, char * seed);//解碼函數
int main()
{
int i = 0;
LONG DistanceToMove = 0xc00+0x8;//文件偏移,這裏有點不一樣;多加的8是因爲後面SetFilePointer設置
//DistanceToMove時好像有點問題,前8個字節通過WinHex手動處理
DWORD dwRead = 0;
char seed[0x20] = { 0x80,0x40,0x15,0x30,0x4f,0xa3,0x52,0xb4,0x2b,0x3,0xc3,0x6e,0x9f,0x53,0x10,0x93,0x0 };
char data[0x10] = { 0x0 };//0x13,0x21,0x8f,0xed,0x74,0x81,0xb5,0x31,
HANDLE hFile = NULL,hNewFile=NULL;
hFile = CreateFile(L"original.bin", //原文件數據
GENERIC_READ, //讀
FILE_SHARE_READ,
NULL,
OPEN_EXISTING,
FILE_ATTRIBUTE_NORMAL ,
NULL);
hNewFile = CreateFile(L"decoded.bin", //解碼後的文件
GENERIC_WRITE,
FILE_SHARE_WRITE,
NULL,
CREATE_ALWAYS,
FILE_ATTRIBUTE_NORMAL,
NULL);
if (!hFile)
{
printf("CreateFile fails\n");
return 0;
}
else
{
printf("open existing file succeed!\n");
}
/*if (!WriteFile(hNewFile, data, 0x8, &dwRead, NULL))
{
printf("WriteFile fails:%x", GetLastError());
}*/
while (i <0x12bf ) //0x12c0-0x1 循環的次數
{
if (!SetFilePointer(hFile,
DistanceToMove, //讀數據的位置需要從樣本中尋找--->0xc00
NULL, FILE_BEGIN) ||
!ReadFile(hFile, data, 0x8, &dwRead, NULL))
{
printf("ReadFile fails:%x\n", GetLastError());
return 0;
}
else
{
Decode(data, seed);
if (!hNewFile)
{
printf("openfile fails\n");
return 0;
}
else //write data
{
if (!SetFilePointer(hNewFile,DistanceToMove-0xc00, NULL, FILE_BEGIN )) //設置位置
{
printf("SetFilePointer FAILS:%x\n", GetLastError());
}
else if (!WriteFile(hNewFile, data, 0x8, &dwRead, NULL)) //寫入數據
{
printf("WriteFile fails:%x", GetLastError());
}
}
//printf(" %x\n", *(DWORD *)data);
//printf("ReadFile succeed!\n");
}
memset(data, 0x0,0x8);//存儲的數據 重新爲0
DistanceToMove = DistanceToMove + 8; //每次寫入8字節的數據
i++;
}
CloseHandle(hNewFile);
printf("all finished\n");
CloseHandle(hFile);
return 0;
}
void Decode(char * data, char * seed) //data要解碼的數據,seed用於相關運位算
{
unsigned int v2; // ecx@1
unsigned int result; // eax@1
int v4; // edi@2
unsigned int v5; // ebx@2
unsigned int v6; // [sp+8h] [bp-4h]@1
v2 = *(DWORD *)data;
result = *(DWORD *)(data + 4);
v6 = -957401312;
do
{
v4 = *(DWORD *)(seed + 4 * ((v6 >> 11) & 3)) + (16 * v2 ^ (v2 >> 5));
v5 = v6;
v6 += 1640531527;
result -= (v2 ^ v5) + v4;
v2 -= (result ^ v6) + *( DWORD *)(seed + 4 * (v6 & 3)) + (16 * result ^ (result >> 5));
} while (v6);
*(DWORD *)data = v2;
*(DWORD *)(data + 4) = result;
}