樣本Exforel的還原過程

它的解碼過程比較清晰:將存放在數據段中的文件數據進行解碼,然後構建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;
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章