参考: Self-extracting executables - strchr.com
用途
将exe和资源文件组合一个文件, 运行时自解压资源
本文只关注: 从Exe文件结构中算出exe文件大小
可参考顶部链接获取其他部分,
需注意修改_IMAGE_NT_HEADERS32为_IMAGE_NT_HEADERS64
组合方法
copy /b sfx.exe+archive.zip sfx_ready.exe
从Exe文件结构中算出exe文件大小
const DWORD ERR_OK = 0, ERR_READFAILED = 1, ERR_NOINFO = 2, ERR_BADFORMAT = 3;
DWORD ReadFromExeFile(const char* path)
{
BYTE buff[4096]; DWORD read; BYTE* data;
// Open exe file
HANDLE hFile = CreateFileA((CHAR*)path, GENERIC_READ, FILE_SHARE_READ,
NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
if (INVALID_HANDLE_VALUE == hFile)
return ERR_READFAILED;
ReadFile(hFile, buff, sizeof(buff), &read, NULL);
IMAGE_DOS_HEADER* dosheader = (IMAGE_DOS_HEADER*)buff;
// Locate PE header
_IMAGE_NT_HEADERS64* header =
(_IMAGE_NT_HEADERS64*)(buff + dosheader->e_lfanew);
if (dosheader->e_magic != IMAGE_DOS_SIGNATURE ||
header->Signature != IMAGE_NT_SIGNATURE) {
CloseHandle(hFile);
return ERR_BADFORMAT;
}
// For each section
IMAGE_SECTION_HEADER* sectiontable =
(IMAGE_SECTION_HEADER*)((BYTE*)header + sizeof(_IMAGE_NT_HEADERS64));
DWORD maxpointer = 0, exesize = 0;
for (int i = 0; i < header->FileHeader.NumberOfSections; i++) {
if (sectiontable->PointerToRawData > maxpointer) {
maxpointer = sectiontable->PointerToRawData;
exesize = sectiontable->PointerToRawData +
sectiontable->SizeOfRawData;
}
sectiontable++;
}
return exesize;
}
main函数代码
int main(int argc, char* argv[])
{
const char* path = argv[1];
path = "C:\\test\\a_b.exe";
std::cout << "Path: " << path << std::endl;
std::cout << "FileSize: " << FileSize(path) << " GetFileAttributesExA" << std::endl;
std::cout << "ExeSize: " << ReadFromExeFile(path) << " Get form PE Header" << std::endl;
}