PE各种操作
#include<stdio.h> #include<stdlib.h> #include<Windows.h> #pragma warning(disable:4996) #define FILEPATH_IN "D:\\IPMSG2007.exe" #define FILEPATH_OUT "D:\\Dll2.dll" #define FILEPATH "D:\\Dll3.dll" #define SHELLCODELENGTH 12 #define MESSAGEBOXADDR 0x76A885D0 #define INFILEPATH "D:\\IPMSG2007.exe" BYTE shellCode[] = { 0x6A, 00, 0x6A, 00, 0x6A, 00, 0x6A, 00, 0xE8, 00, 00, 00, 00, 0xE9, 00, 00, 00, 00 }; //函数声明 //************************************************************************** //ReadPEFile:将文件读取到缓冲区 //参数说明: //lpszFile 文件路径 //pFileBuffer 缓冲区指针 //返回值说明: //读取失败返回0 否则返回实际读取的大小 //************************************************************************** DWORD ReadPEFile(IN LPSTR lpszFile, OUT LPVOID* pFileBuffer); //************************************************************************** //CopyFileBufferToImageBuffer:将文件从FileBuffer复制到ImageBuffer //参数说明: //pFileBuffer FileBuffer指针 //pImageBuffer ImageBuffer指针 //返回值说明: //读取失败返回0 否则返回复制的大小 //************************************************************************** DWORD CopyFileBufferToImageBuffer(IN LPVOID pFileBuffer, OUT LPVOID* pImageBuffer); //************************************************************************** //CopyImageBufferToNewBuffer:将ImageBuffer中的数据复制到新的缓冲区 //参数说明: //pImageBuffer ImageBuffer指针 //pNewBuffer NewBuffer指针 //返回值说明: //读取失败返回0 否则返回复制的大小 //************************************************************************** DWORD CopyImageBufferToNewBuffer(IN LPVOID pImageBuffer,OUT LPVOID* pNewBuffer); //************************************************************************** //MemeryTOFile:将内存中的数据复制到文件 //参数说明: //pMemBuffer 内存中数据的指针 //size 要复制的大小 //lpszFile 要存储的文件路径 //返回值说明: //读取失败返回0 否则返回复制的大小 //************************************************************************** BOOL MemeryTOFile(IN LPVOID pMemBuffer, IN size_t size, OUT LPSTR lpszFile); //************************************************************************** //RvaToFileOffset:将内存偏移转换为文件偏移 //参数说明: //pFileBuffer FileBuffer指针 //dwRva RVA的值 //返回值说明: //返回转换后的FOA的值 如果失败返回0 //************************************************************************** DWORD RvaToFileOffset(IN LPVOID pFileBuffer, IN DWORD dwRva); DWORD ReadPEFile(IN LPSTR lpszFile, OUT LPVOID* pFileBuffer) { FILE* fp = fopen(lpszFile, "rb"); DWORD fileSize = 0; if (!fp) { printf("无法打开exe文件!"); return 0; } fseek(fp, 0, SEEK_END); fileSize = ftell(fp); fseek(fp, 0, SEEK_SET); *pFileBuffer = malloc(fileSize); if (!(*pFileBuffer)) { printf("分配空间失败!"); fclose(fp); return 0; } size_t n = fread(*pFileBuffer, fileSize, 1, fp); if (!n) { printf("读取数据失败!"); free(*pFileBuffer); fclose(fp); return 0; } fclose(fp); return n; } DWORD CopyFileBufferToImageBuffer(IN LPVOID pFileBuffer, OUT LPVOID* pImageBuffer) { PIMAGE_DOS_HEADER pDosHeader = NULL; PIMAGE_NT_HEADERS pNTHeader = NULL; PIMAGE_FILE_HEADER pFileHeader = NULL; PIMAGE_OPTIONAL_HEADER32 pOptionalHeader = NULL; PIMAGE_SECTION_HEADER pSectionHeader = NULL; if ((*(PWORD)pFileBuffer) != IMAGE_DOS_SIGNATURE) { printf("不是有效的MZ标志!"); free(pFileBuffer); return 0; } pDosHeader = (PIMAGE_DOS_HEADER)pFileBuffer; if (*((PDWORD)((DWORD)pFileBuffer + pDosHeader->e_lfanew)) != IMAGE_NT_SIGNATURE) { printf("不是有效的PE标志!"); free(pFileBuffer); return 0; } pNTHeader = (PIMAGE_NT_HEADERS)((DWORD)pFileBuffer + pDosHeader->e_lfanew); pFileHeader = (PIMAGE_FILE_HEADER)((DWORD)pNTHeader + 4); pOptionalHeader = (PIMAGE_OPTIONAL_HEADER32)((DWORD)pFileHeader + IMAGE_SIZEOF_FILE_HEADER); pSectionHeader = (PIMAGE_SECTION_HEADER)((DWORD)pOptionalHeader + pFileHeader->SizeOfOptionalHeader); *pImageBuffer = malloc(pOptionalHeader->SizeOfImage); if (!(*pImageBuffer)) { printf("分配内存失败!"); return 0; } memset(*pImageBuffer, 0, pOptionalHeader->SizeOfImage); memcpy(*pImageBuffer, pFileBuffer, pOptionalHeader->SizeOfHeaders); //printf("%c%c", *((char *)*pImageBuffer), *((char*)*pImageBuffer + 1)); for (int i = 0; i < pFileHeader->NumberOfSections;i++) { memcpy((char *) *pImageBuffer + pSectionHeader->VirtualAddress,(char *) pFileBuffer + pSectionHeader->PointerToRawData, pSectionHeader->SizeOfRawData); pSectionHeader = (PIMAGE_SECTION_HEADER)((DWORD)pSectionHeader + IMAGE_SIZEOF_SECTION_HEADER); } return pOptionalHeader->SizeOfImage; } DWORD CopyImageBufferToNewBuffer(IN LPVOID pImageBuffer, OUT LPVOID* pNewBuffer) { PIMAGE_DOS_HEADER pDosHeader = NULL; PIMAGE_NT_HEADERS pNTHeader = NULL; PIMAGE_FILE_HEADER pFileHeader = NULL; PIMAGE_OPTIONAL_HEADER32 pOptionalHeader = NULL; PIMAGE_SECTION_HEADER pSectionHeader = NULL, flag = NULL; if ((*(PWORD)pImageBuffer) != IMAGE_DOS_SIGNATURE) { printf("不是有效的MZ标志!"); free(pImageBuffer); return 0; } pDosHeader = (PIMAGE_DOS_HEADER)pImageBuffer; if (*((PDWORD)((DWORD)pImageBuffer + pDosHeader->e_lfanew)) != IMAGE_NT_SIGNATURE) { printf("不是有效的PE标志!"); free(pImageBuffer); return 0; } pNTHeader = (PIMAGE_NT_HEADERS)((DWORD)pImageBuffer + pDosHeader->e_lfanew); pFileHeader = (PIMAGE_FILE_HEADER)((DWORD)pNTHeader + 4); pOptionalHeader = (PIMAGE_OPTIONAL_HEADER32)((DWORD)pFileHeader + IMAGE_SIZEOF_FILE_HEADER); pSectionHeader = flag = (PIMAGE_SECTION_HEADER)((DWORD)pOptionalHeader + pFileHeader->SizeOfOptionalHeader); int num = 0; for (int i = 0; i < pFileHeader->NumberOfSections; i++) { num += pSectionHeader->SizeOfRawData; pSectionHeader = (PIMAGE_SECTION_HEADER)((DWORD)pSectionHeader + IMAGE_SIZEOF_SECTION_HEADER); } pSectionHeader = flag; num += pOptionalHeader->SizeOfHeaders; *pNewBuffer = malloc(num); memset(*pNewBuffer, 0, num); memcpy(*pNewBuffer, pImageBuffer, pOptionalHeader->SizeOfHeaders); for (int j = 0; j < pFileHeader->NumberOfSections; j++) { memcpy((char*)*pNewBuffer + pSectionHeader->PointerToRawData, (char*)pImageBuffer + pSectionHeader->VirtualAddress, pSectionHeader->SizeOfRawData); pSectionHeader = (PIMAGE_SECTION_HEADER)((DWORD)pSectionHeader + IMAGE_SIZEOF_SECTION_HEADER); } //printf("%c %c %d\n", *((char*)*pNewBuffer), *((char*)*pNewBuffer + 1), __LINE__); return num; } BOOL MemeryTOFile(IN LPVOID pMemBuffer, IN size_t size, OUT LPSTR lpszFile) { FILE* fp; fp = fopen(lpszFile, "wb"); if (!fp) { printf("打开文件失败!"); return FALSE; } fwrite(pMemBuffer, size, 1, fp); fclose(fp); return TRUE; } VOID TestAddCodeInCodeSec() { LPVOID pFileBuffer = NULL; LPVOID pImageBuffer = NULL; LPVOID pNewBuffer = NULL; PIMAGE_DOS_HEADER pDosHeader = NULL; PIMAGE_OPTIONAL_HEADER32 pOptionalHeader = NULL; PIMAGE_SECTION_HEADER pSectionHeader = NULL; PBYTE codeBegin = NULL; BOOL isOk = FALSE; DWORD size = 0; ReadPEFile(FILEPATH_IN, &pFileBuffer); if (!pFileBuffer) { printf("文件-->缓冲区失败!"); return; } CopyFileBufferToImageBuffer(pFileBuffer, &pImageBuffer); if (!pImageBuffer) { printf("FileBuffer-->ImageBuffer失败!"); free(pFileBuffer); return; } pDosHeader = (PIMAGE_DOS_HEADER)pImageBuffer; pOptionalHeader = (PIMAGE_OPTIONAL_HEADER32)(((DWORD)pDosHeader + pDosHeader->e_lfanew) + 4 + IMAGE_SIZEOF_FILE_HEADER); pSectionHeader = (PIMAGE_SECTION_HEADER)((DWORD)pOptionalHeader + 0XE0); if (pSectionHeader->SizeOfRawData - pSectionHeader->Misc.VirtualSize < SHELLCODELENGTH) { printf("代码空闲区不够!"); free(pFileBuffer); free(pImageBuffer); } codeBegin = (PBYTE)((DWORD)pImageBuffer + pSectionHeader->VirtualAddress + pSectionHeader->Misc.VirtualSize); memcpy(codeBegin, shellCode, SHELLCODELENGTH); //修改E8 X DWORD callAddr = MESSAGEBOXADDR - (pOptionalHeader->ImageBase + (((DWORD)codeBegin + 0xD) - (DWORD)pImageBuffer)); *(PDWORD)(codeBegin + 9) = callAddr; //修改E9 X DWORD jmpAddr = (pOptionalHeader->ImageBase + pOptionalHeader->AddressOfEntryPoint) - (pOptionalHeader->ImageBase + ((DWORD)codeBegin + SHELLCODELENGTH - (DWORD)pImageBuffer)); *(PWORD)(codeBegin + 0xE) = jmpAddr; pOptionalHeader->AddressOfEntryPoint = (DWORD)codeBegin - (DWORD)pImageBuffer; size = CopyImageBufferToNewBuffer(pImageBuffer, &pNewBuffer); if (size == 0 || !pNewBuffer) { printf("ImageBuffer-->NewBuffer失败!"); free(pFileBuffer); free(pImageBuffer); return; } isOk = MemeryTOFile(pNewBuffer, size, FILEPATH_OUT); if (isOk) { printf("存盘成功!"); } } //添加节和节表 DWORD AddSectionToFileBuffer() { PIMAGE_DOS_HEADER pDosHeader = NULL; PIMAGE_NT_HEADERS pNTHeader = NULL; PIMAGE_FILE_HEADER pFileHeader = NULL; PIMAGE_OPTIONAL_HEADER32 pOptionalHeader = NULL; PIMAGE_SECTION_HEADER pSectionHeader = NULL; LPVOID pFileBuffer = NULL; DWORD addr = 0; ReadPEFile(FILEPATH_IN, &pFileBuffer); pDosHeader = (PIMAGE_DOS_HEADER)pFileBuffer; pNTHeader = (PIMAGE_NT_HEADERS)((DWORD)pDosHeader + pDosHeader->e_lfanew); pFileHeader = (PIMAGE_FILE_HEADER)((DWORD)pNTHeader + 4); pOptionalHeader = (PIMAGE_OPTIONAL_HEADER32)(pFileHeader + 1); pSectionHeader = (PIMAGE_SECTION_HEADER)(pOptionalHeader + 1); if (pOptionalHeader->SizeOfHeaders - (pDosHeader->e_lfanew + 4 + 20 + pFileHeader->SizeOfOptionalHeader + pFileHeader->NumberOfSections * 0x28) < 80) { printf("节表后空间不足!"); free(pFileBuffer); return; } PIMAGE_SECTION_HEADER pNewSectionHeader = pSectionHeader + (pFileHeader->NumberOfSections - 1); int sum = pNewSectionHeader->PointerToRawData + pNewSectionHeader->SizeOfRawData + 0x1000; addr = pNewSectionHeader->PointerToRawData + pNewSectionHeader->SizeOfRawData; LPVOID pNewBuffer = malloc(sum); memset((char *)pNewBuffer + pNewSectionHeader->PointerToRawData + pNewSectionHeader->SizeOfRawData, 0x20, 0x1000); pFileHeader->NumberOfSections += 1; pOptionalHeader->SizeOfImage += 0x1000; PIMAGE_SECTION_HEADER pLastSectionHeader = pSectionHeader + 4; memcpy(pLastSectionHeader, pSectionHeader, 0x28); strcpy(pLastSectionHeader->Name, ".tttt"); pLastSectionHeader->Misc.VirtualSize = 0x1000; int size = (pNewSectionHeader->Misc.VirtualSize > pNewSectionHeader->SizeOfRawData) ? pNewSectionHeader->Misc.VirtualSize : pNewSectionHeader->SizeOfRawData; pLastSectionHeader->VirtualAddress = pNewSectionHeader->VirtualAddress + size; pLastSectionHeader->SizeOfRawData = 0x1000; pLastSectionHeader->PointerToRawData = pNewSectionHeader->PointerToRawData + pNewSectionHeader->SizeOfRawData; //printf("%x\n", pLastSectionHeader->PointerToRawData); memcpy(pNewBuffer, pFileBuffer, sum); free(pFileBuffer); if (MemeryTOFile(pNewBuffer, sum, FILEPATH_OUT)) { printf("存盘成功!"); } free(pNewBuffer); return addr; } //扩大最后一个节 VOID ExpandLastSection() { PIMAGE_DOS_HEADER pDosHeader = NULL; PIMAGE_NT_HEADERS pNTHeader = NULL; PIMAGE_FILE_HEADER pFileHeader = NULL; PIMAGE_OPTIONAL_HEADER32 pOptionalHeader = NULL; PIMAGE_SECTION_HEADER pSectionHeader = NULL; LPVOID pFileBuffer = NULL; LPVOID pNewBuffer = NULL; ReadPEFile(FILEPATH_IN, &pFileBuffer); pDosHeader = (PIMAGE_DOS_HEADER)pFileBuffer; pNTHeader = (PIMAGE_NT_HEADERS)((DWORD)pDosHeader + pDosHeader->e_lfanew); pFileHeader = (PIMAGE_FILE_HEADER)((DWORD)pNTHeader + 4); pOptionalHeader = (PIMAGE_OPTIONAL_HEADER32)(pFileHeader + 1); pSectionHeader = (PIMAGE_SECTION_HEADER)(pOptionalHeader + 1); PIMAGE_SECTION_HEADER pLastSectionHeader = pSectionHeader + pFileHeader->NumberOfSections - 1; pNewBuffer = malloc(pLastSectionHeader->PointerToRawData + pLastSectionHeader->SizeOfRawData + 0x1000); memset((char*)pNewBuffer + pLastSectionHeader->PointerToRawData + pLastSectionHeader->SizeOfRawData, 0x20, 0x1000); pOptionalHeader->SizeOfImage += 0x1000; pLastSectionHeader->Misc.VirtualSize = pLastSectionHeader->SizeOfRawData = pLastSectionHeader->SizeOfRawData + 0x1000; memcpy(pNewBuffer, pFileBuffer, pLastSectionHeader->PointerToRawData + pLastSectionHeader->SizeOfRawData); if (MemeryTOFile(pNewBuffer, pLastSectionHeader->PointerToRawData + pLastSectionHeader->SizeOfRawData + 0x1000 , FILEPATH_OUT)) { printf("存盘成功!"); } free(pFileBuffer); free(pNewBuffer); } //合并所有节 VOID MergeAllSection() { PIMAGE_DOS_HEADER pDosHeader = NULL; PIMAGE_NT_HEADERS pNTHeader = NULL; PIMAGE_FILE_HEADER pFileHeader = NULL; PIMAGE_OPTIONAL_HEADER32 pOptionalHeader = NULL; PIMAGE_SECTION_HEADER pSectionHeader = NULL, pNextSectionHeader = NULL; LPVOID pFileBuffer = NULL, pImageBuffer = NULL, pNewBuffer = NULL; ReadPEFile(FILEPATH_IN, &pFileBuffer); CopyFileBufferToImageBuffer(pFileBuffer, &pImageBuffer); free(pFileBuffer); pDosHeader = (PIMAGE_DOS_HEADER)pImageBuffer; pNTHeader = (PIMAGE_NT_HEADERS)((DWORD)pDosHeader + pDosHeader->e_lfanew); pFileHeader = (PIMAGE_FILE_HEADER)((DWORD)pNTHeader + 4); pOptionalHeader = (PIMAGE_OPTIONAL_HEADER32)(pFileHeader + 1); pNextSectionHeader = pSectionHeader = (PIMAGE_SECTION_HEADER)(pOptionalHeader + 1); pSectionHeader->Misc.VirtualSize = pSectionHeader->SizeOfRawData = pOptionalHeader->SizeOfImage - pSectionHeader->VirtualAddress; for (int i = 0; i < pFileHeader->NumberOfSections; i++) { pSectionHeader->Characteristics = pSectionHeader->Characteristics | pNextSectionHeader->Characteristics; pNextSectionHeader += 1; } pFileHeader->NumberOfSections = 1; CopyImageBufferToNewBuffer(pImageBuffer, &pNewBuffer); if (MemeryTOFile(pNewBuffer, pOptionalHeader->SizeOfImage, FILEPATH_OUT)) { printf("存盘成功!"); } free(pImageBuffer); free(pNewBuffer); } DWORD RvaToFileOffset(IN LPVOID FileBuffer, IN DWORD Rva) { PIMAGE_DOS_HEADER pDOS = (PIMAGE_DOS_HEADER)FileBuffer; PIMAGE_NT_HEADERS pNT = (PIMAGE_NT_HEADERS)((DWORD)FileBuffer + pDOS->e_lfanew); PIMAGE_SECTION_HEADER pSECTION = (PIMAGE_SECTION_HEADER)(pNT + 1); int i; for (i = 0; i < pNT->FileHeader.NumberOfSections; i++, pSECTION++) { if (Rva >= pSECTION->VirtualAddress && Rva < pSECTION->VirtualAddress + pSECTION->SizeOfRawData) { return (Rva - pSECTION->VirtualAddress + pSECTION->PointerToRawData); break; } } return 0; } VOID PrintfExportImform() { PIMAGE_DOS_HEADER pDosHeader = NULL; PIMAGE_NT_HEADERS pNTHeader = NULL; PIMAGE_FILE_HEADER pFileHeader = NULL; PIMAGE_OPTIONAL_HEADER32 pOptionalHeader = NULL; PIMAGE_SECTION_HEADER pSectionHeader = NULL; PIMAGE_EXPORT_DIRECTORY pExport = NULL; LPVOID pFileBuffer = NULL; DWORD pExportFileOffset = NULL; ReadPEFile(FILEPATH_IN, &pFileBuffer); pDosHeader = (PIMAGE_DOS_HEADER)pFileBuffer; pNTHeader = (PIMAGE_NT_HEADERS)((DWORD)pDosHeader + pDosHeader->e_lfanew); pFileHeader = (PIMAGE_FILE_HEADER)((DWORD)pNTHeader + 4); pOptionalHeader = (PIMAGE_OPTIONAL_HEADER32)(pFileHeader + 1); pExportFileOffset = pOptionalHeader->DataDirectory[0].VirtualAddress; pExportFileOffset = RvaToFileOffset(pFileBuffer, pExportFileOffset); pExport = (PIMAGE_EXPORT_DIRECTORY)((DWORD)pFileBuffer + pExportFileOffset); //printf("%d", pExport->NumberOfFunctions); //函数地址 DWORD FileOffOfFunctions = RvaToFileOffset(pFileBuffer, pExport->AddressOfFunctions); LPVOID pFunctionInFile = (LPVOID)((DWORD)pFileBuffer + FileOffOfFunctions); for (int i = 0; i < pExport->NumberOfFunctions; i++) { printf("%x\n", *((PDWORD)pFunctionInFile)); pFunctionInFile = (LPVOID)((DWORD)pFunctionInFile + 4); } //函数名称 //AddressOfNames在文件中的偏移 DWORD FileOffOfNames = RvaToFileOffset(pFileBuffer, pExport->AddressOfNames); //printf("%x", FileOffOfNames); //AddressOfNames在文件中的地址 LPVOID pNamesInFile = (LPVOID)((DWORD)pFileBuffer + FileOffOfNames); //printf("%x", pNamesInFile); //AddressOfNames数组项在文件中的偏移 DWORD OffsetOfNames; LPVOID pNameInFile = NULL; //OffsetOfNames = RvaToFileOffset(pFileBuffer, (DWORD)(*((PDWORD)pNamesInFile))); for (int j = 0; j < pExport->NumberOfNames; j++) { OffsetOfNames = RvaToFileOffset(pFileBuffer, (DWORD)(*((PDWORD)pNamesInFile))); pNameInFile = (LPVOID)((DWORD)pFileBuffer + OffsetOfNames); printf("%s\n", pNameInFile); pNamesInFile = (LPVOID)((DWORD)pNamesInFile + 4); } //函数序号 DWORD OrdOffsetInFile = RvaToFileOffset(pFileBuffer, pExport->AddressOfNameOrdinals); LPVOID pOrdinalsInFile = (LPVOID)((DWORD)pFileBuffer + OrdOffsetInFile); for (int k = 0; k < pExport->NumberOfNames; k++) { printf("%d\n", *((PWORD)pOrdinalsInFile)); pOrdinalsInFile = (LPVOID)((DWORD)pOrdinalsInFile + 2); } } VOID GetFunctionAddrByName(LPVOID pFileBuffer, char* funcName) { PIMAGE_DOS_HEADER pDosHeader = NULL; PIMAGE_NT_HEADERS pNTHeader = NULL; PIMAGE_FILE_HEADER pFileHeader = NULL; PIMAGE_OPTIONAL_HEADER32 pOptionalHeader = NULL; PIMAGE_SECTION_HEADER pSectionHeader = NULL; PIMAGE_EXPORT_DIRECTORY pExport = NULL; DWORD pExportFileOffset = NULL; //ReadPEFile(FILEPATH_IN, &pFileBuffer); pDosHeader = (PIMAGE_DOS_HEADER)pFileBuffer; pNTHeader = (PIMAGE_NT_HEADERS)((DWORD)pDosHeader + pDosHeader->e_lfanew); pFileHeader = (PIMAGE_FILE_HEADER)((DWORD)pNTHeader + 4); pOptionalHeader = (PIMAGE_OPTIONAL_HEADER32)(pFileHeader + 1); pExportFileOffset = pOptionalHeader->DataDirectory[0].VirtualAddress; pExportFileOffset = RvaToFileOffset(pFileBuffer, pExportFileOffset); pExport = (PIMAGE_EXPORT_DIRECTORY)((DWORD)pFileBuffer + pExportFileOffset); //printf("%d", pExport->NumberOfFunctions); //函数名称 //AddressOfNames在文件中的偏移 DWORD FileOffOfNames = RvaToFileOffset(pFileBuffer, pExport->AddressOfNames); //printf("%x", FileOffOfNames); //AddressOfNames在文件中的地址 LPVOID pNamesInFile = (LPVOID)((DWORD)pFileBuffer + FileOffOfNames); //printf("%x", pNamesInFile); //AddressOfNames数组项在文件中的偏移 DWORD OffsetOfNames; LPVOID pNameInFile = NULL; //OffsetOfNames = RvaToFileOffset(pFileBuffer, (DWORD)(*((PDWORD)pNamesInFile))); int j; for (j = 0; j < pExport->NumberOfNames; j++) { OffsetOfNames = RvaToFileOffset(pFileBuffer, (DWORD)(*((PDWORD)pNamesInFile))); pNameInFile = (LPVOID)((DWORD)pFileBuffer + OffsetOfNames); if( !strcmp(funcName, (char *)pNameInFile)) break; pNamesInFile = (LPVOID)((DWORD)pNamesInFile + 4); } //函数序号 DWORD OrdOffsetInFile = RvaToFileOffset(pFileBuffer, pExport->AddressOfNameOrdinals); LPVOID pOrdinalsInFile = (LPVOID)((DWORD)pFileBuffer + OrdOffsetInFile); pOrdinalsInFile = (LPVOID)((DWORD)pOrdinalsInFile + 2 * j); int flag = *((PWORD)pOrdinalsInFile); //函数地址 DWORD FileOffOfFunctions = RvaToFileOffset(pFileBuffer, pExport->AddressOfFunctions); LPVOID pFunctionInFile = (LPVOID)((DWORD)pFileBuffer + FileOffOfFunctions); pFunctionInFile = (LPVOID)((DWORD)pFunctionInFile + 4 * flag); printf("%x\n", *((PDWORD)pFunctionInFile)); } VOID GetFunctionAddrByOrdinals(LPVOID pFileBuffer, int num) { PIMAGE_DOS_HEADER pDosHeader = NULL; PIMAGE_NT_HEADERS pNTHeader = NULL; PIMAGE_FILE_HEADER pFileHeader = NULL; PIMAGE_OPTIONAL_HEADER32 pOptionalHeader = NULL; PIMAGE_SECTION_HEADER pSectionHeader = NULL; PIMAGE_EXPORT_DIRECTORY pExport = NULL; DWORD pExportFileOffset = NULL; //ReadPEFile(FILEPATH_IN, &pFileBuffer); pDosHeader = (PIMAGE_DOS_HEADER)pFileBuffer; pNTHeader = (PIMAGE_NT_HEADERS)((DWORD)pDosHeader + pDosHeader->e_lfanew); pFileHeader = (PIMAGE_FILE_HEADER)((DWORD)pNTHeader + 4); pOptionalHeader = (PIMAGE_OPTIONAL_HEADER32)(pFileHeader + 1); pExportFileOffset = pOptionalHeader->DataDirectory[0].VirtualAddress; pExportFileOffset = RvaToFileOffset(pFileBuffer, pExportFileOffset); pExport = (PIMAGE_EXPORT_DIRECTORY)((DWORD)pFileBuffer + pExportFileOffset); //printf("%d", pExport->NumberOfFunctions); DWORD FileOffOfFunctions = RvaToFileOffset(pFileBuffer, pExport->AddressOfFunctions); LPVOID pFunctionInFile = (LPVOID)((DWORD)pFileBuffer + FileOffOfFunctions); pFunctionInFile = (LPVOID)((DWORD)pFunctionInFile + 4 * (num - pExport->Base)); printf("%x\n", *((PDWORD)pFunctionInFile)); } //打印重定位表 VOID PrintRelocation() { PIMAGE_DOS_HEADER pDosHeader = NULL; PIMAGE_NT_HEADERS pNTHeader = NULL; PIMAGE_FILE_HEADER pFileHeader = NULL; PIMAGE_OPTIONAL_HEADER32 pOptionalHeader = NULL; LPVOID pFileBuffer = NULL; PIMAGE_BASE_RELOCATION pRelocation = NULL; DWORD offset = 0; ReadPEFile(FILEPATH_IN, &pFileBuffer); pDosHeader = (PIMAGE_DOS_HEADER)pFileBuffer; pNTHeader = (PIMAGE_NT_HEADERS)((DWORD)pDosHeader + pDosHeader->e_lfanew); pFileHeader = (PIMAGE_FILE_HEADER)((DWORD)pNTHeader + 4); pOptionalHeader = (PIMAGE_OPTIONAL_HEADER32)(pFileHeader + 1); offset = RvaToFileOffset(pFileBuffer, pOptionalHeader->DataDirectory[5].VirtualAddress); pRelocation = (PIMAGE_BASE_RELOCATION)((DWORD)pFileBuffer + offset); int num = 0; int i = 0; LPVOID pDetails = NULL; while (1) { if (pRelocation->VirtualAddress == 0 && pRelocation->SizeOfBlock == 0) break; num = (pRelocation->SizeOfBlock - 8) / 2; printf("VirtualAddress:%x\n", pRelocation->VirtualAddress); printf("SizeOfBlock:%d\n", pRelocation->SizeOfBlock); printf("修改项:\n"); pDetails = (LPVOID)((DWORD)pRelocation + 8); for (i = 0; i < num; i++) { printf("%x\n", *((PWORD)pDetails)); pDetails = (LPVOID)((DWORD)pDetails + 2); } pRelocation = (PIMAGE_BASE_RELOCATION)((DWORD)pRelocation + pRelocation->SizeOfBlock); } } DWORD FileFoaToRva(LPVOID pFileBuffer, DWORD foa) { PIMAGE_DOS_HEADER pDosHeader = (PIMAGE_DOS_HEADER)pFileBuffer; PIMAGE_NT_HEADERS pNTHeader = (PIMAGE_NT_HEADERS)((DWORD)pDosHeader + pDosHeader->e_lfanew); PIMAGE_SECTION_HEADER pSectionHeader = (PIMAGE_SECTION_HEADER)(pNTHeader + 1); for (int i = 0; i < pNTHeader->FileHeader.NumberOfSections; i++, pSectionHeader++) { if (foa > pSectionHeader->PointerToRawData && foa <= pSectionHeader->PointerToRawData + pSectionHeader->SizeOfRawData) return (foa - pSectionHeader->PointerToRawData + pSectionHeader->VirtualAddress); } return 0; } VOID MoveExport() { PIMAGE_DOS_HEADER pDosHeader = NULL; PIMAGE_NT_HEADERS pNTHeader = NULL; PIMAGE_FILE_HEADER pFileHeader = NULL; PIMAGE_OPTIONAL_HEADER32 pOptionalHeader = NULL; PIMAGE_EXPORT_DIRECTORY pExport = NULL; LPVOID pFileBuffer = NULL; LPVOID pAddrOfFunc = NULL; LPVOID pAddrOfNames = NULL; LPVOID pAddrOfOri = NULL; LPVOID pCurrent = NULL; LPVOID pFunc = NULL; LPVOID pNames = NULL; LPVOID pOrdinals = NULL; LPVOID pNamesInFile = NULL; LPVOID pAddrName = NULL; int sum = 0; DWORD addr = AddSectionToFileBuffer(); sum = addr + 0x1000; ReadPEFile(FILEPATH_OUT, &pFileBuffer); pDosHeader = (PIMAGE_DOS_HEADER)pFileBuffer; pNTHeader = (PIMAGE_NT_HEADERS)((DWORD)pDosHeader + pDosHeader->e_lfanew); pFileHeader = (PIMAGE_FILE_HEADER)((DWORD)pNTHeader + 4); pOptionalHeader = (PIMAGE_OPTIONAL_HEADER32)(pFileHeader + 1); DWORD Foa = RvaToFileOffset(pFileBuffer, pOptionalHeader->DataDirectory[0].VirtualAddress); pExport = (PIMAGE_EXPORT_DIRECTORY)((DWORD)pFileBuffer + Foa); pAddrOfFunc = (LPVOID)((DWORD)pFileBuffer + RvaToFileOffset(pFileBuffer, pExport->AddressOfFunctions)); pAddrOfNames = (LPVOID)((DWORD)pFileBuffer + RvaToFileOffset(pFileBuffer, pExport->AddressOfNames)); pAddrOfOri = (LPVOID)((DWORD)pFileBuffer + RvaToFileOffset(pFileBuffer, pExport->AddressOfNameOrdinals)); pFunc = pCurrent = (LPVOID)((DWORD)pFileBuffer + addr); memcpy(pCurrent, pAddrOfFunc, 4 * pExport->NumberOfFunctions); pOrdinals = pCurrent = (LPVOID)((DWORD)pCurrent + 4 * pExport->NumberOfFunctions); memcpy(pCurrent, pAddrOfOri, 2 * pExport->NumberOfNames); pNames = pAddrName = pCurrent = (LPVOID)((DWORD)pCurrent + 2 * pExport->NumberOfNames); memcpy(pCurrent, pAddrOfNames, 4 * pExport->NumberOfNames); pCurrent = (LPVOID)((DWORD)pCurrent + 4 * pExport->NumberOfNames); for (int i = 0; i < pExport->NumberOfNames; i++) { Foa = RvaToFileOffset(pFileBuffer,(DWORD) (*((PDWORD)pAddrOfNames))); pNamesInFile = (LPVOID)((DWORD)pFileBuffer + Foa); strcpy((char*)pCurrent, (char*)pNamesInFile); *((PDWORD)pAddrName) = FileFoaToRva(pFileBuffer,(DWORD)pCurrent - (DWORD)pFileBuffer); pCurrent = (LPVOID)((DWORD)pCurrent + strlen((char*)pNamesInFile) + 1); pAddrName = (LPVOID)((DWORD)pAddrName + 4); pAddrOfNames = (LPVOID)((DWORD)pAddrOfNames + 4); } memcpy(pCurrent, pExport, 0x28); pExport = (PIMAGE_EXPORT_DIRECTORY)pCurrent; pExport->AddressOfFunctions = FileFoaToRva(pFileBuffer, (DWORD)pFunc - (DWORD)pFileBuffer); pExport->AddressOfNames = FileFoaToRva(pFileBuffer, (DWORD)pNames - (DWORD)pFileBuffer); pExport->AddressOfNameOrdinals = FileFoaToRva(pFileBuffer, (DWORD)pOrdinals - (DWORD)pFileBuffer); pOptionalHeader->DataDirectory[0].VirtualAddress = FileFoaToRva(pFileBuffer,(DWORD)pCurrent - (DWORD)pFileBuffer); MemeryTOFile(pFileBuffer, sum, FILEPATH); } DWORD MoveRelo() { PIMAGE_DOS_HEADER pDosHeader = NULL; PIMAGE_NT_HEADERS pNTHeader = NULL; PIMAGE_FILE_HEADER pFileHeader = NULL; PIMAGE_OPTIONAL_HEADER32 pOptionalHeader = NULL; PIMAGE_BASE_RELOCATION pRelocation = NULL; LPVOID pFileBuffer = NULL; LPVOID pNewBuffer = NULL; LPVOID pNewRe = NULL; int sum = 0; DWORD addr = AddSectionToFileBuffer(); sum = addr + 0x1000; ReadPEFile(FILEPATH_OUT, &pFileBuffer); pDosHeader = (PIMAGE_DOS_HEADER)pFileBuffer; pNTHeader = (PIMAGE_NT_HEADERS)((DWORD)pDosHeader + pDosHeader->e_lfanew); pFileHeader = (PIMAGE_FILE_HEADER)((DWORD)pNTHeader + 4); pOptionalHeader = (PIMAGE_OPTIONAL_HEADER32)(pFileHeader + 1); pRelocation = (PIMAGE_BASE_RELOCATION)((DWORD)pFileBuffer + RvaToFileOffset(pFileBuffer, pOptionalHeader->DataDirectory[5].VirtualAddress)); pNewRe = pNewBuffer = (LPVOID)((DWORD)pFileBuffer + addr); while (1) { if (pRelocation->SizeOfBlock == 0 && pRelocation->VirtualAddress == 0) { memcpy(pNewBuffer, pRelocation, 8); break; } memcpy(pNewBuffer, pRelocation, pRelocation->SizeOfBlock); pNewBuffer = (LPVOID)((DWORD)pNewBuffer + pRelocation->SizeOfBlock); pRelocation = (LPVOID)((DWORD)pRelocation + pRelocation->SizeOfBlock); } pOptionalHeader->DataDirectory[5].VirtualAddress = FileFoaToRva(pFileBuffer, (DWORD)pNewRe - (DWORD)pFileBuffer); MemeryTOFile(pFileBuffer, sum, FILEPATH); return addr; } VOID FixRelocation() { PIMAGE_DOS_HEADER pDosHeader = NULL; PIMAGE_NT_HEADERS pNTHeader = NULL; PIMAGE_FILE_HEADER pFileHeader = NULL; PIMAGE_OPTIONAL_HEADER32 pOptionalHeader = NULL; PIMAGE_BASE_RELOCATION pRelocation = NULL; LPVOID pFileBuffer = NULL; LPVOID pr = NULL; LPVOID offset = NULL; int addr = MoveRelo(); int sum = 0, howMany = 0; sum = addr + 0x1000; //printf("%x\n", addr); ReadPEFile(FILEPATH, &pFileBuffer); pDosHeader = (PIMAGE_DOS_HEADER)pFileBuffer; pNTHeader = (PIMAGE_NT_HEADERS)((DWORD)pDosHeader + pDosHeader->e_lfanew); pFileHeader = (PIMAGE_FILE_HEADER)((DWORD)pNTHeader + 4); pOptionalHeader = (PIMAGE_OPTIONAL_HEADER32)(pFileHeader + 1); //printf("%x\n", RvaToFileOffset(pFileBuffer, pOptionalHeader->DataDirectory[5].VirtualAddress)); pr = pRelocation = (PIMAGE_BASE_RELOCATION)((DWORD)pFileBuffer + RvaToFileOffset(pFileBuffer, pOptionalHeader->DataDirectory[5].VirtualAddress)); pOptionalHeader->ImageBase += 0x1000; int i = 0; while (1) { if (pRelocation->VirtualAddress == 0 && pRelocation->SizeOfBlock == 0) break; howMany = (pRelocation->SizeOfBlock - 8) / 2; for (i = 0; i < howMany; i++) { pr = (LPVOID)((DWORD)pRelocation + 8); if (*((PWORD)pr) >> 12 == 3) { offset = (LPVOID)(RvaToFileOffset(pFileBuffer, (pRelocation->VirtualAddress + (*((PWORD)pr) & 0xfff))) + (DWORD)pFileBuffer); *((PDWORD)offset) += 0x1000; } pr = (LPVOID)((DWORD)pr + 2); } pRelocation = (PIMAGE_BASE_RELOCATION)((DWORD)pRelocation + pRelocation->SizeOfBlock); } MemeryTOFile(pFileBuffer, sum, FILEPATH); } VOID PrintImportTable() { PIMAGE_DOS_HEADER pDosHeader = NULL; PIMAGE_NT_HEADERS pNTHeader = NULL; PIMAGE_FILE_HEADER pFileHeader = NULL; PIMAGE_OPTIONAL_HEADER32 pOptionalHeader = NULL; LPVOID pFileBuffer = NULL; PIMAGE_IMPORT_DESCRIPTOR pImport = NULL; PIMAGE_IMPORT_BY_NAME pName = NULL; DWORD addrOfOri = 0; int i = 0; ReadPEFile(FILEPATH_IN, &pFileBuffer); pDosHeader = (PIMAGE_DOS_HEADER)pFileBuffer; pNTHeader = (PIMAGE_NT_HEADERS)((DWORD)pDosHeader + pDosHeader->e_lfanew); pFileHeader = (PIMAGE_FILE_HEADER)((DWORD)pNTHeader + 4); pOptionalHeader = (PIMAGE_OPTIONAL_HEADER32)(pFileHeader + 1); pImport = (PIMAGE_IMPORT_DESCRIPTOR)((DWORD)pFileBuffer + RvaToFileOffset(pFileBuffer, pOptionalHeader->DataDirectory[1].VirtualAddress)); addrOfOri = (DWORD)pFileBuffer + RvaToFileOffset(pFileBuffer, pImport->OriginalFirstThunk); while (1) { if (pImport->OriginalFirstThunk == 0) break; printf("****************%s****************\n", (char *)((DWORD)pFileBuffer + RvaToFileOffset(pFileBuffer, pImport->Name))); addrOfOri = (DWORD)pFileBuffer + RvaToFileOffset(pFileBuffer, pImport->OriginalFirstThunk); while (1) { if ((DWORD)(*(PDWORD)addrOfOri == 0)) { break; } if ((DWORD)(*(PDWORD)addrOfOri) >> 31 == 1) printf("序号:%d\n", (DWORD)(*(PDWORD)addrOfOri) & 0x7fffffff); else { pName = (PIMAGE_IMPORT_BY_NAME)((DWORD)pFileBuffer + RvaToFileOffset(pFileBuffer, (DWORD)(*(PDWORD)addrOfOri))); i = 0; while (pName->Name[i] != 0) { printf("%c", pName->Name[i]); i++; } printf("\n"); } addrOfOri += 4; } pImport = (PIMAGE_IMPORT_DESCRIPTOR)((DWORD)pImport + 20); } free(pFileBuffer); } VOID printBoundImportTable() {//RVATOFOA需要考虑rva在sizeofheaders里的情况 PIMAGE_DOS_HEADER pDosHeader = NULL; PIMAGE_NT_HEADERS pNTHeader = NULL; PIMAGE_FILE_HEADER pFileHeader = NULL; PIMAGE_OPTIONAL_HEADER32 pOptionalHeader = NULL; PIMAGE_BOUND_IMPORT_DESCRIPTOR pBdImport = NULL, pImport = NULL; PIMAGE_BOUND_FORWARDER_REF pRef = NULL; LPVOID pFileBuffer = NULL; ReadPEFile(FILEPATH_IN, &pFileBuffer); pDosHeader = (PIMAGE_DOS_HEADER)pFileBuffer; pNTHeader = (PIMAGE_NT_HEADERS)((DWORD)pDosHeader + pDosHeader->e_lfanew); pFileHeader = (PIMAGE_FILE_HEADER)((DWORD)pNTHeader + 4); pOptionalHeader = (PIMAGE_OPTIONAL_HEADER32)(pFileHeader + 1); if (pOptionalHeader->DataDirectory[11].VirtualAddress == 0) { printf("没有绑定导入表\n"); return; } pBdImport = pImport = (PIMAGE_BOUND_IMPORT_DESCRIPTOR)((DWORD)pFileBuffer + RvaToFileOffset(pFileBuffer, pOptionalHeader->DataDirectory[11].VirtualAddress)); int i = 0; while (1) { if (pBdImport->OffsetModuleName == 0 && pBdImport->NumberOfModuleForwarderRefs == 0 && pBdImport->TimeDateStamp == 0) break; printf("***************OffsetMoudleName:%s*****************\n", (char*)((DWORD)pImport + pBdImport->OffsetModuleName)); printf("TimeDateStamp:%d\n", pBdImport->TimeDateStamp); printf("NumberOfModuleForWarderRefs:%d\n", pBdImport->NumberOfModuleForwarderRefs); pRef = (PIMAGE_BOUND_FORWARDER_REF)((DWORD)pBdImport + 8); for (i = 0; i < pBdImport->NumberOfModuleForwarderRefs; i++) { printf("***************OffsetMoudleName:%s*****************\n", (char*)((DWORD)pImport + pRef->OffsetModuleName)); printf("TimeDateStamp:%d\n", pRef->TimeDateStamp); pRef += 1; } pBdImport += pBdImport->NumberOfModuleForwarderRefs + 1; } } PrintResourceTable() { PIMAGE_DOS_HEADER pDosHeader = NULL; PIMAGE_NT_HEADERS pNTHeader = NULL; PIMAGE_FILE_HEADER pFileHeader = NULL; PIMAGE_OPTIONAL_HEADER32 pOptionalHeader = NULL; PIMAGE_RESOURCE_DIRECTORY pRes = NULL; PIMAGE_RESOURCE_DIRECTORY_ENTRY pEntry = NULL; PIMAGE_DATA_DIRECTORY pDataDir = NULL; LPVOID pFileBuffer = NULL; ReadPEFile(FILEPATH_IN, &pFileBuffer); pDosHeader = (PIMAGE_DOS_HEADER)pFileBuffer; pNTHeader = (PIMAGE_NT_HEADERS)((DWORD)pDosHeader + pDosHeader->e_lfanew); pFileHeader = (PIMAGE_FILE_HEADER)((DWORD)pNTHeader + 4); pOptionalHeader = (PIMAGE_OPTIONAL_HEADER32)(pFileHeader + 1); pRes = (PIMAGE_RESOURCE_DIRECTORY)((DWORD)pFileBuffer + RvaToFileOffset(pFileBuffer,pOptionalHeader->DataDirectory[2].VirtualAddress)); size_t num1 = pRes->NumberOfNamedEntries + pRes->NumberOfIdEntries; pEntry = (PIMAGE_RESOURCE_DIRECTORY_ENTRY)((DWORD)pRes + sizeof(IMAGE_RESOURCE_DIRECTORY)); for (size_t i = 0; i < num1; i++) { if (!pEntry[i].NameIsString) { printf("资源类型ID: %d \n", pEntry[i].Id); if (pEntry[i].Id == 3) { PIMAGE_RESOURCE_DIRECTORY pRes2 = (PIMAGE_RESOURCE_DIRECTORY)((DWORD)pRes + pEntry[i].OffsetToDirectory); PIMAGE_RESOURCE_DIRECTORY_ENTRY pEntry1 = (PIMAGE_RESOURCE_DIRECTORY_ENTRY)(pRes2 + 1); size_t num2 = pRes2->NumberOfIdEntries + pRes2->NumberOfNamedEntries; for (size_t i = 0; i < num2; i++) { if(!pEntry1[i].NameIsString) { printf("资源编号ID: %d", pEntry1[1].Id); } else { PIMAGE_RESOURCE_DIR_STRING_U pStr1 = (PIMAGE_RESOURCE_DIR_STRING_U)((DWORD)pRes + pEntry1[i].NameOffset); WCHAR str1[MAX_PATH] = { 0 }; memcpy_s(str1, MAX_PATH, pStr1, pStr1->Length * sizeof(WCHAR)); printf("%资源名称: %ls", str1); } PIMAGE_RESOURCE_DIRECTORY pRes3 = (PIMAGE_RESOURCE_DIRECTORY)((DWORD)pRes + pEntry1[i].OffsetToDirectory); PIMAGE_RESOURCE_DIRECTORY_ENTRY pEntry2 = (PIMAGE_RESOURCE_DIRECTORY_ENTRY)(pRes3 + 1); size_t num3 = pRes3->NumberOfIdEntries + pRes3->NumberOfNamedEntries; for (size_t i = 0; i < num3; i++) { PIMAGE_RESOURCE_DATA_ENTRY pData = (PIMAGE_RESOURCE_DATA_ENTRY)((DWORD)pRes + pEntry2[i].OffsetToData); printf("rva: %x size: %x \n", pData->OffsetToData, pData->Size); } printf("\n\n"); } } } else { PIMAGE_RESOURCE_DIR_STRING_U pStr = (PIMAGE_RESOURCE_DIR_STRING_U)((DWORD)pRes + pEntry[i].NameOffset); WCHAR str[MAX_PATH] = { 0 }; memcpy_s(str, MAX_PATH, pStr, pStr->Length * sizeof(WCHAR)); printf("%资源名称: %ls", str); } } } VOID PrintfResourceTable() { //定义一个名称数组 static char* szResName[0x11] = { 0, "鼠标指针", "位图", "图标", "菜单", "对话框", "字符串列表", "字体目录", "字体", "快捷键", "非格式化资源", "消息列表", "鼠标指针组", "zz", "图标组", "xx", "版本信息" }; //读取文件 PIMAGE_DOS_HEADER pDosHeader = NULL; PIMAGE_NT_HEADERS pNtHeader = NULL; PIMAGE_FILE_HEADER pFileHeader = NULL; PIMAGE_OPTIONAL_HEADER pOptionalHeader = NULL; PIMAGE_DATA_DIRECTORY pDataDirectory = NULL; PIMAGE_SECTION_HEADER pSectionHeader = NULL; PIMAGE_IMPORT_DESCRIPTOR pImportDescriptor = NULL; printf("打印的文件是:%s!\n", INFILEPATH); //定义文件缓冲区 LPVOID pFileBuffer = NULL; ReadPEFile(INFILEPATH, &pFileBuffer); if (pFileBuffer != 0) { printf("文件打开成功!\n"); } else { printf("文件打开失败!\n"); free(pFileBuffer); return; } pDosHeader = (PIMAGE_DOS_HEADER)pFileBuffer; pNtHeader = (PIMAGE_NT_HEADERS)((DWORD)pFileBuffer + pDosHeader->e_lfanew); pFileHeader = (PIMAGE_FILE_HEADER)(((DWORD)pNtHeader) + 4); pOptionalHeader = (PIMAGE_OPTIONAL_HEADER)((DWORD)pFileHeader + IMAGE_SIZEOF_FILE_HEADER); pDataDirectory = (PIMAGE_DATA_DIRECTORY)(((DWORD)pOptionalHeader) + 96); pDataDirectory += 2; PIMAGE_RESOURCE_DIRECTORY pResourceDirectory = NULL; DWORD RESRVA = pDataDirectory->VirtualAddress; DWORD RESFOA = 0; RESFOA = RvaToFileOffset(pFileBuffer, RESRVA); //定位资源目录 pResourceDirectory = (PIMAGE_RESOURCE_DIRECTORY)((DWORD)pFileBuffer + RESFOA); //printf("NumberOfNameEntries:%d,NumberOfIdEntries:%d\n", pResourceDirectory->NumberOfNamedEntries, pResourceDirectory->NumberOfIdEntries); //获取RESOURCEENTRY 的个数 size_t NumEntry = pResourceDirectory->NumberOfIdEntries + pResourceDirectory->NumberOfNamedEntries; //资源目录表的宽度 size_t dwResourceData = sizeof(PIMAGE_RESOURCE_DIRECTORY); //定位资源目录节点 PIMAGE_RESOURCE_DIRECTORY_ENTRY pResEntry = (PIMAGE_RESOURCE_DIRECTORY_ENTRY)((DWORD)pResourceDirectory + 16); //获取第一层 for (size_t i = 0; i < NumEntry; i++) { if (!pResEntry[i].NameIsString) {//0 if (pResEntry[i].Id < 0x11) //如果id大于0x11就是自己写的ID资源 { printf("资源类型ID:%p %s\n", pResEntry[i].Id, szResName[pResEntry[i].Id]); } else { char type[20]; sprintf_s(type, "%d", pResEntry[i].Id); printf("资源类型ID:%p %s\n", pResEntry[i].Id, type); } } else {//1那么这个第一个联合体的最高位为1,也就是说NameIsString为1,如果资源是未知的,这种资源属于字符串作为资源标识, Name就不会起作用了,NameOffset会指向IMAGE_RESOUCE_DIR_STRING_U的位置 //先获取偏移 PIMAGE_RESOURCE_DIR_STRING_U pStringRes = (PIMAGE_RESOURCE_DIR_STRING_U)((DWORD)pResourceDirectory + pResEntry[i].NameOffset); //定义一个用来接收自定义字符串的宽数组然后直接复制 WCHAR szStr[MAX_PATH] = { 0 }; memcpy_s(szStr, MAX_PATH, pStringRes->NameString, pStringRes->Length * sizeof(WCHAR)); printf("资源名称:%ls \n", szStr); } //第二层 if (pResEntry[i].DataIsDirectory) { printf("第二层目录偏移是:%p\n", pResEntry[i].OffsetToDirectory); //定义二层目录的目录头 以及entry PIMAGE_RESOURCE_DIRECTORY pResDirectory2 = (PIMAGE_RESOURCE_DIRECTORY)((DWORD)pResourceDirectory + pResEntry[i].OffsetToDirectory); PIMAGE_RESOURCE_DIRECTORY_ENTRY pResEntry2 = (PIMAGE_RESOURCE_DIRECTORY_ENTRY)(pResDirectory2 + 1); //获得ENtry个数 size_t NumEntry2 = pResDirectory2->NumberOfIdEntries + pResDirectory2->NumberOfNamedEntries; for (DWORD i = 0; i < NumEntry2; i++) { if (!pResEntry2[i].NameIsString) { printf("->资源标识ID:%d\n", pResEntry2[i].Id); } else { // 显示资源字符串 // NameOffset为相对资源的文件偏移 // 字符串偏移为 资源基地址+NameOffset PIMAGE_RESOURCE_DIR_STRING_U pstcString = (PIMAGE_RESOURCE_DIR_STRING_U)((DWORD)pResourceDirectory + pResEntry2[i].NameOffset); WCHAR szStr[MAX_PATH] = { 0 }; memcpy(szStr, pstcString->NameString, pstcString->Length * sizeof(WCHAR) ); printf("->资源字符串:%ls\n", szStr); } } //第三层 PIMAGE_RESOURCE_DIRECTORY pResourceDirectory3 = (PIMAGE_RESOURCE_DIRECTORY)((DWORD)pResourceDirectory + pResEntry2[i].OffsetToDirectory); printf("第三层目录:%d\n", pResourceDirectory3->NumberOfIdEntries); PIMAGE_RESOURCE_DIRECTORY_ENTRY pResEntry3 = (PIMAGE_RESOURCE_DIRECTORY_ENTRY)(pResourceDirectory3 + 1); if (!pResEntry3[i].DataIsDirectory) { // 取数据偏移,显示数据 PIMAGE_RESOURCE_DATA_ENTRY pResData = (PIMAGE_RESOURCE_DATA_ENTRY)((DWORD)pResourceDirectory + pResEntry3->OffsetToData); printf("->->->数据RVA:%x\t数据大小:%x\n", pResData->OffsetToData, pResData->Size); //printf("->->->数据大小:%x\n", pResData->Size); //printf("->->->数据RVA:%x\n", pResData->OffsetToData); } } printf("\n\n\n"); } } void main() { PVOID p2 = NULL; //pFileBuffer PVOID p3 = NULL; //pImageBuffer PVOID p4 = NULL; //pNewBuffer FILE* fp; int sum; ReadPEFile(FILEPATH_IN, &p2); //CopyFileBufferToImageBuffer(p2, &p3); //free(p2); /*sum = CopyImageBufferToNewBuffer(p3, &p4); free(p3);*/ //TestAddCodeInCodeSec(); //AddSectionToFileBuffer(); //ExpandLastSection(); //MergeAllSection(); //PrintfExportImform(); //GetFunctionAddrByName(p2, "sub1"); //GetFunctionAddrByOrdinals(p2, 2); //PrintRelocation(); //MoveExport(); //MoveRelo(); //FixRelocation(); //PrintImportTable(); //printBoundImportTable(); // LPVOID pFileBuffer = NULL; //ReadPEFile(FILEPATH_IN, &pFileBuffer); //PrintBoundImport(pFileBuffer); PrintResourceTable(); }