⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 cexportripper.cpp

📁 pe exe packer (must use vc2005 to compile)
💻 CPP
字号:
// Author:   Brandon LaCombe
// Date:     February 3, 2006
// License:  Public Domain
#include "CExportRipper.h"
#include "..\..\FileTools.h"
#include "..\..\remem.h"

// user defined types

// class version of the export directory
struct _EXPORT_DIRECTORY
{
    DWORD  dwTimeDateStamp;
    PSTR   pszName;
    DWORD  dwBase;
    DWORD  dwNumberOfFunctions;
    DWORD  dwNumberOfNames;
    PDWORD pdwFunctions;
    PSTR * ppszNames;
    PWORD  pwNameOrdinals;
};

// code start

// Class constructor
CExportRipper::CExportRipper()
{
    m_hHeap = GetProcessHeap();
    m_pExportDirectory = NULL;
    m_dwHeaderSize = 0;
    m_dwStringSize = 0;
    m_bStrip = FALSE;
    m_bMoveData = TRUE;
}

// Class destructor
CExportRipper::~CExportRipper()
{
    FreeExportDirectory();
}

// Writes the export directory.
VOID CExportRipper::Export(PVOID pvOutput, DWORD dwBaseRva)
{
    DWORD                   dwSize,
                            x;
    PBYTE                   pbHeaderPtr;
    PIMAGE_EXPORT_DIRECTORY pDirectory;
    PDWORD                  pdwNames,
                            pdwFunctions;
    PSTR                    pszStringPtr;

    if(m_bStrip == FALSE)
    {
        pDirectory = (PIMAGE_EXPORT_DIRECTORY)pvOutput;
        pszStringPtr = PSTR((PBYTE)pvOutput + m_dwHeaderSize);
        pbHeaderPtr = (PBYTE)pvOutput + sizeof(IMAGE_EXPORT_DIRECTORY);

        // fill out export directory
        ZeroMemory(pDirectory, sizeof(IMAGE_EXPORT_DIRECTORY));
        pDirectory->TimeDateStamp = m_pExportDirectory->dwTimeDateStamp;
        pDirectory->Base = m_pExportDirectory->dwBase;
        pDirectory->NumberOfFunctions = m_pExportDirectory->dwNumberOfFunctions;
        pDirectory->NumberOfNames = m_pExportDirectory->dwNumberOfNames;

        // copy name
        pDirectory->Name = DWORD((PBYTE)pszStringPtr - (PBYTE)pDirectory) + dwBaseRva;
        lstrcpyA(pszStringPtr, m_pExportDirectory->pszName);
        pszStringPtr += (lstrlenA(pszStringPtr) + 1);

        // copy function array
        pDirectory->AddressOfFunctions = DWORD(pbHeaderPtr - (PBYTE)pDirectory) + dwBaseRva;
        dwSize = pDirectory->NumberOfFunctions * sizeof(DWORD);
        CopyMemory(pbHeaderPtr, m_pExportDirectory->pdwFunctions, dwSize);

        // copy forwarded function names
        pdwFunctions = (PDWORD)pbHeaderPtr;
        for(x = 0; x < pDirectory->NumberOfFunctions; x++)
        {
            if(pdwFunctions[x] & 0x80000000)
            {
                lstrcpyA(pszStringPtr, (PSTR)UlongToPtr(pdwFunctions[x] & ~0x80000000));
                pdwFunctions[x] = DWORD((PBYTE)pszStringPtr - (PBYTE)pDirectory) + dwBaseRva;
                pszStringPtr += (lstrlenA(pszStringPtr) + 1);
            }
        }
        pbHeaderPtr += dwSize;

        if(pDirectory->NumberOfNames)
        {
            // copy name array and the name strings
            pdwNames = (PDWORD)pbHeaderPtr;
            pDirectory->AddressOfNames = DWORD((PBYTE)pdwNames - (PBYTE)pDirectory) + dwBaseRva;
            for(x = 0; x < pDirectory->NumberOfNames; x++)
            {
                pdwNames[x] = DWORD((PBYTE)pszStringPtr - (PBYTE)pDirectory) + dwBaseRva;
                lstrcpyA(pszStringPtr, m_pExportDirectory->ppszNames[x]);
                pszStringPtr += (lstrlenA(pszStringPtr) + 1);
            }
            pbHeaderPtr += (pDirectory->NumberOfNames * sizeof(DWORD));

            // copy ordinal array
            pDirectory->AddressOfNameOrdinals = DWORD(pbHeaderPtr - (PBYTE)pDirectory) + dwBaseRva;
            dwSize = pDirectory->NumberOfNames * sizeof(WORD);
            CopyMemory(pbHeaderPtr, m_pExportDirectory->pwNameOrdinals, dwSize);
        }
    }
}

// Extracts export directory from the input file.
VOID CExportRipper::ExtractExportDirectory()
{
    DWORD                   dwFunctionSize,
                            dwNameSize,
                            dwOrdinalSize,
                            dwStringSize,
                            x;
    PBYTE                   pbFunction,
                            pbMem;
    PIMAGE_EXPORT_DIRECTORY pDirectory;
    PDWORD                  pdwNameRvas;
    PSTR                    pszString;

    pDirectory = PIMAGE_EXPORT_DIRECTORY(m_pbExports);

    // calculate sizes
    dwFunctionSize = sizeof(DWORD) * pDirectory->NumberOfFunctions;
    dwNameSize = sizeof(DWORD) * pDirectory->NumberOfNames;
    dwOrdinalSize = sizeof(WORD) * pDirectory->NumberOfNames;
    m_dwHeaderSize = sizeof(IMAGE_EXPORT_DIRECTORY) + dwFunctionSize + dwNameSize + dwOrdinalSize;

    // allocate our export directory
    m_pExportDirectory = (PEXPORT_DIRECTORY)HeapAlloc(m_hHeap, HEAP_ZERO_MEMORY, sizeof(EXPORT_DIRECTORY));

    // copy simple fields to our export directory
    m_pExportDirectory->dwTimeDateStamp = pDirectory->TimeDateStamp;
    m_pExportDirectory->dwBase = pDirectory->Base;
    m_pExportDirectory->dwNumberOfFunctions = pDirectory->NumberOfFunctions;
    m_pExportDirectory->dwNumberOfNames = pDirectory->NumberOfNames;

    // copy the export directory name to our export directory
    pszString = (PSTR)RvaToPointer(m_pbFile, pDirectory->Name);
    dwStringSize = lstrlenA(pszString) + 1;
    m_pExportDirectory->pszName = (PSTR)HeapAlloc(m_hHeap, 0, dwStringSize);
    lstrcpyA(m_pExportDirectory->pszName, pszString);
    m_dwStringSize = dwStringSize;

    if(m_bMoveData)
        ZeroMemory(pszString, dwStringSize);

    // copy the function array to our export directory
    m_pExportDirectory->pdwFunctions = (PDWORD)HeapAlloc(m_hHeap, 0, dwFunctionSize);
    pbMem = RvaToPointer(m_pbFile, pDirectory->AddressOfFunctions);
    CopyMemory(m_pExportDirectory->pdwFunctions, pbMem, dwFunctionSize);

    if(m_bMoveData)
        ZeroMemory(pbMem, dwFunctionSize);

    // copy any forwarded functions
    for(x = 0; x < pDirectory->NumberOfFunctions; x++)
    {
        pbFunction = RvaToPointer(m_pbFile, m_pExportDirectory->pdwFunctions[x]);
        if(pbFunction >= m_pbExports && pbFunction < m_pbExports + m_dwExportsSize)
        {
            dwStringSize = lstrlenA((PSTR)pbFunction) + 1;
            m_pExportDirectory->pdwFunctions[x] = PtrToUlong(HeapAlloc(m_hHeap, 0, dwStringSize));
            lstrcpyA((PSTR)UlongToPtr(m_pExportDirectory->pdwFunctions[x]), (PSTR)pbFunction);
            m_pExportDirectory->pdwFunctions[x] |= 0x80000000;
            m_dwStringSize += dwStringSize;

            if(m_bMoveData)
                ZeroMemory(pbFunction, dwStringSize);
        }
    }

    // ensure at least one named export exists
    if(dwNameSize)
    {
        // copy the name ordinal array to our export directory
        m_pExportDirectory->pwNameOrdinals = (PWORD)HeapAlloc(m_hHeap, 0, dwOrdinalSize);
        pbMem = RvaToPointer(m_pbFile, pDirectory->AddressOfNameOrdinals);
        CopyMemory(m_pExportDirectory->pwNameOrdinals, pbMem, dwOrdinalSize);

        if(m_bMoveData)
            ZeroMemory(pbMem, dwOrdinalSize);

        // copy each string in the name array to our export directory
        m_pExportDirectory->ppszNames = (PSTR*)HeapAlloc(m_hHeap, 0, dwNameSize);
        pdwNameRvas = (PDWORD)RvaToPointer(m_pbFile, pDirectory->AddressOfNames);
        for(x = 0; x < pDirectory->NumberOfNames; x++)
        {
            pszString = (PSTR)RvaToPointer(m_pbFile, pdwNameRvas[x]);
            dwStringSize = lstrlenA(pszString) + 1;
            m_pExportDirectory->ppszNames[x] = (PSTR)HeapAlloc(m_hHeap, 0, dwStringSize);
            lstrcpyA(m_pExportDirectory->ppszNames[x], pszString);
            m_dwStringSize += dwStringSize;

            if(m_bMoveData)
                ZeroMemory(pszString, dwStringSize);
        }
        if(m_bMoveData)
            ZeroMemory(pdwNameRvas, dwNameSize);
    }
    if(m_bMoveData)
        ZeroMemory(pDirectory, sizeof(IMAGE_EXPORT_DIRECTORY));
}

// frees the export directory
VOID CExportRipper::FreeExportDirectory()
{
    DWORD x;

    if(m_pExportDirectory)
    {
        // free forwarded functions
        for(x = 0; x < m_pExportDirectory->dwNumberOfFunctions; x++)
        {
            if(m_pExportDirectory->pdwFunctions[x] & 0x80000000)
            {
                m_pExportDirectory->pdwFunctions[x] &= ~0x80000000;
                HeapFree(m_hHeap, 0, UlongToPtr(m_pExportDirectory->pdwFunctions[x] & ~0x80000000));
            }
        }

        // free function array
        HeapFree(m_hHeap, 0, m_pExportDirectory->pdwFunctions);

        if(m_pExportDirectory->dwNumberOfNames)
        {
            // free ordinal array
            HeapFree(m_hHeap, 0, m_pExportDirectory->pwNameOrdinals);

            // free name array and their names
            for(x = 0; x < m_pExportDirectory->dwNumberOfNames; x++)
                HeapFree(m_hHeap, 0, m_pExportDirectory->ppszNames[x]);
            HeapFree(m_hHeap, 0, m_pExportDirectory->ppszNames);
        }
        HeapFree(m_hHeap, 0, m_pExportDirectory);
        m_pExportDirectory = NULL;
    }
}

// Returns size of export directory.
DWORD CExportRipper::GetSize()
{
    DWORD dwSize = 0;

    if(m_bStrip == FALSE)
        dwSize = m_dwHeaderSize + m_dwStringSize;

    return dwSize;
}

// Loads input file and returns TRUE if an export directory exists.
BOOL CExportRipper::LoadFile(PBYTE pbFile)
{
    BOOL              bRet;
    DWORD             dwExportRva;
    PIMAGE_NT_HEADERS pNt;

    bRet = FALSE;
    m_pbFile = pbFile;
    pNt = PIMAGE_NT_HEADERS(pbFile + PIMAGE_DOS_HEADER(pbFile)->e_lfanew);
    dwExportRva = pNt->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].VirtualAddress;
    m_pbExports = RvaToPointer(pbFile, dwExportRva);
    m_dwExportsSize = pNt->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].Size;
    if(m_pbExports) bRet = TRUE;
    return bRet;
}

// Tells the ripper whether or not to null out the original export data.
VOID CExportRipper::MoveData(BOOL bMoveData)
{
    m_bMoveData = bMoveData;
}

// Driver for ripping the export directory from the input file.
VOID CExportRipper::Rip(PVOID pvFile)
{
    if(LoadFile((PBYTE)pvFile))
    {
        FreeExportDirectory();
        ExtractExportDirectory();
    }
}

// Sets strip flag.
VOID CExportRipper::Strip(BOOL bStrip)
{
    m_bStrip = bStrip;
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -