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

📄 portableexecutable.cpp

📁 一个用BCB写的壳!
💻 CPP
📖 第 1 页 / 共 2 页
字号:
// PortableExecutable.cpp: implementation of the CPortableExecutable class.
//
//////////////////////////////////////////////////////////////////////

#include "StdAfx.h"
#include "PortableExecutable.h"

using namespace std;

namespace PE {

//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////

CPortableExecutable::CPortableExecutable()
: m_ddDebug(this), m_ddExport(this), m_ddImport(this), m_ddCopyright(this), m_ddResource(this)
{
    m_flIsLoaded = FALSE;
}

CPortableExecutable::~CPortableExecutable()
{
    Cleanup();
}

PE_ERROR CPortableExecutable::LoadByHandle(HANDLE hFile)
{
    DWORD dwStubStart;
    CSection sctSection;
    DWORD dwCount;
    PIMAGE_NT_HEADERS pNtHeaders;
    HANDLE hMap;
    LPBYTE pMap;

    // Clean up before loading
    Cleanup();

    if (hFile == INVALID_HANDLE_VALUE)
        return(PE_OPEN);

    // Make sure file isn't empty
    FileSize = GetFileSize(hFile, NULL);
    if (FileSize == 0) {
        return(PE_SIZE);
    }

    // Try to create file mapping
    hMap = CreateFileMapping(hFile, NULL, PAGE_READONLY, 0, 0, NULL);

    if (hMap == NULL) {
        return(PE_MAP);
    }

    // Get a mapping view of the file
    pMap = (LPBYTE )MapViewOfFile(hMap, FILE_MAP_READ, 0, 0, 0);

    if (pMap == NULL) {
        CloseHandle(hMap);
        return(PE_VIEW);
    }

    // Get DOS header
    if (IsBadReadPtr(pMap, sizeof(IMAGE_DOS_HEADER))) {
        UnmapViewOfFile(pMap);
        CloseHandle(hMap);
        return(PE_MEM);
    }

    // Check if MZ executable
    m_Headers.SetDos(*(PIMAGE_DOS_HEADER )pMap);
    if (m_Headers.m_hdrDos.e_magic != IMAGE_DOS_SIGNATURE) {
        UnmapViewOfFile(pMap);
        CloseHandle(hMap);
        return(PE_NOTMZ);
    }

    // Check if this is a new executable
    if (m_Headers.m_hdrDos.e_lfanew == 0) {
        // No new header
        UnmapViewOfFile(pMap);
        CloseHandle(hMap);
        return(PE_NOTPE);
    }

    // Get NT headers
    pNtHeaders = (PIMAGE_NT_HEADERS )(pMap + m_Headers.m_hdrDos.e_lfanew);

    if (IsBadReadPtr(pNtHeaders, sizeof(IMAGE_NT_HEADERS))) {
        UnmapViewOfFile(pMap);
        CloseHandle(hMap);
        return(PE_NOTPE);
    }

    // Check if PE executable
    m_Headers.SetNt(*pNtHeaders);
    if (m_Headers.m_hdrNt.Signature != IMAGE_NT_SIGNATURE) {
        UnmapViewOfFile(pMap);
        CloseHandle(hMap);
        return(PE_NOTPE);
    }

    // Get DOS stub
    dwStubStart = (m_Headers.m_hdrDos.e_cs << 4) + m_Headers.m_hdrDos.e_ip + (m_Headers.m_hdrDos.e_cparhdr << 4);
    if (dwStubStart >= (65536 << 4)) dwStubStart -= (65536 << 4);

    m_Headers.SetHeaderSize((signed long )dwStubStart < sizeof(IMAGE_DOS_HEADER) ? sizeof(IMAGE_DOS_HEADER) : dwStubStart);
    m_DOSStub.Set((pMap + dwStubStart), ((m_Headers.m_hdrDos.e_cp - 1) * 512) + m_Headers.m_hdrDos.e_cblp - dwStubStart);

    // Load sections
    for (dwCount = 0; dwCount < m_Headers.m_hdrNt.FileHeader.NumberOfSections; dwCount++) {

        if (IsBadReadPtr((LPBYTE )pNtHeaders + pNtHeaders->FileHeader.SizeOfOptionalHeader + (sizeof(IMAGE_SECTION_HEADER) * dwCount) + sizeof(DWORD) + sizeof(IMAGE_FILE_HEADER), sizeof(IMAGE_SECTION_HEADER)) == FALSE) {

            sctSection.SetHeader(*(PIMAGE_SECTION_HEADER )((LPBYTE )pNtHeaders + pNtHeaders->FileHeader.SizeOfOptionalHeader + (sizeof(IMAGE_SECTION_HEADER) * dwCount) + sizeof(DWORD) + sizeof(IMAGE_FILE_HEADER)));

            if (sctSection.m_hdr.SizeOfRawData && sctSection.m_hdr.PointerToRawData) {
                if (IsBadReadPtr(&pMap[sctSection.m_hdr.PointerToRawData], sctSection.m_hdr.SizeOfRawData) == FALSE)
                    sctSection.SetData(&pMap[sctSection.m_hdr.PointerToRawData], sctSection.m_hdr.SizeOfRawData);
            }

            m_lstSections.push_back(sctSection);
        }
    }

    // We don't need the file anymore
    UnmapViewOfFile(pMap);
    CloseHandle(hMap);

    // Set the Loaded flag
    m_flIsLoaded = TRUE;

    // Fix various stuff
    FixSectionOffsets();
    FixSectionSizes();
    FixImageSize();
    m_Headers.FixSizeOfHeaders();

    // Set up data directories
    m_ddDebug.Assign(GetDataAtRVA(m_Headers.m_hdrNt.OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_DEBUG].VirtualAddress), m_Headers.m_hdrNt.OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_DEBUG].Size);
    m_ddExport.Assign(GetDataAtRVA(m_Headers.m_hdrNt.OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].VirtualAddress), m_Headers.m_hdrNt.OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].Size);
    m_ddImport.Assign(GetDataAtRVA(m_Headers.m_hdrNt.OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].VirtualAddress), m_Headers.m_hdrNt.OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].Size);
    m_ddCopyright.Assign(GetDataAtRVA(m_Headers.m_hdrNt.OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_ARCHITECTURE].VirtualAddress), m_Headers.m_hdrNt.OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_ARCHITECTURE].Size);
    m_ddResource.Assign(GetDataAtRVA(m_Headers.m_hdrNt.OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_RESOURCE].VirtualAddress), m_Headers.m_hdrNt.OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_RESOURCE].Size);

    return(PE_NONE);
}

// Load a portable executable
PE_ERROR CPortableExecutable::Load(LPSTR pszFileName)
{
    HANDLE hFile;


    // Clean up before loading
    Cleanup();

    // Try to open the file
    hFile = CreateFile(pszFileName, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
    if (hFile)
    {
      PE_ERROR peerror = LoadByHandle (hFile);
      CloseHandle (hFile);
      strcpy (FileName, pszFileName);
      return peerror;
    }
    return(PE_OPEN);
}

// Write portable executable
PE_ERROR CPortableExecutable::Write(LPSTR pszFileName, BOOL flSetChecksum)
{
    HANDLE hFile;
    sctIterator i;
    DWORD dwAlign;
    DWORD dwCurrent;
    CSection *pCurrentSection;
    LPBYTE pStub;
    BYTE byNull;
    DWORD dwWritten;

    // Change checksum
    if (flSetChecksum == TRUE)
        m_Headers.m_hdrNt.OptionalHeader.CheckSum = CalcCheckSum();

    // Check if a file was loaded
    if (m_flIsLoaded == FALSE)
        return(PE_LOAD);

    // Open output file
    hFile = CreateFile(pszFileName, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);

    if (hFile == NULL)
        return(PE_OPEN);

    // Write MZ header
    WriteFile(hFile, &m_Headers.m_hdrDos, m_Headers.GetHeaderSize(), &dwWritten, NULL);

    // Write DOS stub
    if (m_DOSStub.Get(NULL)) {
        pStub = new BYTE [m_DOSStub.Get(NULL)];
        if (pStub) {
            m_DOSStub.Get(pStub);
            WriteFile(hFile, pStub, m_DOSStub.Get(NULL), &dwWritten, NULL);
            delete [] pStub;
        }
    }

    // Seek to new PE header offset
    SetFilePointer(hFile, m_Headers.m_hdrDos.e_lfanew, NULL, FILE_BEGIN);

    // Write PE header
    WriteFile(hFile, &m_Headers.m_hdrNt, sizeof(IMAGE_NT_HEADERS), &dwWritten, NULL);

    // Write section headers
    for (i = m_lstSections.begin(); i != m_lstSections.end(); i++) {
        WriteFile(hFile, &(*i).m_hdr, sizeof(IMAGE_SECTION_HEADER), &dwWritten, NULL);
    }

    // Pad to alignment
    dwCurrent = SetFilePointer(hFile, 0L, NULL, FILE_CURRENT);

    dwAlign = m_Headers.FileAlignment(dwCurrent);
    byNull = 0;

    while (dwCurrent < dwAlign) {
        WriteFile(hFile, &byNull, 1, &dwWritten, NULL);
        dwCurrent++;
    }

    // Write section data
    for (i = m_lstSections.begin(); i != m_lstSections.end(); i++) {
        pCurrentSection = &(*i);

        if (pCurrentSection->m_hdr.PointerToRawData && pCurrentSection->m_hdr.SizeOfRawData) {
            SetFilePointer(hFile, pCurrentSection->m_hdr.PointerToRawData, NULL, FILE_BEGIN);
            if (IsBadReadPtr(pCurrentSection->m_pData, pCurrentSection->m_hdr.SizeOfRawData) == FALSE)
                WriteFile(hFile, pCurrentSection->m_pData, pCurrentSection->m_hdr.SizeOfRawData, &dwWritten, NULL);
        }
    }

    // Close file
    CloseHandle(hFile);

    return(PE_NONE);
}

// Clean up variables
void CPortableExecutable::Cleanup()
{
    // Free section list
    if (m_lstSections.empty() == FALSE)
        m_lstSections.clear();

    // Reset Loaded flag
    m_flIsLoaded = FALSE;
}

// Relative Virtual Address to File Offset
DWORD CPortableExecutable::RVA2FO(DWORD dwRVA)
{
    CSection *pSection;

    // Check if a file was loaded
    if (m_flIsLoaded == FALSE)
        return(PE_INVALID);

    pSection = GetSectionByRVA(dwRVA);

    if (pSection) {
        // Convert RVA to File Offset
        dwRVA -= pSection->m_hdr.VirtualAddress;
        dwRVA += pSection->m_hdr.PointerToRawData;

        // In section but not in file
        if (dwRVA >= (pSection->m_hdr.PointerToRawData + pSection->m_hdr.SizeOfRawData))
            dwRVA = PE_INVALID;

    } else {
        dwRVA = PE_INVALID;
    }

    return(dwRVA);
}

// Virtual Address to File Offset
DWORD CPortableExecutable::VA2FO(DWORD dwVA)
{
    // Check if a file was loaded
    if (m_flIsLoaded == FALSE)
        return(PE_INVALID);

    // Convert Virtual Address to Relative Virtual Address
    if (dwVA != PE_INVALID)
        dwVA -= m_Headers.m_hdrNt.OptionalHeader.ImageBase;

    return(RVA2FO(dwVA));
}

// File Offset to Relative Virtual Address
DWORD CPortableExecutable::FO2RVA(DWORD dwFO)
{
    CSection *pSection;

    // Check if a file was loaded
    if (m_flIsLoaded == FALSE)
        return(PE_INVALID);

    pSection = GetSectionByFO(dwFO);

    if (pSection) {
        // Convert File Offset to RVA
        dwFO += pSection->m_hdr.VirtualAddress;
        dwFO -= pSection->m_hdr.PointerToRawData;
    } else {
        dwFO = PE_INVALID;
    }

    return(dwFO);
}

// File Offset to Virtual Address
DWORD CPortableExecutable::FO2VA(DWORD dwFO)
{
    DWORD dwVA;

    // Check if a file was loaded
    if (m_flIsLoaded == FALSE)
        return(PE_INVALID);

    // Convert File Offset to Virtual Address
    dwVA = FO2RVA(dwFO);

    if (dwVA != PE_INVALID)
        dwVA += m_Headers.m_hdrNt.OptionalHeader.ImageBase;

    return(dwVA);
}

// Get section by Relative Virtual Address
CSection * CPortableExecutable::GetSectionByRVA(DWORD dwRVA)
{
    CSection *pSection;
    sctIterator i;

    // Check if a file was loaded
    if (m_flIsLoaded == FALSE)
        return(NULL);

    pSection = NULL;

    // Search which section contains the RVA
    for (i = m_lstSections.begin(); i != m_lstSections.end(); i++) {
        if ((*i).WithinRVA(dwRVA) == TRUE) {
            pSection = &(*i);
            break;
        }
    }

    // RVA isn't in the file limits
    if (i == m_lstSections.end())
        return(NULL);

    // Return the section that the RVA is within
    return(pSection);
}

// Get section by Virtual Address
CSection * CPortableExecutable::GetSectionByVA(DWORD dwVA)
{
    // Check if a file was loaded
    if (m_flIsLoaded == FALSE)
        return(NULL);

    dwVA -= m_Headers.m_hdrNt.OptionalHeader.ImageBase;
    return(GetSectionByRVA(dwVA));
}

// Get section by File Offset
CSection * CPortableExecutable::GetSectionByFO(DWORD dwFO)
{
    CSection *pSection;
    sctIterator i;

    // Check if a file was loaded
    if (m_flIsLoaded == FALSE)
        return(NULL);

    pSection = NULL;

    // Search which section contains the RVA
    for (i = m_lstSections.begin(); i != m_lstSections.end(); i++) {
        if ((*i).WithinFO(dwFO) == TRUE) {
            pSection = &(*i);
            break;
        }
    }

    // RVA isn't in the file limits
    if (i == m_lstSections.end())
        return(NULL);

    // Return the section that the RVA is within
    return(pSection);
}

// Get pointer to data at Relative Virtual Address
LPBYTE CPortableExecutable::GetDataAtRVA(DWORD dwRVA)
{
    CSection *pSection;

    pSection = GetSectionByRVA(dwRVA);

    if (pSection) {
        dwRVA -= pSection->m_hdr.VirtualAddress;
        if (dwRVA < pSection->m_hdr.SizeOfRawData)
            return(&pSection->m_pData[dwRVA]);
    }

    return(NULL);
}

// Get pointer to data at Virtual Address
LPBYTE CPortableExecutable::GetDataAtVA(DWORD dwVA)
{
    // Check if a file was loaded
    if (m_flIsLoaded == FALSE)
        return(NULL);

    dwVA -= m_Headers.m_hdrNt.OptionalHeader.ImageBase;
    return(GetDataAtRVA(dwVA));
}

// Virtual Address to Relative Virtual Address
DWORD CPortableExecutable::VA2RVA(DWORD dwVA)
{
    // Check if a file was loaded
    if (m_flIsLoaded == FALSE)
        return(PE_INVALID);

    if (dwVA != PE_INVALID)
        dwVA -= m_Headers.m_hdrNt.OptionalHeader.ImageBase;

    return(dwVA);
}

// Relative Virtual Address to Virtual Address
DWORD CPortableExecutable::RVA2VA(DWORD dwRVA)
{
    // Check if a file was loaded
    if (m_flIsLoaded == FALSE)
        return(PE_INVALID);

    if (dwRVA != PE_INVALID)
        dwRVA += m_Headers.m_hdrNt.OptionalHeader.ImageBase;

    return(dwRVA);
}

// Remove a section
PE_ERROR CPortableExecutable::RemoveSection(CSection *pSection)
{
    sctIterator i;

    // Check if a file was loaded
    if (m_flIsLoaded == FALSE)
        return(PE_LOAD);

    if (pSection) {
        // Fix offset of all sections that go after pSection
        for (i = m_lstSections.begin(); i != m_lstSections.end(); i++) {
            if ((*i).m_hdr.PointerToRawData > pSection->m_hdr.PointerToRawData) {
                (*i).m_hdr.PointerToRawData -= pSection->m_hdr.SizeOfRawData;
            }
        }

        // Decrease number of section in file header
        m_Headers.m_hdrNt.FileHeader.NumberOfSections--;

        // Remove section from list
        for (i = m_lstSections.begin(); i != m_lstSections.end(); i++) {
            if (&(*i) == pSection) {
                m_lstSections.erase(i);
                break;
            }
        }
    }

    FixImageSize();
    m_Headers.FixSizeOfHeaders();

    return(PE_NONE);
}

// Insert a section
PE_ERROR CPortableExecutable::InsertSection(CSection *pToAdd, CSection *pNext)
{
    sctIterator iNext;
    sctIterator i;

    // Check if a file was loaded
    if (m_flIsLoaded == FALSE)
        return(PE_LOAD);

    if (pToAdd) {
        // Find where to insert the section
        if (pNext) {
            for (iNext = m_lstSections.begin(); iNext != m_lstSections.end(); iNext++) {
                if (&(*iNext) == pNext) {
                    // Found where to insert the section
                    break;
                }
            }
        } else {
            // Insert at end
            iNext = m_lstSections.end();

⌨️ 快捷键说明

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