(编辑:jimmy 日期: 2024/12/24 浏览:2)
为什么选择SizeOfRawData,不选择Misc.VirtualSize来确定需要复制的节的大小?因为上面说过,Misc.VirtualSize的值由于节中有未初始化的数据且未使用而计算出预留的空间装入内存后的总大小的值可能会很大,如果这个值大到已经包含了后面一个节的数据,那么按照这个值将FileBuffer中的数据复制到ImageBuffer中很可能会把下一个节的数据也复制过去,所以直接用SizeOfRawData就可以了。但是如果节中包含未初始化数据,这样做起始就不太准确了,但是可以大致模拟这个过程即可
#include<stdio.h>#include<string.h>#include<malloc.h>#include<stdlib.h>#include<windows.h>​#define test 1​DWORD ToLoaderPE(LPSTR file_path, PVOID* pFileBuffer);​DWORD CopyFileBufferToImageBuffer(PVOID pFileBuffer, PVOID* pImageBuffer);DWORD CopyImageBufferToNewFileBuffer(PVOID pImageBuffer, PVOID* pNewFileBuffer);BOOL MemoryToFile(PVOID pMemBuffer, DWORD size, LPSTR lpszFile);​char file_path[] = "E:\\Reverse\\吾爱破解工具包2.0\\吾爱破解工具包\\Tools\\Others\\ipmsg.exe";char write_file_path[] = "C:\\Users\\whl\\Desktop\\1.exe";​//返回PE文件大小DWORD ToLoaderPE(LPSTR file_path, PVOID* pFileBuffer){ FILE* pFile = NULL; DWORD FileSize = 0; PVOID pFileBufferTemp = NULL;​ pFile = fopen(file_path, "rb");​ if (!pFile) { printf("(ToLoaderPE)Can't open file!\n"); return 0; }​ fseek(pFile, 0, SEEK_END); FileSize = ftell(pFile); printf("FileBuffer: %#x\n", FileSize); fseek(pFile, 0, SEEK_SET); pFileBufferTemp = malloc(FileSize);​ if (!pFileBufferTemp) { printf("(ToLoaderPE)Allocate dynamic memory failed!\n"); fclose(pFile); return 0; }​ DWORD n = fread(pFileBufferTemp, FileSize, 1, pFile);​ if (!n) { printf("(ToLoaderPE)Read file failed!\n"); free(pFileBufferTemp); fclose(pFile); return 0; } *pFileBuffer = pFileBufferTemp; pFileBufferTemp = NULL; fclose(pFile); return FileSize;}​DWORD CopyFileBufferToImageBuffer(PVOID pFileBuffer, PVOID* pImageBuffer){ PIMAGE_DOS_HEADER pDosHeader = NULL; PIMAGE_NT_HEADERS pNTHeader = NULL; PIMAGE_FILE_HEADER pPEHeader = NULL; PIMAGE_OPTIONAL_HEADER32 pOptionHeader = NULL; PIMAGE_SECTION_HEADER pSectionHeader = NULL;​ PVOID pImageTemp = NULL;​ if (!pFileBuffer) { printf("(CopyFileBufferToImageBuffer)Can't open file!\n"); return 0; }​ if (*((PWORD)pFileBuffer) != IMAGE_DOS_SIGNATURE) { printf("(CopyFileBufferToImageBuffer)No MZ flag, not exe file!\n"); return 0; }​ pDosHeader = (PIMAGE_DOS_HEADER)pFileBuffer;​ if (*((LPDWORD)((DWORD)pFileBuffer + pDosHeader->e_lfanew)) != IMAGE_NT_SIGNATURE) { printf("(CopyFileBufferToImageBuffer)Not a valid PE flag!\n"); return 0; }​ pNTHeader = (PIMAGE_NT_HEADERS)((DWORD)pFileBuffer + pDosHeader->e_lfanew); pPEHeader = (PIMAGE_FILE_HEADER)(((DWORD)pNTHeader) + 4); pOptionHeader = (PIMAGE_OPTIONAL_HEADER32)((DWORD)pPEHeader + IMAGE_SIZEOF_FILE_HEADER); pSectionHeader = (PIMAGE_SECTION_HEADER)((DWORD)pOptionHeader + pPEHeader->SizeOfOptionalHeader);​ pImageTemp = malloc(pOptionHeader->SizeOfImage);​ if (!pImageTemp) { printf("(CopyFileBufferToImageBuffer)Allocate dynamic memory failed!\n"); free(pImageTemp); return 0; }​ memset(pImageTemp, 0, pOptionHeader->SizeOfImage); memcpy(pImageTemp, pDosHeader, pOptionHeader->SizeOfHeaders);​ PIMAGE_SECTION_HEADER pSectionHeaderTemp = pSectionHeader;​ for (int n = 0; n < pPEHeader->NumberOfSections; n++, pSectionHeaderTemp++) { memcpy((PVOID)((DWORD)pImageTemp + pSectionHeaderTemp->VirtualAddress), (PVOID)((DWORD)pFileBuffer + pSectionHeaderTemp->PointerToRawData), pSectionHeaderTemp->SizeOfRawData); printf("VirtualAddress%d: %#10x PointerToRawData%d: %#10x\n", n, (DWORD)pImageTemp + pSectionHeader->VirtualAddress, n, (DWORD)pFileBuffer + pSectionHeader->PointerToRawData); } *pImageBuffer = pImageTemp; pImageTemp = NULL; return pOptionHeader->SizeOfImage;}​DWORD CopyImageBufferToNewFileBuffer(PVOID pImageBuffer, PVOID* pNewFileBuffer){ PIMAGE_DOS_HEADER pDosHeader = NULL; PIMAGE_NT_HEADERS pNTHeader = NULL; PIMAGE_FILE_HEADER pPEHeader = NULL; PIMAGE_OPTIONAL_HEADER32 pOptionHeader = NULL; PIMAGE_SECTION_HEADER pSectionHeader = NULL;​ LPVOID pTempNewbuffer = NULL;​ if (!pImageBuffer) { printf("(CopyImageBufferToNewBuffer)Can't open file!\n"); return 0; }​ if (*((PWORD)pImageBuffer) != IMAGE_DOS_SIGNATURE) { printf("(CopyImageBufferToNewBuffer)No MZ flag, not exe file!\n"); return 0; }​ pDosHeader = (PIMAGE_DOS_HEADER)pImageBuffer; if (*((PDWORD)((DWORD)pImageBuffer + pDosHeader->e_lfanew)) != IMAGE_NT_SIGNATURE) { printf("(CopyImageBufferToNewBuffer)Not a valid PE flag!\n"); return 0; }​ pNTHeader = (PIMAGE_NT_HEADERS)((DWORD)pImageBuffer + pDosHeader->e_lfanew); pPEHeader = (PIMAGE_FILE_HEADER)((DWORD)pNTHeader + 4); // 这里必须强制类型转换 pOptionHeader = (PIMAGE_OPTIONAL_HEADER32)((DWORD)pPEHeader + IMAGE_SIZEOF_FILE_HEADER); pSectionHeader = (PIMAGE_SECTION_HEADER)((DWORD)pOptionHeader + pPEHeader->SizeOfOptionalHeader);​ //获取new_buffer的大小 int new_buffer_size = pOptionHeader->SizeOfHeaders; for (DWORD i = 0; i < pPEHeader->NumberOfSections; i++) { new_buffer_size += pSectionHeader[i].SizeOfRawData; // pSectionHeader[i]另一种加法 } // 分配内存(newbuffer) pTempNewbuffer = malloc(new_buffer_size); if (!pTempNewbuffer) { printf("(CopyImageBufferToNewBuffer)Allocate dynamic memory failed!\n"); return 0; } memset(pTempNewbuffer, 0, new_buffer_size); memcpy(pTempNewbuffer, pDosHeader, pOptionHeader->SizeOfHeaders); // 循环拷贝节区 PIMAGE_SECTION_HEADER pTempSectionHeader = pSectionHeader; for (DWORD j = 0; j < pPEHeader->NumberOfSections; j++, pTempSectionHeader++) { //PointerToRawData节区在文件中的偏移,VirtualAddress节区在内存中的偏移地址,SizeOfRawData节在文件中对齐后的尺寸 memcpy((PDWORD)((DWORD)pTempNewbuffer + pTempSectionHeader->PointerToRawData), (PDWORD)((DWORD)pImageBuffer + pTempSectionHeader->VirtualAddress), pTempSectionHeader->SizeOfRawData); } //返回数据 *pNewFileBuffer = pTempNewbuffer; //暂存的数据传给参数后释放 pTempNewbuffer = NULL; return new_buffer_size; // 返回计算得到的分配内存的大小}​BOOL MemoryToFile(PVOID pMemBuffer, DWORD size, LPSTR lpszFile){ FILE* fp; fp = fopen(lpszFile, "wb"); if (fp != NULL) { fwrite(pMemBuffer, size, 1, fp); } fclose(fp); return 1;}​VOID operate(){ LPVOID pFileBuffer = NULL; LPVOID pNewFileBuffer = NULL; LPVOID pImageBuffer = NULL;​ DWORD ret1 = ToLoaderPE(file_path, &pFileBuffer); // &pFileBuffer(void**类型) 传递地址对其值可以进行修改 printf("exe->filebuffer 返回值为计算所得文件大小:%#x\n", ret1);​ DWORD ret2 = CopyFileBufferToImageBuffer(pFileBuffer, &pImageBuffer); printf("filebuffer -> imagebuffer返回值为计算所得文件大小:%#x\n", ret2); DWORD ret3 = CopyImageBufferToNewFileBuffer(pImageBuffer, &pNewFileBuffer); printf("imagebuffer -> newfilebuffer返回值为计算所得文件大小:%#x\n", ret3); MemoryToFile(pNewFileBuffer, ret3, write_file_path);​ free(pFileBuffer); free(pNewFileBuffer); free(pImageBuffer);}​int main(){ operate(); getchar(); return 0;}
#include<stdafx.h>#include<stdio.h>#include<stdlib.h>#include<windows.h>#define test 1DWORD ToLoaderPE(LPSTR file_path, PVOID* pFileBuffer);DWORD FoaToImageOffset(PVOID pBuffer, DWORD dwFoa);DWORD RvaToFileOffset(PVOID pBuffer, DWORD dwRva);char file_path[] = "C:\\Windows\\System32\\notepad.exe";char write_file_path[] = "E:\\滴水\\1.exe";​//返回PE文件大小DWORD ToLoaderPE(LPSTR file_path, PVOID* pFileBuffer){ FILE *pFile = NULL; DWORD FileSize = 0; PVOID pFileBufferTemp = NULL; pFile = fopen(file_path, "rb"); if (!pFile) { printf("(ToLoaderPE)Can't open file!\n"); return 0; } fseek(pFile, 0, SEEK_END); FileSize = ftell(pFile); printf("FileBuffer: %#x\n", FileSize); fseek(pFile, 0, SEEK_SET); pFileBufferTemp = malloc(FileSize); if (!pFileBufferTemp) { printf("(ToLoaderPE)Allocate dynamic memory failed!\n"); fclose(pFile); return 0; } DWORD n = fread(pFileBufferTemp, FileSize, 1, pFile); if (!n) { printf("(ToLoaderPE)Read file failed!\n"); free(pFileBufferTemp); fclose(pFile); return 0; } *pFileBuffer = pFileBufferTemp; pFileBufferTemp = NULL; fclose(pFile); return FileSize;}DWORD RvaToFileOffset(PVOID pBuffer, DWORD dwRva){ PIMAGE_DOS_HEADER pDosHeader = NULL; PIMAGE_NT_HEADERS pNTHeader = NULL; PIMAGE_FILE_HEADER pPEHeader = NULL; PIMAGE_OPTIONAL_HEADER32 pOptionHeader = NULL; PIMAGE_SECTION_HEADER pSectionHeader = NULL; if (!pBuffer) { printf("(RvaToFileOffset)Can't open file!\n"); return 0; } if (*((PWORD)pBuffer) != IMAGE_DOS_SIGNATURE) { printf("(RvaToFileOffset)No MZ flag, not exe file!\n"); return 0; } pDosHeader = (PIMAGE_DOS_HEADER)pBuffer; if (*((PDWORD)((DWORD)pBuffer + pDosHeader->e_lfanew)) != IMAGE_NT_SIGNATURE) { printf("(RvaToFileOffset)Not a valid PE flag!\n"); return 0; } printf("ImageOffset: %#x\n", dwRva); pNTHeader = (PIMAGE_NT_HEADERS)((DWORD)pBuffer + pDosHeader->e_lfanew); pPEHeader = (PIMAGE_FILE_HEADER)((DWORD)pNTHeader + 4); // 这里必须强制类型转换 pOptionHeader = (PIMAGE_OPTIONAL_HEADER32)((DWORD)pPEHeader + IMAGE_SIZEOF_FILE_HEADER); pSectionHeader = (PIMAGE_SECTION_HEADER)((DWORD)pOptionHeader + pPEHeader->SizeOfOptionalHeader); PIMAGE_SECTION_HEADER pSectionTemp = pSectionHeader; if (dwRva <= pOptionHeader->SizeOfHeaders) return (DWORD)dwRva; else { for (int n = 0; n < pPEHeader->NumberOfSections; n++, pSectionTemp++) { //判断 : 文件对齐+文件偏移>file_panyi>文件偏移 (即是在文件的哪个节中) if ((dwRva >= pSectionTemp->VirtualAddress) && (dwRva < pSectionTemp->VirtualAddress + pSectionTemp->Misc.VirtualSize)) { return dwRva - pSectionTemp->VirtualAddress + pSectionTemp->PointerToRawData; } } } printf("RvaToFoa failed!\n"); return 0;}DWORD FoaToImageOffset(PVOID pBuffer, DWORD dwFoa){ PIMAGE_DOS_HEADER pDosHeader = NULL; PIMAGE_NT_HEADERS pNTHeader = NULL; PIMAGE_FILE_HEADER pPEHeader = NULL; PIMAGE_OPTIONAL_HEADER32 pOptionHeader = NULL; PIMAGE_SECTION_HEADER pSectionHeader = NULL; if (!pBuffer) { printf("(FoaToImageOffset)Can't open file!\n"); return 0; } if (*((PWORD)pBuffer) != IMAGE_DOS_SIGNATURE) { printf("(FoaToImageOffset)No MZ flag, not exe file!\n"); return 0; } pDosHeader = (PIMAGE_DOS_HEADER)pBuffer; if (*((PDWORD)((DWORD)pBuffer + pDosHeader->e_lfanew)) != IMAGE_NT_SIGNATURE) { printf("(FoaToImageOffset)Not a valid PE flag!\n"); return 0; } printf("FileOffset: %#x\n", dwFoa); pNTHeader = (PIMAGE_NT_HEADERS)((DWORD)pBuffer + pDosHeader->e_lfanew); pPEHeader = (PIMAGE_FILE_HEADER)((DWORD)pNTHeader + 4); // 这里必须强制类型转换 pOptionHeader = (PIMAGE_OPTIONAL_HEADER32)((DWORD)pPEHeader + IMAGE_SIZEOF_FILE_HEADER); pSectionHeader = (PIMAGE_SECTION_HEADER)((DWORD)pOptionHeader + pPEHeader->SizeOfOptionalHeader); PIMAGE_SECTION_HEADER pSectionTemp = pSectionHeader; if (dwFoa <= pOptionHeader->SizeOfHeaders) return (DWORD)dwFoa; else { for (int n = 0; n < pPEHeader->NumberOfSections; n++, pSectionTemp++) { //判断 : 文件对齐+文件偏移>file_panyi>文件偏移 (即是在文件的哪个节中) if ((dwFoa >= pSectionTemp->PointerToRawData) && (dwFoa < pSectionTemp->PointerToRawData + pSectionTemp->SizeOfRawData)) { return dwFoa - pSectionTemp->PointerToRawData + pSectionTemp->VirtualAddress; } } } printf("FoaToRva failed!\n"); return 0;}VOID operate(){ LPVOID pFileBuffer = NULL; LPVOID pNewFileBuffer = NULL; LPVOID pImageBuffer = NULL; size_t pRVA = 0x0003123; size_t pFOA = 0x00020450; DWORD ret1 = ToLoaderPE(file_path, &pFileBuffer); // &pFileBuffer(void**类型) 传递地址对其值可以进行修改 printf("exe->filebuffer 返回值为计算所得文件大小:%#x\n", ret1); DWORD ret_FOA1 = RvaToFileOffset(pFileBuffer, pRVA); printf("内存偏移%#x 转换为文件中的偏移: %#x\n", pRVA, ret_FOA1); DWORD ret_RVA1 = FoaToImageOffset(pFileBuffer, pFOA); printf("文件偏移%#x 转换为内存中的偏移: %#x\n", pFOA, ret_RVA1); free(pFileBuffer); free(pNewFileBuffer); free(pImageBuffer);}int main(){ operate(); getchar(); return 0;}