返回> 网站首页
数据保存到PE自定义段
yoours2026-05-26 09:05:58
简介一边听听音乐,一边写写文章。
一、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;
}