丁同亚的博客
夺朱非正色

代码如下:

// clonefile.cpp : 此文件包含 "main" 函数。程序执行将在此处开始并结束。
//
#define _CRT_SECURE_NO_WARNINGS // 必须放在文件最顶部
#include <iostream>
#include <iomanip> // 包含 iomanip 头文件


/**
   获取文件大小
*/

int  getFileSize(const char* sourcePath) {
    FILE* fp;

    fp = fopen(sourcePath, "rb+");
    if (fp == NULL) {
        return 0;
    }
    // 移动文件指针到文件末尾
    fseek(fp, 0, SEEK_END);
    // 获取文件大小
    int filesize = ftell(fp);
    fclose(fp);
    return filesize;

}


/**
    读取文件到内存,返回文件在内存中的指针
*/

unsigned char* readFile(const char* sourcePath) {
    FILE* fp;

    fp = fopen(sourcePath, "rb+");
    if (fp == NULL) {
        return 0;
    }
    // 移动文件指针到文件末尾
    fseek(fp, 0, SEEK_END);
    // 获取文件大小
    int filesize = ftell(fp);

    unsigned char* newfile = (unsigned char*)malloc(filesize);
    if (newfile == NULL) {
        return NULL;
    }
    memset(newfile, 0, filesize);
    /* 查找文件的开头 */
    fseek(fp, 0, SEEK_SET);
    /* 读取数据 */
    fread(newfile, 1, filesize, fp);
    fclose(fp);
    return newfile;
}


/**
    读取文件到内存,将读到的内存写入硬盘,要求完整复制.
        1.打开文件
        2.获取文件大小
        3.开辟内存空间
        4.写入到内存
        4.将内存数据输出到新的文件
*/

void clone(const char* sourcePath, const char* targetPath) {

    unsigned char* newfile = readFile(sourcePath);

    int filesize = getFileSize(sourcePath);

    FILE* fpw;
    fpw = fopen(targetPath, "wb+");
    if (fpw == NULL) {
        return;
    }
    fwrite(newfile, 1, filesize, fpw);

    fclose(fpw);

    return;
}


/**
    拷贝源指针位置的内容,size指定字节数,flag指定往前还是往后拷贝
        往前拷贝可以把小端序换
*/
void* copyByte(void* source, int size, int flag) {
    if (source == NULL) {
        return NULL;
    }
    char* rtn = (char*)malloc(size);
    if (rtn == NULL) {
        return NULL;
    }
    if (flag == -1) {
        source = (void*)((int)source + size - 1);
    }
    int i = 0;
    while (i < size) {
        rtn[i] = ((char*)source)[i * flag];
        //target[i] = ((char*)source)[i * flag];
        i++;
    }
    return rtn;
}
//没用
char* offset(char* p, int offset) {
    return p + offset;
}
//各字段文件偏移和数据宽度
struct Item {
    int address;
    int size;
};
//节表
struct SectionTable {
    Item Name;
    Item VirtualSize;
    Item VirtualAddress;
    Item SizeOfRawData;
    Item PointerToRawData;
    Item PointerToRelocations;
    Item PointerToLinenumbers;
    Item NumberOfRelocations;
    Item NumberOfLinenumbers;
    Item Characteristics;

};

//放置每个字段的地址和宽度,
struct PE
{
    const char* fileName;
    Item e_magic;
    Item e_lfanew;
    Item PESigned;
    int NT_BASE;
    Item Machine;
    Item NumberOfSections;
    Item SizeOfOptionalHeader;
    Item Characteristics;
    Item SizeOfUninitializedData;
    Item SizeOfInitializedData;
    Item SizeOfCode;
    Item MinorLinkerVersion;
    Item MajorLinkerVersion;
    Item Magic;
    int OPTIONAL_HEADER_OFFSET;
    Item AddressOfEntryPoint;
    Item BaseOfCode;
    Item ImageBase;
    Item SectionAlignment;
    Item FileAlignment;
    Item MajorOperatingSystemVersion;
    Item MinorOperatingSystemVersion;
    Item SizeOfImage;
    Item SizeOfHeaders;
    Item CheckSum;
    Item NumberOfRvaAndSizes;
    Item* dataDir;
    int section_offset;
    SectionTable* sectionTable;
};


/**
*  targetExe:目标文件地址
    解析PE文件
    返回结构体,其中每一个字段放的是该字段的文件偏移和宽度
*/
PE resolvePE(const char* targetExe) {
    //clone("restart.exe","restartclone.exe");
    struct PE pe = *(PE*)malloc(sizeof(PE));
    pe.fileName = targetExe;
    bool isPE32add = false;
    int size = 4;

    unsigned char* file = readFile(targetExe);

    short f1 = *((short*)file);

    short* e_magic = (short*)copyByte((void*)file, 2, -1);
    pe.e_magic.address = 0;
    pe.e_magic.size = 2;

    int* e_lfanew = (int*)copyByte((void*)((int)file + 0x3c), 4, 1);
    pe.e_lfanew.address = 0x3c;
    pe.e_lfanew.size = 4;


    int* PESigned = (int*)copyByte((void*)((int)file + (int)*e_lfanew), 4, 1);
    pe.PESigned.address = (int)*e_lfanew;
    pe.PESigned.size = 4;

    int NT_BASE = (int)*e_lfanew + 0x04;

    pe.NT_BASE = (int)*e_lfanew + 0x04;

    short* Machine = (short*)copyByte((void*)((int)file + NT_BASE + 0x00), 2, 1);
    pe.Machine.address = NT_BASE;
    pe.Machine.size = 2;
    short* NumberOfSections = (short*)copyByte((void*)((int)file + NT_BASE + 0x02), 2, 1);
    pe.NumberOfSections.address = NT_BASE + 0x02;
    pe.NumberOfSections.size = 2;
    short* SizeOfOptionalHeader = (short*)copyByte((void*)((int)file + NT_BASE + 0x0F), 2, 1);

    pe.SizeOfOptionalHeader.address = NT_BASE + 0x0F;
    pe.SizeOfOptionalHeader.size = 2;


    short* Characteristics = (short*)copyByte((void*)((int)file + NT_BASE + 0x12), 2, 1);
    pe.Characteristics.address = NT_BASE + 0x12;
    pe.Characteristics.size = 2;


    int OPTIONAL_HEADER_OFFSET = NT_BASE + 0x14;
    pe.OPTIONAL_HEADER_OFFSET = OPTIONAL_HEADER_OFFSET;

    short* OPTIONAL_HEADER_Magic = (short*)copyByte((void*)((int)file + OPTIONAL_HEADER_OFFSET), 2, 1);
    pe.Magic.address = OPTIONAL_HEADER_OFFSET;
    pe.Magic.size = 2;


    if (*OPTIONAL_HEADER_Magic == 0x020b) {
        isPE32add = true;
    }

    unsigned char* MajorLinkerVersion = (unsigned char*)copyByte((void*)((int)file + OPTIONAL_HEADER_OFFSET + 0x02), 1, 1);
    pe.MajorLinkerVersion.address = OPTIONAL_HEADER_OFFSET + 0x02;
    pe.MajorLinkerVersion.size = 1;


    unsigned char* MinorLinkerVersion = (unsigned char*)copyByte((void*)((int)file + OPTIONAL_HEADER_OFFSET + 0x03), 1, 1);

    pe.MinorLinkerVersion.address = OPTIONAL_HEADER_OFFSET + 0x03;
    pe.MinorLinkerVersion.size = 1;

    int* OPTIONAL_HEADER_SizeOfCode = (int*)copyByte((void*)((int)file + OPTIONAL_HEADER_OFFSET + 0x04), 4, 1);
    pe.SizeOfCode.address = OPTIONAL_HEADER_OFFSET + 0x04;
    pe.SizeOfCode.size = 4;

    int* OP_SizeOfInitializedData = (int*)copyByte((void*)((int)file + OPTIONAL_HEADER_OFFSET + 0x08), 4, 1);
    pe.SizeOfInitializedData.address = OPTIONAL_HEADER_OFFSET + 0x08;
    pe.SizeOfInitializedData.size = 4;

    int* OP_SizeOfUninitializedData = (int*)copyByte((void*)((int)file + OPTIONAL_HEADER_OFFSET + 0x0C), 4, 1);
    pe.SizeOfUninitializedData.address = OPTIONAL_HEADER_OFFSET + 0x0c;
    pe.SizeOfUninitializedData.size = 4;
    //AddressOfEntryPoint

    int* OP_AddressOfEntryPoint = (int*)copyByte((void*)((int)file + OPTIONAL_HEADER_OFFSET + 0x10), 4, 1);

    pe.AddressOfEntryPoint.address = OPTIONAL_HEADER_OFFSET + 0x10;
    pe.AddressOfEntryPoint.size = 4;

    //BaseOfCode
    int* OP_BaseOfCode = (int*)copyByte((void*)((int)file + OPTIONAL_HEADER_OFFSET + 0x14), 4, 1);

    pe.BaseOfCode.address = OPTIONAL_HEADER_OFFSET + 0x14;
    pe.BaseOfCode.size = 4;


    if (!isPE32add) {
        //BaseOfData
        int* OP_BaseOfData = (int*)copyByte((void*)((int)file + OPTIONAL_HEADER_OFFSET + 0x18), 4, 1);
    }
    int OP_Win_offset32 = OPTIONAL_HEADER_OFFSET + 0x1c;
    int OP_Win_offset64 = OPTIONAL_HEADER_OFFSET + 0x18;


    int* ImageBase = (int*)copyByte((void*)((int)file + OPTIONAL_HEADER_OFFSET + 28), 4 + isPE32add * 4, 1);

    pe.ImageBase.address = OPTIONAL_HEADER_OFFSET + 28;
    pe.ImageBase.size = 4;

    int* SectionAlignment = (int*)copyByte((void*)((int)file + OPTIONAL_HEADER_OFFSET + 32), 4, 1);

    pe.SectionAlignment.address = OPTIONAL_HEADER_OFFSET + 32;
    pe.SectionAlignment.size = 4;


    int* FileAlignment = (int*)copyByte((void*)((int)file + OPTIONAL_HEADER_OFFSET + 36), 4, 1);
    pe.FileAlignment.address = OPTIONAL_HEADER_OFFSET + 36;
    pe.FileAlignment.size = 4;

    short* MajorOperatingSystemVersion = (short*)copyByte((void*)((int)file + OPTIONAL_HEADER_OFFSET + 40), 2, 1);
    pe.MajorOperatingSystemVersion.address = OPTIONAL_HEADER_OFFSET + 40;
    pe.MajorOperatingSystemVersion.size = 2;

    short* MinorOperatingSystemVersion = (short*)copyByte((void*)((int)file + OPTIONAL_HEADER_OFFSET + 42), 2, 1);
    pe.MinorOperatingSystemVersion.address = OPTIONAL_HEADER_OFFSET + 42;
    pe.MinorOperatingSystemVersion.size = 2;

    int* SizeOfImage = (int*)copyByte((void*)((int)file + OPTIONAL_HEADER_OFFSET + 56), 4, 1);
    pe.SizeOfImage.address = OPTIONAL_HEADER_OFFSET + 56;
    pe.SizeOfImage.size = 4;

    int* SizeOfHeaders = (int*)copyByte((void*)((int)file + OPTIONAL_HEADER_OFFSET + 60), 4, 1);
    pe.SizeOfHeaders.address = OPTIONAL_HEADER_OFFSET + 60;
    pe.SizeOfHeaders.size = 4;

    int* CheckSum = (int*)copyByte((void*)((int)file + OPTIONAL_HEADER_OFFSET + 64), 4, 1);
    pe.CheckSum.address = OPTIONAL_HEADER_OFFSET + 64;
    pe.CheckSum.size = 4;

    int* NumberOfRvaAndSizes = (int*)copyByte((void*)((int)file + OPTIONAL_HEADER_OFFSET + 92), 4, 1);
    pe.NumberOfRvaAndSizes.address = OPTIONAL_HEADER_OFFSET + 92;
    pe.NumberOfRvaAndSizes.size = 4;

    //数据目录
    pe.dataDir = (Item*)malloc(*NumberOfRvaAndSizes * sizeof(Item));

    int j = 0;
    while (j < *NumberOfRvaAndSizes) {
        pe.dataDir[j].address = OPTIONAL_HEADER_OFFSET + 96 + j * 8;
        pe.dataDir[j].size = 8;
        j++;
    }



    int section_offset = *NumberOfRvaAndSizes * 8 + (OPTIONAL_HEADER_OFFSET + 96);
    pe.section_offset = section_offset;

    pe.sectionTable = (SectionTable*)malloc(sizeof(SectionTable) * (*NumberOfSections));
    int i = 0;
    while (i < *NumberOfSections) {

        pe.sectionTable[i].Name.address = section_offset + 40 * i;
        pe.sectionTable[i].Name.size = 8;

        pe.sectionTable[i].VirtualSize.address = section_offset + 8 + 40 * i;
        pe.sectionTable[i].VirtualSize.size = 4;

        pe.sectionTable[i].VirtualAddress.address = section_offset + 12 + 40 * i;
        pe.sectionTable[i].VirtualAddress.size = 4;

        pe.sectionTable[i].SizeOfRawData.address = section_offset + 16 + 40 * i;
        pe.sectionTable[i].SizeOfRawData.size = 4;

        pe.sectionTable[i].PointerToRawData.address = section_offset + 20 + 40 * i;
        pe.sectionTable[i].PointerToRawData.size = 4;

        pe.sectionTable[i].PointerToRelocations.address = section_offset + 24 + 40 * i;
        pe.sectionTable[i].PointerToRelocations.size = 4;

        pe.sectionTable[i].PointerToLinenumbers.address = section_offset + 28 + 40 * i;
        pe.sectionTable[i].PointerToLinenumbers.size = 4;

        pe.sectionTable[i].NumberOfRelocations.address = section_offset + 32 + 40 * i;
        pe.sectionTable[i].NumberOfRelocations.size = 2;

        pe.sectionTable[i].NumberOfLinenumbers.address = section_offset + 34 + 40 * i;
        pe.sectionTable[i].NumberOfLinenumbers.size = 2;

        pe.sectionTable[i].Characteristics.address = section_offset + 36 + 40 * i;
        pe.sectionTable[i].Characteristics.size = 4;
       
        i++;
    }

    return pe;
}





int main()
{
    
    PE pe = resolvePE("restart.exe");
    unsigned char* file = readFile("restart.exe");
    int SizeOfHeaders = *(int*)((int)file + pe.SizeOfHeaders.address);
    std::cout << std::hex << std::setw(8) << std::setfill('0');
    std::cout << "SizeOfHeaders:" << SizeOfHeaders << std::endl;

    system("pause");
}

posted on 2025-03-02 20:43  丁同亚的博客  阅读(22)  评论(0)    收藏  举报