它的解码过程比较清晰:将存放在数据段中的文件数据进行解码,然后构建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;
}