IMAGE_DOS_HEADER

12 篇文章 0 订阅
IMAGE_DOS_HEADER STRUCT 

{ 
+00h WORD e_magic // Magic DOS signature MZ(4Dh 5Ah) DOS可执行文件标记 
+02h WORD e_cblp // Bytes on last page of file 
+04h WORD e_cp // Pages in file 
+06h WORD e_crlc // Relocations 
+08h WORD e_cparhdr // Size of header in paragraphs 
+0ah WORD e_minalloc // Minimun extra paragraphs needs 
+0ch WORD e_maxalloc // Maximun extra paragraphs needs 
+0eh WORD e_ss // intial(relative)SS value DOS代码的初始化堆栈SS 
+10h WORD e_sp // intial SP value DOS代码的初始化堆栈指针SP 
+12h WORD e_csum // Checksum 
+14h WORD e_ip // intial IP value DOS代码的初始化指令入口[指针IP] 
+16h WORD e_cs // intial(relative)CS value DOS代码的初始堆栈入口 
+18h WORD e_lfarlc // File Address of relocation table 
+1ah WORD e_ovno // Overlay number 
+1ch WORD e_res[4] // Reserved words 
+24h WORD e_oemid // OEM identifier(for e_oeminfo) 
+26h WORD e_oeminfo // OEM information;e_oemid specific 
+29h WORD e_res2[10] // Reserved words 
+3ch LONG e_lfanew // Offset to start of PE header 指向PE文件头 
} IMAGE_DOS_HEADER ENDS
复制代码

 


1.该结构有两个重要的成员

DWORD e_magic和LONG e_lfanew。DWORD e_magic为"MZ",定义为IMAGE_DOS_SIGNATURE。LONG e_lfanew存放PE头的文件偏移量。

#define IMAGE_DOS_SIGNATURE 0x4D5A // MZ
#define IMAGE_OS2_SIGNATURE 0x4E45 // NE
#define IMAGE_OS2_SIGNATURE_LE 0x4C45 // LE
#define IMAGE_NT_SIGNATURE 0x50450000 // PE00



2.DOS Stub
它是一个总是由大约100个字节所组成的和MS-DOS 2.0兼容的可执行体,用来输出
“this program needs windows NT”之类的错误信息win32系统都直接跳过DOS Stub定
位到PE头。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
`_get_next_member_name` 函数的实现需要用到一些Windows API,具体来说是 `ImageNtHeader`、`ImageDirectoryEntryToData`、`ImageRvaToVa` 等函数。以下是一个简单的实现示例代码: ```c++ #include <Windows.h> #include <DbgHelp.h> const char* _get_next_member_name(const char* className, size_t* offset) { const char* memberName = nullptr; IMAGE_DOS_HEADER* pDosHeader = (IMAGE_DOS_HEADER*)GetModuleHandle(nullptr); IMAGE_NT_HEADERS* pNTHeader = (IMAGE_NT_HEADERS*)((DWORD_PTR)pDosHeader + pDosHeader->e_lfanew); IMAGE_SECTION_HEADER* pSectionHeader = IMAGE_FIRST_SECTION(pNTHeader); for (int i = 0; i < pNTHeader->FileHeader.NumberOfSections; i++) { if (strcmp((char*)pSectionHeader->Name, ".rdata") == 0) { DWORD_PTR rdataBase = (DWORD_PTR)GetModuleHandle(nullptr) + pSectionHeader->VirtualAddress; DWORD_PTR rdataEnd = rdataBase + pSectionHeader->Misc.VirtualSize; PIMAGE_SECTION_HEADER pRdataHeader = pSectionHeader; PIMAGE_SECTION_HEADER pRsrcHeader = pSectionHeader + 1; DWORD_PTR rsrcBase = (DWORD_PTR)GetModuleHandle(nullptr) + pRsrcHeader->VirtualAddress; DWORD_PTR rsrcEnd = rsrcBase + pRsrcHeader->Misc.VirtualSize; IMAGE_RESOURCE_DIRECTORY* pRootDirectory = (IMAGE_RESOURCE_DIRECTORY*)rsrcBase; IMAGE_RESOURCE_DIRECTORY_ENTRY* pRootEntry = (IMAGE_RESOURCE_DIRECTORY_ENTRY*)(pRootDirectory + 1); int typeOffset = 0x0; IMAGE_RESOURCE_DIRECTORY* pTypeDirectory = nullptr; IMAGE_RESOURCE_DIRECTORY_ENTRY* pTypeEntry = nullptr; IMAGE_RESOURCE_DIRECTORY* pNameDirectory = nullptr; IMAGE_RESOURCE_DIRECTORY_ENTRY* pNameEntry = nullptr; IMAGE_RESOURCE_DIRECTORY* pLanguageDirectory = nullptr; IMAGE_RESOURCE_DIRECTORY_ENTRY* pLanguageEntry = nullptr; for (int rootIndex = 0; rootIndex < pRootDirectory->NumberOfIdEntries + pRootDirectory->NumberOfNamedEntries; rootIndex++) { if (pRootEntry[rootIndex].NameIsString) { IMAGE_RESOURCE_DIR_STRING_U* pName = (IMAGE_RESOURCE_DIR_STRING_U*)(rsrcBase + pRootEntry[rootIndex].NameOffset); if (wcsncmp(pName->NameString, L"TYPEINFO", pName->Length) == 0) { typeOffset = pRootEntry[rootIndex].OffsetToDirectory; break; } } } if (typeOffset > 0) { pTypeDirectory = (IMAGE_RESOURCE_DIRECTORY*)(rsrcBase + typeOffset); pTypeEntry = (IMAGE_RESOURCE_DIRECTORY_ENTRY*)(pTypeDirectory + 1); for (int typeIndex = 0; typeIndex < pTypeDirectory->NumberOfIdEntries + pTypeDirectory->NumberOfNamedEntries; typeIndex++) { if (!pTypeEntry[typeIndex].NameIsString) { if (pTypeEntry[typeIndex].Id == 0x7) { pNameDirectory = (IMAGE_RESOURCE_DIRECTORY*)(rsrcBase + pTypeEntry[typeIndex].OffsetToDirectory); pNameEntry = (IMAGE_RESOURCE_DIRECTORY_ENTRY*)(pNameDirectory + 1); for (int nameIndex = 0; nameIndex < pNameDirectory->NumberOfIdEntries + pNameDirectory->NumberOfNamedEntries; nameIndex++) { if (pNameEntry[nameIndex].NameIsString) { IMAGE_RESOURCE_DIR_STRING_U* pName = (IMAGE_RESOURCE_DIR_STRING_U*)(rsrcBase + pNameEntry[nameIndex].NameOffset); if (strcmp((char*)pName->NameString, className) == 0) { pLanguageDirectory = (IMAGE_RESOURCE_DIRECTORY*)(rsrcBase + pNameEntry[nameIndex].OffsetToDirectory); pLanguageEntry = (IMAGE_RESOURCE_DIRECTORY_ENTRY*)(pLanguageDirectory + 1); for (int languageIndex = 0; languageIndex < pLanguageDirectory->NumberOfIdEntries + pLanguageDirectory->NumberOfNamedEntries; languageIndex++) { if (!pLanguageEntry[languageIndex].NameIsString) { DWORD_PTR symbolAddress = (DWORD_PTR)ImageDirectoryEntryToData(GetModuleHandle(nullptr), TRUE, IMAGE_DIRECTORY_ENTRY_EXPORT); PIMAGE_EXPORT_DIRECTORY pExportDirectory = (PIMAGE_EXPORT_DIRECTORY)symbolAddress; DWORD_PTR* pFuncAddress = (DWORD_PTR*)(symbolAddress + (DWORD_PTR)pExportDirectory->AddressOfFunctions); DWORD_PTR* pNameAddress = (DWORD_PTR*)(symbolAddress + (DWORD_PTR)pExportDirectory->AddressOfNames); WORD* pOrdinalAddress = (WORD*)(symbolAddress + (DWORD_PTR)pExportDirectory->AddressOfNameOrdinals); DWORD_PTR classVTableAddress = 0; for (int i = 0; i < pExportDirectory->NumberOfFunctions; i++) { if (strcmp((char*)(symbolAddress + pNameAddress[i]), className) == 0) { classVTableAddress = (DWORD_PTR)pFuncAddress[pOrdinalAddress[i]]; break; } } if (classVTableAddress > 0) { DWORD_PTR* pVTable = (DWORD_PTR*)*(DWORD_PTR*)classVTableAddress; int memberIndex = 0; while (true) { DWORD_PTR* pMemberAddress = (DWORD_PTR*)(pVTable[memberIndex]); if (*pMemberAddress == 0) { break; } if (*pMemberAddress >= rdataBase && *pMemberAddress < rdataEnd) { DWORD_PTR memberOffset = *pMemberAddress - rdataBase; if (memberOffset == *offset) { memberName = (const char*)(pMemberAddress + 1); *offset += sizeof(DWORD_PTR); break; } } memberIndex++; } } } if (memberName != nullptr) { break; } pLanguageEntry++; } } } if (memberName != nullptr) { break; } pNameEntry++; } } } if (memberName != nullptr) { break; } pTypeEntry++; } } break; } pSectionHeader++; } return memberName; } ``` 需要注意的是,由于这个函数的实现依赖于一些Windows API,因此在使用前需要先添加相关的头文件和库文件,并且在调用该函数时需要保证程序已经加载了相关的模块。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值