Добавление новой секции в EXE

автор | 21 Декабрь, 2008
рубрики RCE программирование Комментарии к записи Добавление новой секции в EXE отключены

Код на C++, добавление новой секции в PE файл

/////////////////////////////////////////////////////////////////

//
// Coded by NEOx <NEOx@Pisem.net>
//
/////////////////////////////////////////////////////////////////

#define WIN32_LEAN_AND_MEAN        // Exclude rarely-used stuff from Windows headers
#include <windows.h>
#include "MMFiles.h"

#ifdef NDEBUG
#pragma optimize ("gsy",on)
#pragma comment (linker,"/IGNORE:4078 /IGNORE:4089")
#pragma comment (linker,"/RELEASE")
#pragma comment (linker,"/merge:.rdata=.data")
#pragma comment (linker,"/merge:.text=.data")
#pragma comment (linker,"/merge:.reloc=.data")
#if _MSC_VER >= 1000
#pragma comment (linker,"/FILEALIGN:0×200")
#endif
#endif
#pragma comment (linker,"/ENTRY:main")

#define DEFAULT_NEW_SECTION_CHARACTERISTICS    IMAGE_SCN_CNT_CODE | IMAGE_SCN_CNT_INITIALIZED_DATA | IMAGE_SCN_CNT_UNINITIALIZED_DATA | IMAGE_SCN_MEM_EXECUTE | IMAGE_SCN_MEM_READ | IMAGE_SCN_MEM_WRITE

#define MIN (a,b)  ((a)<(b)?(a):(b))
#define RALIGN (dwToAlign, dwAlignOn) ((dwToAlign % dwAlignOn == 0) ? dwToAlign : dwToAlign — (dwToAlign % dwAlignOn) + dwAlignOn)
#if !defined (MakePtr)
#define MakePtr (cast, ptr, addValue) (cast)( (DWORD)(ptr) + (DWORD)(addValue))
#endif

BOOL AddSectionHeader (PIMAGE_SECTION_HEADER pSH);
BOOL IsRoom (LPVOID lpMem);
PIMAGE_SECTION_HEADER GetLastSection (LPVOID lpMap);
DWORD CalcRealSizeOfImage (LPVOID m_Map);
DWORD CalcRealHeaderSize (PIMAGE_NT_HEADERS pNT);

BOOL LoadSectionFromFile (CHAR *szFilePath, LPVOID lpData, DWORD dwDataSize);

int main ()
{
    BYTE sb[20023] = {'N', 'E', 'O', 'x'};
    LoadSectionFromFile ("c.exe", sb, sizeof (sb));
    return 0;
}

BOOL AddSectionHeader (LPVOID lpMem, PIMAGE_SECTION_HEADER pSH)
{
    PIMAGE_DOS_HEADER       pDosH;
    PIMAGE_NT_HEADERS       pNTH;
    PIMAGE_SECTION_HEADER   pLastH;

    if (!IsRoom (lpMem))
    {
        MessageBox (GetActiveWindow (), "Not enough room for a new section available !", "Error", MB_ICONERROR);
        return FALSE;
    }

    pDosH = (PIMAGE_DOS_HEADER) lpMem;
    pNTH  = (PIMAGE_NT_HEADERS)((DWORD) pDosH + pDosH->e_lfanew);

    __try
    {
        pLastH = GetLastSection (lpMem);
        pLastH++;
        CopyMemory (pLastH, pSH, sizeof (IMAGE_SECTION_HEADER));
        pNTH->FileHeader.NumberOfSections++;
    }
    __except (EXCEPTION_EXECUTE_HANDLER)
    {
        MessageBox (GetActiveWindow (), "Access violation !", "Error", MB_OK | MB_ICONERROR);
        return FALSE;
    }

    return TRUE;
}

BOOL IsRoom (LPVOID lpMem)
{
    PIMAGE_DOS_HEADER       pDosH;
    PIMAGE_NT_HEADERS       pNTH;
    PIMAGE_SECTION_HEADER   pSH;
    DWORD                   dwNumOfSect, dwHeadersSize;

    pDosH = (PIMAGE_DOS_HEADER) lpMem;
    pNTH  = (PIMAGE_NT_HEADERS)((DWORD) pDosH + pDosH->e_lfanew);
    pSH = IMAGE_FIRST_SECTION (pNTH);

    dwNumOfSect = pNTH->FileHeader.NumberOfSections;
    dwHeadersSize = sizeof (IMAGE_NT_HEADERS) + (dwNumOfSect * sizeof (IMAGE_SECTION_HEADER)) + sizeof (IMAGE_SECTION_HEADER);

    if (dwHeadersSize > pNTH->OptionalHeader.SizeOfHeaders)
        return FALSE;
    return TRUE;
}

PIMAGE_SECTION_HEADER GetLastSection (LPVOID lpMap)
{
    WORD                  u;
    PIMAGE_DOS_HEADER pDosh;
    PIMAGE_NT_HEADERS pPeh;
    IMAGE_SECTION_HEADER  *pSH;

    __try
    {
        pDosh = (PIMAGE_DOS_HEADER) lpMap;
        pPeh = (PIMAGE_NT_HEADERS)((DWORD) pDosh + pDosh->e_lfanew);
        pSH = IMAGE_FIRST_SECTION32 (pPeh);
        for (u = 0; u < pPeh->FileHeader.NumberOfSections — 1; u++) ++pSH;
            return pSH;
    }
    __except (EXCEPTION_EXECUTE_HANDLER)
    {
        MessageBox (GetActiveWindow (), "Access violation !", "Error", MB_OK | MB_ICONERROR);
        return NULL;
    }
}

DWORD CalcRealSizeOfImage (LPVOID m_Map)
{
    DWORD dwCorrSoI = 0;
    DWORD dwNumOfSect = 0;
    PIMAGE_DOS_HEADER pDosh     = {0};
    PIMAGE_NT_HEADERS pPeh      = {0};
    IMAGE_SECTION_HEADER  *pSH;
    pDosh = (PIMAGE_DOS_HEADER) m_Map;

    pPeh = (PIMAGE_NT_HEADERS)((DWORD) pDosh + pDosh->e_lfanew);
    pSH  = IMAGE_FIRST_SECTION32 (pPeh);
    dwNumOfSect = pPeh->FileHeader.NumberOfSections;

    for (WORD i = 0; i < dwNumOfSect; i++)
    {
        if ((pSH->VirtualAddress + pSH->Misc.VirtualSize) > dwCorrSoI)
            dwCorrSoI = pSH->VirtualAddress + pSH->Misc.VirtualSize;
        ++pSH;
    }

    return dwCorrSoI;
}

DWORD CalcRealHeaderSize (PIMAGE_NT_HEADERS pNT)
{
    DWORD                  dwHSize;
    UINT                   i;
    IMAGE_SECTION_HEADER   *pS;

    if (!pNT->FileHeader.NumberOfSections)
        return ((PIMAGE_NT_HEADERS32) pNT) ->OptionalHeader.SizeOfHeaders;

    dwHSize = 0xFFFFFFFF;
    pS = IMAGE_FIRST_SECTION (pNT);
    for (i = 0; i < pNT->FileHeader.NumberOfSections; i++)
    {
        if (pS->PointerToRawData)
            dwHSize = MIN (dwHSize, pS->PointerToRawData);
        ++pS;
    }

    // Fix
    return (dwHSize > 0×00001000) ? 0×00001000 : dwHSize;
}

BOOL LoadSectionFromFile (CHAR *szFilePath, LPVOID lpData, DWORD dwDataSize)
{
    CMMFiles m_File;
    PIMAGE_DOS_HEADER pDosH;
    PIMAGE_NT_HEADERS pNTH;
    PIMAGE_SECTION_HEADER pSH;

    IMAGE_SECTION_HEADER  pNewSH[1];

    if (!m_File.MMMakeMappedFile (szFilePath))
    {
        // File I/O error
        return FALSE;
    }

    //
    // Если юзаешь мою Dll'ку (rebpe32.dll), тогда расскомментируй вызов
    // этой функции. Потому что лучше выровнять все секции.
    //
    // DumpFixer32 (m_File.m_pMap);

    if (!m_File.MMSetFileSize (m_File.MMGetFileSize () + dwDataSize))
    {
        // Clean up
        m_File.MMEndMappedFile ();
        return FALSE;
    }

    try
    {
        // Copy new section data
        pSH = GetLastSection (m_File.m_pMap);
        // !!! BUG !!!
        CopyMemory (MakePtr (LPVOID, m_File.m_pMap, (pSH->PointerToRawData + pSH->SizeOfRawData)), lpData, dwDataSize);
    }
    catch (...)
    {
        MessageBox (GetActiveWindow (), "Access violation !", "Error", MB_OK | MB_ICONERROR);
        return FALSE;
    }

    pDosH = (PIMAGE_DOS_HEADER) m_File.m_pMap;
    pNTH  = (PIMAGE_NT_HEADERS)((DWORD) pDosH + pDosH->e_lfanew);

    ZeroMemory (&pNewSH, sizeof (IMAGE_SECTION_HEADER));
    lstrcpy ((CHAR *) pNewSH[0].Name, ".NewSect");

    pNewSH[0].Characteristics  = DEFAULT_NEW_SECTION_CHARACTERISTICS;
    pNewSH[0].Misc.VirtualSize = dwDataSize/*RALIGN (dwDataSize, pNTH->OptionalHeader.SectionAlignment)*/;
    pNewSH[0].VirtualAddress   = pSH->VirtualAddress + pSH->Misc.VirtualSize;
    pNewSH[0].SizeOfRawData    = dwDataSize;
    pNewSH[0].PointerToRawData = pSH->PointerToRawData + pSH->SizeOfRawData;

    if (!AddSectionHeader (m_File.m_pMap, pNewSH))
    {
        // Clean up
        m_File.MMEndMappedFile ();
        return FALSE;
    }

    pNTH->OptionalHeader.SizeOfImage = CalcRealSizeOfImage (m_File.m_pMap);
    pNTH->OptionalHeader.SizeOfHeaders = CalcRealHeaderSize (pNTH);

    // Clean up
    m_File.MMEndMappedFile ();
    return TRUE;
}

Автор: NEOx

Оценить эту тему:
1 звезда2 звезды3 звезды4 звезды5 звезд (4 голосов, средний: 4,00 из 5)
Loading...Loading...
Популярность: 6 169 просмотров
Вы можете следить за любыми ответами на эту запись через RSS 2.0 feed. Комментарии в настоящее время закрыты.