码迷,mamicode.com
首页 > 编程语言 > 详细

PEtools PE操作工具类C++

时间:2020-02-16 17:55:56      阅读:79      评论:0      收藏:0      [点我收藏+]

标签:输出   head   get   for   loader   ber   reserve   图片   sed   

源码来自各大网友并非原创修改了部分函数 仅供参考(PE没源码参考应该是很吃力的)

暂未更新完持续更新中.......

PETools.h

技术图片
//函数头
int GetFileLength(FILE *pf, DWORD *Length);
int ReadFileByPathToBuffer(IN LPSTR FilePath, OUT LPVOID* pFileAddress);
int PrintPEFileHeader(void* pFileAddress);
int PrintPESectionHeader(PVOID pFileAddress);
int WriteFileFromFileAddress(PVOID pFileAddress, DWORD FileSize, LPSTR FilePath);
int FileBufferToImageBuffer(PVOID pFileBuffer, OUT PVOID *pImageBuffer);
int ExtendLastSection(PVOID FileAddress, OUT PVOID *NewFileAddress, IN LPSTR FilePath, IN DWORD size0xold, IN DWORD size0xadd, bool ChangeCharacteristics, LPSTR newLastSecName);
int ImageBufferToNewFileBuffer(PVOID pImageBuffer, OUT PVOID* pNewFileBuffer, PDWORD pNewFileBufferSize);
int ExtendLastSection(PVOID FileAddress, OUT PVOID *NewFileAddress, IN LPSTR FilePath, IN DWORD size0xold, IN DWORD size0xadd);
View Code

PETools.cpp

技术图片
#pragma once
# define _CRT_SECURE_NO_WARNINGS
#include  "stdafx.h"
# include "stdio.h"
# include "stdlib.h"
# include "windows.h"
#include "PETools.h"

/*d通过路径读文件返回文件指针
 @参数一位 要输入的文件路径
 @参数二是 返回读入内存的指针地址;
  返回的是文件大小
*/

int ReadFileByPathToBuffer(IN LPSTR FilePath, OUT void** pFileAddress)
{
    int ret = 0;
    DWORD Length = 0;
    //打开文件
    FILE* pf = fopen(FilePath, "rb");
    if (pf == NULL)
    {
        ret = -1;
        printf("func ReadFile() Error!\n");
        return ret;
    }

    //获取文件长度
    ret = GetFileLength(pf, &Length);
    if (ret != 0 && Length == -1)
    {
        ret = -2;
        printf("func GetFileLength() Error!\n");
        return ret;
    }

    //分配空间
    *pFileAddress = (PVOID)malloc(Length);
    if (*pFileAddress == NULL)
    {
        ret = -3;
        printf("func malloc() Error!\n");
        return ret;
    }
    memset(*pFileAddress, 0, Length);//申请的空间初始化为0

    //读取文件进入内存(自己申请的缓冲区)
    fread(*pFileAddress, Length, 1, pf);
    //printf("%s", ret);
    fclose(pf);//关闭文件打开流
    return Length;

}

/*得到文件size但返回0一定要fseek(pf, 0, SEEK_SET);//把指针指导最前*/
int GetFileLength(FILE *pf, DWORD *Length)
{
    int ret = 0;
    fseek(pf, 0, SEEK_END);//把指针指导最后
    *Length = ftell(pf);
    fseek(pf, 0, SEEK_SET);//把指针指导最前
    return ret;
}

/*
从内存中输出文件 
@参数一 要输出的文件地址
@参数二 输出的文件大小size
@参数三 输出的文件路径
成功返回1 失败<0
*/
int WriteFileFromFileAddress(PVOID pFileAddress, DWORD FileSize, LPSTR FilePath)
{
    int ret = 1;
    FILE *pf = fopen(FilePath, "wb");
    if (pf == NULL)
    {
        ret = -1;
        printf("func fopen() error :%d!\n", ret);
        return ret;
    }
    fwrite(pFileAddress, FileSize, 1, pf);
    fclose(pf);
    return ret;
}
int PrintPEOptionalHeader(PVOID pFileAddress)
{
    int ret = 0;

    PIMAGE_DOS_HEADER pDosHeader = (PIMAGE_DOS_HEADER)pFileAddress;
    PIMAGE_FILE_HEADER pFileHeader = (PIMAGE_FILE_HEADER)((DWORD)pDosHeader + (DWORD)pDosHeader->e_lfanew + 4);
    PIMAGE_OPTIONAL_HEADER32 pOptionalHeader = (PIMAGE_OPTIONAL_HEADER32)((DWORD)pFileHeader + sizeof(IMAGE_FILE_HEADER));


    printf("****************OPTIONAL_HEADER32 STAR*************************\n");
    printf("OptionalHeader->Magic                        : %02X\n", pOptionalHeader->Magic);
    printf("OptionalHeader->MajorLinkerVersion           : %01X\n", pOptionalHeader->MajorLinkerVersion);
    printf("OptionalHeader->MinorLinkerVersion           : %01X\n", pOptionalHeader->MinorLinkerVersion);
    printf("OptionalHeader->SizeOfCode                   : %04X\n", pOptionalHeader->SizeOfCode);
    printf("OptionalHeader->SizeOfInitializedData        : %04X\n", pOptionalHeader->SizeOfInitializedData);
    printf("OptionalHeader->SizeOfUninitializedData      : %04X\n", pOptionalHeader->SizeOfUninitializedData);
    printf("OptionalHeader->AddressOfEntryPoint          : %04X\n", pOptionalHeader->AddressOfEntryPoint);
    printf("OptionalHeader->BaseOfCode                   : %04X\n", pOptionalHeader->BaseOfCode);
    printf("OptionalHeader->BaseOfData                   : %04X\n", pOptionalHeader->BaseOfData);
    printf("OptionalHeader->ImageBase                    : %04X\n", pOptionalHeader->ImageBase);
    printf("OptionalHeader->SectionAlignment             : %04X\n", pOptionalHeader->SectionAlignment);
    printf("OptionalHeader->FileAlignment                : %04X\n", pOptionalHeader->FileAlignment);
    printf("OptionalHeader->MajorOperatingSystemVersion  : %02X\n", pOptionalHeader->MajorOperatingSystemVersion);
    printf("OptionalHeader->MinorOperatingSystemVersion  : %02X\n", pOptionalHeader->MinorOperatingSystemVersion);
    printf("OptionalHeader->MajorImageVersion            : %02X\n", pOptionalHeader->MajorImageVersion);
    printf("OptionalHeader->MinorImageVersion            : %02X\n", pOptionalHeader->MinorImageVersion);
    printf("OptionalHeader->MajorSubsystemVersion        : %02X\n", pOptionalHeader->MajorSubsystemVersion);
    printf("OptionalHeader->MinorSubsystemVersion        : %02X\n", pOptionalHeader->MinorSubsystemVersion);
    printf("OptionalHeader->Win32VersionValue            : %04X\n", pOptionalHeader->Win32VersionValue);
    printf("OptionalHeader->SizeOfImage                  : %04X\n", pOptionalHeader->SizeOfImage);
    printf("OptionalHeader->SizeOfHeaders                : %04X\n", pOptionalHeader->SizeOfHeaders);
    printf("OptionalHeader->CheckSum                     : %04X\n", pOptionalHeader->CheckSum);
    printf("OptionalHeader->Subsystem                    : %02X\n", pOptionalHeader->Subsystem);
    printf("OptionalHeader->DllCharacteristics           : %02X\n", pOptionalHeader->DllCharacteristics);
    printf("OptionalHeader->SizeOfStackReserv            : %04X\n", pOptionalHeader->SizeOfStackReserve);
    printf("OptionalHeader->SizeOfStackCommit            : %04X\n", pOptionalHeader->SizeOfStackCommit);
    printf("OptionalHeader->SizeOfHeapReserve            : %04X\n", pOptionalHeader->SizeOfHeapReserve);
    printf("OptionalHeader->SizeOfHeapCommit             : %04X\n", pOptionalHeader->SizeOfHeapCommit);
    printf("OptionalHeader->LoaderFlags                  : %04X\n", pOptionalHeader->LoaderFlags);
    printf("OptionalHeader->NumberOfRvaAndSizes          : %04X\n", pOptionalHeader->NumberOfRvaAndSizes);

    printf("*****************OPTIONAL_HEADER32 END************************\n");

    return ret;
}
int PrintPEFileHeader(PVOID pFileAddress)
{
    int ret = 0;
    PIMAGE_DOS_HEADER pDosHeader = (PIMAGE_DOS_HEADER)pFileAddress;
    PIMAGE_FILE_HEADER pFileHeader = (PIMAGE_FILE_HEADER)((DWORD)pDosHeader + (DWORD)pDosHeader->e_lfanew + 4);//相当于文件tou加上那个lfanew 现在指向PE位置
    printf("FileHeader->Machine              : %02X\n", pDosHeader->e_lfanew);
    printf("****************FILE_HEADER STAR*************************\n");
    printf("FileHeader->Machine              : %02X\n", pFileHeader->Machine);
    printf("FileHeader->NumberOfSections     : %02X\n", pFileHeader->NumberOfSections);
    printf("FileHeader->TimeDateStamp        : %04X\n", pFileHeader->TimeDateStamp);
    printf("FileHeader->PointerToSymbolTable : %04X\n", pFileHeader->PointerToSymbolTable);
    printf("FileHeader->NumberOfSymbols      : %04X\n", pFileHeader->NumberOfSymbols);
    printf("FileHeader->SizeOfOptionalHeader : %02X\n", pFileHeader->SizeOfOptionalHeader);//可选PE头大小
    printf("FileHeader->Characteristics      : %02X\n", pFileHeader->Characteristics);
    printf("*****************FILE_HEADER END************************\n");

    return ret;

}
int PrintPESectionHeader(PVOID pFileAddress)
{
    int ret = 0;
    PIMAGE_DOS_HEADER pDosHeader = (PIMAGE_DOS_HEADER)pFileAddress;
    PIMAGE_FILE_HEADER pFileHeader = (PIMAGE_FILE_HEADER)((DWORD)pDosHeader + (DWORD)pDosHeader->e_lfanew + 4);
    PIMAGE_OPTIONAL_HEADER32 pOptionalHeader = (PIMAGE_OPTIONAL_HEADER32)((DWORD)pFileHeader + sizeof(IMAGE_FILE_HEADER));
    PIMAGE_SECTION_HEADER pSectionGroup = (PIMAGE_SECTION_HEADER)((DWORD)pOptionalHeader + pFileHeader->SizeOfOptionalHeader);
    printf("****************SECTION_HEADER STAR*************************\n");
    printf("%x", pSectionGroup[0]);
    for (int i = 0; i < pFileHeader->NumberOfSections; i++)
    {
        printf("pSectionGroup[%d].Name                   : %s\n", i, pSectionGroup[i].Name);
        printf("pSectionGroup[%d].Misc.VirtualSize       : %04X\n", i, pSectionGroup[i].Misc.VirtualSize);
        printf("pSectionGroup[%d].VirtualAddress         : %04X\n", i, pSectionGroup[i].VirtualAddress);
        printf("pSectionGroup[%d].SizeOfRawData          : %04X\n", i, pSectionGroup[i].SizeOfRawData);
        printf("pSectionGroup[%d].PointerToRawData       : %04X\n", i, pSectionGroup[i].PointerToRawData);
        printf("pSectionGroup[%d].PointerToRelocations   : %04X\n", i, pSectionGroup[i].PointerToRelocations);
        printf("pSectionGroup[%d].PointerToLinenumbers   : %04X\n", i, pSectionGroup[i].PointerToLinenumbers);
        printf("pSectionGroup[%d].NumberOfRelocations    : %02X\n", i, pSectionGroup[i].NumberOfRelocations);
        printf("pSectionGroup[%d].NumberOfLinenumbers    : %02X\n", i, pSectionGroup[i].NumberOfLinenumbers);
        printf("pSectionGroup[%d].Characteristics        : %04X\n\n\n", i, pSectionGroup[i].Characteristics);
    }
    printf("*****************SECTION_HEADER END************************\n");
    return ret;
}
/*
@参数一 要输出的文件pFileBuffer
@参数二 *pImageBuffer 拉伸后镜像缓冲区首地址
成功返回1 失败<0
*/
int FileBufferToImageBuffer(PVOID pFileBuffer, OUT PVOID *pImageBuffer)
{
    int ret =1;
    DWORD ImageBufferSize = 0;

    PIMAGE_DOS_HEADER pDosHeader = (PIMAGE_DOS_HEADER)pFileBuffer;
    PIMAGE_FILE_HEADER pFileHeader = (PIMAGE_FILE_HEADER)((DWORD)pDosHeader + (DWORD)pDosHeader->e_lfanew + 4);
    PIMAGE_OPTIONAL_HEADER32 pOptionalHeader = (PIMAGE_OPTIONAL_HEADER32)((DWORD)pFileHeader + sizeof(IMAGE_FILE_HEADER));
    PIMAGE_SECTION_HEADER pSectionGroup = (PIMAGE_SECTION_HEADER)((DWORD)pOptionalHeader + pFileHeader->SizeOfOptionalHeader);

    //1、获取ImageBufffer的内存大小
    ImageBufferSize = pOptionalHeader->SizeOfImage;

    //2、为pImageBuffer分配内存空间
    *pImageBuffer = (PVOID)malloc(ImageBufferSize);
    if (pImageBuffer == NULL)
    {
        ret = -4;
        printf("func malloc() Error : %d!\n", ret);
        return ret;
    }
    memset(*pImageBuffer, 0, ImageBufferSize);

    //3、将FileBuffer的数据拷贝到ImageBuffer中
    //        文件头直接拷贝
    memcpy(*pImageBuffer, pFileBuffer, pOptionalHeader->SizeOfHeaders);

    //        节区循环拷贝
    for (int i = 0; i < pFileHeader->NumberOfSections; i++)
    {
        //按照PointerToRawData 复制是不会出错的
        memcpy((PVOID)((DWORD)*pImageBuffer + pSectionGroup[i].VirtualAddress),
            (PVOID)((DWORD)pFileBuffer + pSectionGroup[i].PointerToRawData),
            pSectionGroup[i].SizeOfRawData);
    }

    return ret;
}
/*
从内存中输出文件
@参数一 要输出的文件pFileBuffer
@参数二 pNewFileBuffer 新的文件缓冲
@参数三 新缓冲地址
成功返回1 失败<0
*/
int ImageBufferToNewFileBuffer(PVOID pImageBuffer,  OUT PVOID* pNewFileBuffer, OUT PDWORD pNewFileBufferSize)
{
    int ret = 1;
    DWORD NewFileBufferSize = 0;

    PIMAGE_DOS_HEADER pDosHeader = (PIMAGE_DOS_HEADER)pImageBuffer;
    PIMAGE_FILE_HEADER pFileHeader = (PIMAGE_FILE_HEADER)((DWORD)pDosHeader + (DWORD)pDosHeader->e_lfanew + 4);
    PIMAGE_OPTIONAL_HEADER32 pOptionalHeader = (PIMAGE_OPTIONAL_HEADER32)((DWORD)pFileHeader + sizeof(IMAGE_FILE_HEADER));
    PIMAGE_SECTION_HEADER pSectionGroup = (PIMAGE_SECTION_HEADER)((DWORD)pOptionalHeader + pFileHeader->SizeOfOptionalHeader);

    //1、获取NewFileBuffer的内存大小
    NewFileBufferSize += pOptionalHeader->SizeOfHeaders;        //文件头大小
    for (int i = 0; i < pFileHeader->NumberOfSections; i++)
    {
        NewFileBufferSize += pSectionGroup[i].SizeOfRawData;
    }

    //2、为pNewFileBuffer分配内存空间
    *pNewFileBuffer = (PVOID)malloc(NewFileBufferSize);
    if (pNewFileBuffer == NULL)
    {
        ret = -4;
        printf("func malloc() Error : %d!\n", ret);
        return ret;
    }
    memset(*pNewFileBuffer, 0, NewFileBufferSize);

    //3、将ImageBuffer的数据拷贝到NewFileBuffer中
    //        文件头直接拷贝
    memcpy(*pNewFileBuffer, pImageBuffer, pOptionalHeader->SizeOfHeaders);

    //        节区循环拷贝
    for (int i = 0; i < pFileHeader->NumberOfSections; i++)
    {
        memcpy((PVOID)((DWORD)*pNewFileBuffer + pSectionGroup[i].PointerToRawData),
            (PVOID)((DWORD)pImageBuffer + pSectionGroup[i].VirtualAddress),
            pSectionGroup[i].SizeOfRawData);
    }

    *pNewFileBufferSize = NewFileBufferSize;

    return ret;
}
/*
成功返回新文件size‘
失败返回<0
参数一 文件读入内存地址
参数二 输出新文件内存地址
参数三 输入的文件路径+名称
参数四 源文件大小size
参数五 要增加的字节长度十六进制
参数六 是否更改节属性为可读可写可执行 true为更改
参数七 更改最后一个节的名称可空 null 长度最大为8字节

*/
int ExtendLastSection(PVOID FileAddress, OUT PVOID *NewFileAddress, IN LPSTR FilePath, IN DWORD size0xold, IN DWORD size0xadd, bool ChangeCharacteristics, LPSTR newLastSecName)
{
    int ret = 0;
    DWORD OldLength = 0;
    DWORD NewLength = 0;
    PIMAGE_DOS_HEADER pDosHeader = NULL;
    PIMAGE_FILE_HEADER pFileHeader = NULL;
    PIMAGE_OPTIONAL_HEADER32 pOptionalHeader = NULL;
    PIMAGE_SECTION_HEADER pSectionGroup = NULL;
    PIMAGE_SECTION_HEADER pLastSection = NULL;
    OldLength = size0xold;
    if (OldLength<=0)
    {
        ret = -2;
        printf("func GetFileLength() Error!\n");
        return ret;
    }

    //将旧的空间增加0x1000
    NewLength = OldLength + size0xadd;
    *NewFileAddress = (LPVOID)malloc(NewLength);
    if (*NewFileAddress == NULL)
    {
        ret = -3;
        printf("func malloc() Error!\n");
        return ret;
    }
    memset(*NewFileAddress, 0, NewLength);

    //2、将旧空间的内容copy到新的空间
    memcpy(*NewFileAddress, FileAddress, OldLength);

    //3、将指针指向对应位置
    pDosHeader = (PIMAGE_DOS_HEADER)(*NewFileAddress);
    pFileHeader = (PIMAGE_FILE_HEADER)((DWORD)pDosHeader + pDosHeader->e_lfanew + 4);
    pOptionalHeader = (PIMAGE_OPTIONAL_HEADER32)((DWORD)pFileHeader + sizeof(IMAGE_FILE_HEADER));
    pSectionGroup = (PIMAGE_SECTION_HEADER)((DWORD)pOptionalHeader + pFileHeader->SizeOfOptionalHeader);
    pLastSection = &pSectionGroup[pFileHeader->NumberOfSections - 1];

    //4、修改相关内容 需要用更高级的指针进行操作
    LPDWORD pSizeOfImage = &pOptionalHeader->SizeOfImage;
    LPDWORD pSecMisc = &pLastSection->Misc.VirtualSize;
    LPDWORD pSecSizeOfRawData = &pLastSection->SizeOfRawData;
    LPDWORD Characteristics = &pLastSection->Characteristics;//获取是否哦可执行
    PVOID pSecName = &pLastSection->Name;//获取节的名称

    *pSizeOfImage = *pSizeOfImage + size0xadd;
    *pSecMisc = *pSecMisc + size0xadd;
    *pSecSizeOfRawData = *pSecSizeOfRawData + size0xadd;

    //更改最后一个节属性
    if (ChangeCharacteristics)
    {
        *Characteristics = 0xE0000000 + (*Characteristics % 16777216);
        //增加可读可写可执行
    }
    if (newLastSecName!=NULL)
    {
        //修改最后一个节的名称
        memcpy(pSecName, newLastSecName, 8);
    }
    
    
    
    //*pNewLength = NewLength;

    return NewLength;
}
int ExtendLastSection(PVOID FileAddress, OUT PVOID *NewFileAddress, IN LPSTR FilePath, IN DWORD size0xold, IN DWORD size0xadd)
{
    int ret = 0;
    DWORD OldLength = 0;
    DWORD NewLength = 0;
    PIMAGE_DOS_HEADER pDosHeader = NULL;
    PIMAGE_FILE_HEADER pFileHeader = NULL;
    PIMAGE_OPTIONAL_HEADER32 pOptionalHeader = NULL;
    PIMAGE_SECTION_HEADER pSectionGroup = NULL;
    PIMAGE_SECTION_HEADER pLastSection = NULL;
    OldLength = size0xold;
    if (OldLength <= 0)
    {
        ret = -2;
        printf("func GetFileLength() Error!\n");
        return ret;
    }

    //将旧的空间增加0x1000
    NewLength = OldLength + size0xadd;
    *NewFileAddress = (LPVOID)malloc(NewLength);
    if (*NewFileAddress == NULL)
    {
        ret = -3;
        printf("func malloc() Error!\n");
        return ret;
    }
    memset(*NewFileAddress, 0, NewLength);

    //2、将旧空间的内容copy到新的空间
    memcpy(*NewFileAddress, FileAddress, OldLength);

    //3、将指针指向对应位置
    pDosHeader = (PIMAGE_DOS_HEADER)(*NewFileAddress);
    pFileHeader = (PIMAGE_FILE_HEADER)((DWORD)pDosHeader + pDosHeader->e_lfanew + 4);
    pOptionalHeader = (PIMAGE_OPTIONAL_HEADER32)((DWORD)pFileHeader + sizeof(IMAGE_FILE_HEADER));
    pSectionGroup = (PIMAGE_SECTION_HEADER)((DWORD)pOptionalHeader + pFileHeader->SizeOfOptionalHeader);
    pLastSection = &pSectionGroup[pFileHeader->NumberOfSections - 1];

    //4、修改相关内容 需要用更高级的指针进行操作
    LPDWORD pSizeOfImage = &pOptionalHeader->SizeOfImage;
    LPDWORD pSecMisc = &pLastSection->Misc.VirtualSize;
    LPDWORD pSecSizeOfRawData = &pLastSection->SizeOfRawData;
    LPDWORD Characteristics = &pLastSection->Characteristics;//获取是否哦可执行
    PVOID pSecName = &pLastSection->Name;//获取节的名称

    *pSizeOfImage = *pSizeOfImage + size0xadd;
    *pSecMisc = *pSecMisc + size0xadd;
    *pSecSizeOfRawData = *pSecSizeOfRawData + size0xadd;



    //*pNewLength = NewLength;

    return NewLength;
}
View Code

 

PEtools PE操作工具类C++

标签:输出   head   get   for   loader   ber   reserve   图片   sed   

原文地址:https://www.cnblogs.com/xuexidememeda/p/12317788.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!