#define _CRT_SECURE_NO_WARNINGS #include<Windows.h> #include<stdlib.h> #include<stdio.h> #define FILE_PATH_IN "C:/Windows/System32/notepad.exe" static const char* szResName[0x11] { 0, "Corsor", "Bitmap", "Icon", "Menu", "Dialog", "StringTable", "FontDir", "Font", "Accelerator", "RCDATA", "MessageTable", "GroupCursor", "zz", "GroupIcon", "xx", "Version" }; DWORD RVA2FOA(IN DWORD stRVA, IN LPVOID pFileBuffer) { //重置头指针 PIMAGE_DOS_HEADER pDosHeader = nullptr; PIMAGE_NT_HEADERS pNTHeader = nullptr; PIMAGE_FILE_HEADER pFileHeader = nullptr; PIMAGE_OPTIONAL_HEADER pOptionalHeader = nullptr; PIMAGE_SECTION_HEADER pSectionHeader = nullptr; pDosHeader = (PIMAGE_DOS_HEADER)pFileBuffer; pNTHeader = (PIMAGE_NT_HEADERS)((DWORD)pFileBuffer + pDosHeader->e_lfanew); pFileHeader = (PIMAGE_FILE_HEADER)((DWORD)pNTHeader + sizeof(pNTHeader->Signature)); pOptionalHeader = (PIMAGE_OPTIONAL_HEADER)((DWORD)pFileHeader + IMAGE_SIZEOF_FILE_HEADER); pSectionHeader = (PIMAGE_SECTION_HEADER)((DWORD)pOptionalHeader + pFileHeader->SizeOfOptionalHeader); //内存对齐 DWORD dwMemAlignCount = pOptionalHeader->FileAlignment; //节区头个数 DWORD dwSectionCount = pFileHeader->NumberOfSections; //距节区的偏移 DWORD dwDiffer = 0; for (DWORD i = 0; i < dwSectionCount; i++,pSectionHeader++) { //在内存中对齐后的大小 DWORD dwBlockCount = 0; dwBlockCount = pSectionHeader->SizeOfRawData / dwMemAlignCount; dwBlockCount += (pSectionHeader->SizeOfRawData % dwMemAlignCount ? 1 : 0); DWORD dwBeginRVA = pSectionHeader->VirtualAddress; DWORD dwEndRVA = pSectionHeader->VirtualAddress + dwBlockCount * dwMemAlignCount; if (stRVA >= dwBeginRVA && stRVA < dwEndRVA) { dwDiffer = stRVA - dwBeginRVA; return dwDiffer + pSectionHeader->PointerToRawData; } else if (stRVA < dwBeginRVA) { return stRVA; } } return 0; } DWORD ReadFile(OUT LPVOID* pFileBuffer,IN const char* lpszFile) { LPVOID pTempFileBuffer = nullptr; FILE* pFile = nullptr; DWORD FileSize = 0; size_t n = 0; //打开文件 pFile = fopen(lpszFile, "rb"); if (pFile == nullptr) { printf("文件打开失败"); return 0; } //计算文件长度 fseek(pFile, 0, SEEK_END); FileSize = ftell(pFile); fseek(pFile, 0, SEEK_SET); //分配缓冲区 pTempFileBuffer = calloc(FileSize, sizeof(char)); if (pTempFileBuffer == nullptr) { printf("缓冲区分配失败"); fclose(pFile); return 0; } //初始化缓冲区 memset(pTempFileBuffer, 0, FileSize); //读取文件 n = fread(pTempFileBuffer, FileSize, 1, pFile); if (n == 0) { printf("读取文件失败"); fclose(pFile); free(pTempFileBuffer); pTempFileBuffer = nullptr; return 0; } //关闭文件 fclose(pFile); *pFileBuffer = pTempFileBuffer; pTempFileBuffer = nullptr; return n; } void PrintResourceTable() { PIMAGE_DOS_HEADER pDosHeader = nullptr; PIMAGE_NT_HEADERS pNTHeader = nullptr; PIMAGE_FILE_HEADER pFileHeader = nullptr; PIMAGE_OPTIONAL_HEADER pOptionalHeader = nullptr; PIMAGE_DATA_DIRECTORY pDataDirectory = nullptr; PIMAGE_RESOURCE_DIRECTORY pResourceTable = nullptr; PIMAGE_RESOURCE_DIRECTORY_ENTRY pResourceEntry = nullptr; LPVOID pFileBuffer = nullptr; DWORD dwSize = 0; dwSize = ReadFile(&pFileBuffer, FILE_PATH_IN); if (dwSize == 0 || pFileBuffer == nullptr) { printf("读取文件失败"); } pDosHeader = (PIMAGE_DOS_HEADER)pFileBuffer; pNTHeader = (PIMAGE_NT_HEADERS)((DWORD)pFileBuffer + pDosHeader->e_lfanew); pFileHeader = (PIMAGE_FILE_HEADER)((DWORD)pNTHeader + sizeof(pNTHeader->Signature)); pOptionalHeader = (PIMAGE_OPTIONAL_HEADER)((DWORD)pFileHeader + IMAGE_SIZEOF_FILE_HEADER); //定位资源表 pDataDirectory = (PIMAGE_DATA_DIRECTORY)(&pOptionalHeader->DataDirectory[IMAGE_DIRECTORY_ENTRY_RESOURCE]); pResourceTable = (PIMAGE_RESOURCE_DIRECTORY)((DWORD)pFileBuffer + RVA2FOA(pDataDirectory->VirtualAddress, pFileBuffer)); pResourceEntry = (PIMAGE_RESOURCE_DIRECTORY_ENTRY)(pResourceTable + 1); //解析第一层 DWORD dwTypeCount = pResourceTable->NumberOfIdEntries + pResourceTable->NumberOfNamedEntries; for (DWORD i = 0; i < dwTypeCount; i++) { //最高位为0 if (pResourceEntry[i].NameIsString == 0) { if (pResourceEntry[i].Id < 0x11) { printf("资源类型ID:%d %s\n", pResourceEntry[i].Id, szResName[pResourceEntry[i].Id]); } else { printf("资源类型ID:%d\n", pResourceEntry[i].Id); } } //最高位为1 else if (pResourceEntry[i].NameIsString == 1) { PIMAGE_RESOURCE_DIR_STRING_U pStr = (PIMAGE_RESOURCE_DIR_STRING_U)((DWORD)pResourceTable + pResourceEntry[i].NameOffset); WCHAR szStr[MAX_PATH] = { 0 }; memcpy(szStr, pStr->NameString, pStr->Length * sizeof(WCHAR)); printf("资源类型名称:%ls\n", szStr); } //解析第二层 if (pResourceEntry[i].DataIsDirectory == 1) { printf("第二层目录偏移:%x\n", pResourceEntry[i].OffsetToDirectory); PIMAGE_RESOURCE_DIRECTORY pRes2 = (PIMAGE_RESOURCE_DIRECTORY)((DWORD)pResourceTable + pResourceEntry[i].OffsetToDirectory); PIMAGE_RESOURCE_DIRECTORY_ENTRY pResEntry2 = (PIMAGE_RESOURCE_DIRECTORY_ENTRY)(pRes2 + 1); DWORD dwCount = pRes2->NumberOfIdEntries + pRes2->NumberOfNamedEntries; for (DWORD i = 0; i < dwCount; i++) { //最高位为0 if (pResEntry2[i].NameIsString == 0) { printf(" ->资源标识ID:%d\n", pResEntry2[i].Id); } else { PIMAGE_RESOURCE_DIR_STRING_U pStr = (PIMAGE_RESOURCE_DIR_STRING_U)((DWORD)pResourceTable + pResEntry2[i].NameOffset); WCHAR szStr[MAX_PATH] = { 0 }; memcpy(szStr, pStr->NameString, pStr->Length * sizeof(WCHAR)); printf(" ->资源名称:%ls\n", szStr); } //解析第三层 if (pResEntry2[i].DataIsDirectory == 1) { PIMAGE_RESOURCE_DIRECTORY pRes3 = (PIMAGE_RESOURCE_DIRECTORY)((DWORD)pResourceTable + pResEntry2[i].OffsetToDirectory); PIMAGE_RESOURCE_DIRECTORY_ENTRY pResEntry3 = (PIMAGE_RESOURCE_DIRECTORY_ENTRY)(pRes3 + 1); printf(" -->代码页标号为:%x\n", pResEntry3->Id); if (pResEntry3->DataIsDirectory == 0) { PIMAGE_RESOURCE_DATA_ENTRY pResDataEntry = (PIMAGE_RESOURCE_DATA_ENTRY)((DWORD)pResourceTable+pResEntry3->OffsetToData); printf(" --数据RVA:%x\n", pResDataEntry->OffsetToData); printf(" --数据大小:%x\n", pResDataEntry->Size); } } } } } } int main() { PrintResourceTable(); return 0; }
原文:https://www.cnblogs.com/yanmo/p/14645019.html