返回> 网站首页 

数据保存到PE自定义段

yoours2026-05-26 09:05:58 阅读 32

简介一边听听音乐,一边写写文章。

一、PE段

    Windows PE文件没有绝对的物理地址概念,我们通过自定义段名来标识数据位置。程序运行后可以直接访问该段中的变量,就像访问普通全局变量一样。


二、定义

    1. 定义段,名为mydata,长度不能超过8字节

    #pragma section("mydata", read, write)

    2. 创建一个变量,并将其放入 "mydata" 段中

    __declspec(allocate("mydata")) VersionInfo g_VersionInfo = {

        "1.0.0",      // 版本号

        __DATE__,     // 编译日期

        __TIME__      // 编译时间

    };


三、POD(Plain Old Data)类型

    POD 类型的初始化数据直接嵌入 PE 段中,dumpbin 可见。非 POD 类型必须等运行时构造函数执行,dumpbin 只能看到零值。

    如 C 结构体、基本类型数组)的初始化数据在编译期就完全确定,因此可以直接嵌入 PE 文件的段中,dumpbin 能看到具体的十六进制值。而非 POD 类型(例如带有构造函数的类、包含 std::string 等成员的结构体)的全局对象,其初始化可能延迟到程序启动时的 main 函数之前(动态初始化),此时编译器只会在段中预留空间(初始化为零),真正的初始值由构造函数在运行时写入,所以 dumpbin 看到的自然全是 0。


四、读取

int ReadSectionInfo(string target, string sectionName, void* d, unsigned int len)

{

    if (strlen(sectionName.c_str()) > 8)

        return 1;


    HANDLE hFile = CreateFileA(target.c_str(), GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);

    if (hFile == INVALID_HANDLE_VALUE)

    {

        return 2;

    }


    HANDLE hMapping = CreateFileMapping(hFile, NULL, PAGE_READONLY, 0, 0, NULL);

    if (!hMapping)

    {

        CloseHandle(hFile);

        return 3;

    }


    LPVOID pBase = MapViewOfFile(hMapping, FILE_MAP_READ, 0, 0, 0);

    if (!pBase)

    {

        CloseHandle(hMapping);

        CloseHandle(hFile);

        return 4;

    }


    PIMAGE_DOS_HEADER pDos = (PIMAGE_DOS_HEADER)pBase;

    if (pDos->e_magic != IMAGE_DOS_SIGNATURE)

    {

        UnmapViewOfFile(pBase);

        return 5;

    }


    PIMAGE_NT_HEADERS pNt = (PIMAGE_NT_HEADERS)((BYTE*)pBase + pDos->e_lfanew);

    if (pNt->Signature != IMAGE_NT_SIGNATURE)

    {

        UnmapViewOfFile(pBase);

        return 6;

    }


    PIMAGE_SECTION_HEADER pSection = IMAGE_FIRST_SECTION(pNt);

    WORD numSections = pNt->FileHeader.NumberOfSections;

    PIMAGE_SECTION_HEADER pVerSection = NULL;


    for (int i = 0; i < numSections; i++)

    {

        if (memcmp(pSection->Name, sectionName.c_str(), strlen(sectionName.c_str())) == 0)

        {

            pVerSection = pSection;

            break;

        }

        pSection++;

    }


    if (!pVerSection)

    {

        UnmapViewOfFile(pBase);

        return 7;

    }


    DWORD fileOffset = pVerSection->PointerToRawData;

    DWORD size = pVerSection->SizeOfRawData;


    memcpy(d, (BYTE*)pBase + fileOffset, len);


    UnmapViewOfFile(pBase);

    CloseHandle(hMapping);

    CloseHandle(hFile);

    return 0;

}


微信小程序扫码登陆

文章评论

32人参与,0条评论