检测测试利用PE架构, 将文件载入到内村, 主要利用的是节表的知识
代码目录(多动手,总会有收获!!):
// PEOperate.cpp: implementation of the PEOperate class. // ////////////////////////////////////////////////////////////////////// #include "PEOperate.h" ////////////////////////////////////////////////////////////////////// // Construction/Destruction ////////////////////////////////////////////////////////////////////// #include "windows.h" #include "stdio.h" //加载PE文件到内存中 LPVOID ReadPEFile(LPSTR lpszFile) { FILE *pFile = NULL; DWORD fileSize = 0; LPVOID pFileBuffer = NULL; //打开文件 pFile = fopen(lpszFile,"rb"); if(!pFile) { printf("无法打开文件EXE文件"); return NULL; } fseek(pFile,0,SEEK_END); fileSize = ftell(pFile); fseek(pFile,0,SEEK_SET); //分配缓冲区 pFileBuffer = malloc(fileSize); if(!pFileBuffer) { printf("分配空间失败!\n"); fclose(pFile); return NULL; } //文件读取 size_t n = fread(pFileBuffer,fileSize,1,pFile); if(!n) { printf("读取数据失败\n"); free(pFileBuffer); fclose(pFile); return NULL; } //关闭文件 fclose(pFile); return pFileBuffer; } //内存直接写入到文件 void WirteToFile(LPVOID pFileBuffer,size_t fileSize,LPSTR lpszFile) { FILE *pFile = NULL; //打开文件 pFile = fopen(lpszFile,"wb"); if(!pFile) { printf("无法打开文件EXE文件"); return; } size_t writeSize = fwrite(pFileBuffer,fileSize,1,pFile); printf("WirteSize:%d\n",writeSize); //关闭文件 fclose(pFile); return; } //打印所有的PE头信息 VOID PrintNTHeaders(LPSTR lpszFile) { LPVOID pFileBuffer = NULL; 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; pFileBuffer= ReadPEFile(lpszFile); if(!pFileBuffer) { printf("文件读取失败\n"); return; } //MZ标志 if(*((PWORD)pFileBuffer)!=IMAGE_DOS_SIGNATURE) { printf("不是有效的MZ标志\n"); free(pFileBuffer); return; } pDosHeader = (PIMAGE_DOS_HEADER)pFileBuffer; //打印DOS头 printf("------------DOS头------------\n"); printf("MZ标志: %x\n",pDosHeader->e_magic); printf("PE偏移: %x\n",pDosHeader->e_lfanew); //判断是否是有效的PE if(*((PDWORD)((DWORD)pFileBuffer+pDosHeader->e_lfanew))!=IMAGE_NT_SIGNATURE) { printf("不是有效的PE标志\n"); free(pFileBuffer); return; } pNTHeader = (PIMAGE_NT_HEADERS)((DWORD)pFileBuffer+pDosHeader->e_lfanew); //打印NT头 printf("------------NT头------------\n"); printf("Signature: %x\n",pNTHeader->Signature); pPEHeader = (PIMAGE_FILE_HEADER)(((DWORD)pNTHeader)+4); printf("------------标准PE头--------\n"); printf("Machine: %x\n",pPEHeader->Machine); printf("节的数量: %x\n",pPEHeader->NumberOfSections); printf("SizeOfOptionHeaders: %x\n",pPEHeader->SizeOfOptionalHeader); //可选择PE头 pOptionHeader = (PIMAGE_OPTIONAL_HEADER32)((DWORD)pPEHeader+IMAGE_SIZEOF_FILE_HEADER); printf("------------OPTION_PE头--------\n"); printf("Machine: %x \n",pOptionHeader->Magic); printf("OEP: %x \n",pOptionHeader->AddressOfEntryPoint); printf("ImageBase: %x \n",pOptionHeader->ImageBase); printf("SectionAlignment: %x \n",pOptionHeader->SectionAlignment); printf("FileAlignment: %x \n",pOptionHeader->FileAlignment); printf("SizeOfImage: %x \n",pOptionHeader->SizeOfImage); printf("SizeOfHeaders: %x \n",pOptionHeader->SizeOfHeaders); //节表的信息(分别打印) //确定节表的个数: int Section_Number = pPEHeader->NumberOfSections; pSectionHeader = (PIMAGE_SECTION_HEADER)((DWORD)pOptionHeader+pPEHeader->SizeOfOptionalHeader); for(int i=0;i<Section_Number;i++) { printf("------------节表信息:%d--------\n",i+1); printf("Name: %s \n",pSectionHeader->Name); printf("VirualSize : %x\n",pSectionHeader->Misc); printf("VirualAddress: %x\n",pSectionHeader->VirtualAddress); printf("SizeOfRawData: %x \n",pSectionHeader->SizeOfRawData); printf("PointerToRowData: %x \n",pSectionHeader->PointerToRawData); //下一个节表 pSectionHeader = (PIMAGE_SECTION_HEADER)((DWORD)pSectionHeader+40); } //释放内存 free(pFileBuffer); } //将PE的FileBuffer拷贝到ImageBuffer LPVOID CopyFileBufferToImageBuffer(LPVOID pFileBuffer) { 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(!pFileBuffer) { printf("文件读取失败\n"); return NULL; } //Header信息 pDosHeader = (PIMAGE_DOS_HEADER)pFileBuffer; 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); DWORD ImageSize = pOptionHeader->SizeOfImage; //LPVOID pImageBuffer=NULL; //分配缓冲区 LPVOID pImageBuffer=NULL; pImageBuffer = malloc(ImageSize); if(!pImageBuffer) { printf("pImageBuffer分配空间失败!\n"); return NULL; } //printf("%x \n",ImageSize); memset(pImageBuffer,0,ImageSize); //分段拷贝数据到ImageBuffer中 //1 拷贝头 DWORD HeaderSize = pOptionHeader->SizeOfHeaders; //DWORD Head_i = 0; //copy header memcpy(pImageBuffer,pFileBuffer,HeaderSize); //2 拷贝节 pSectionHeader //数量,位置 int Section_Number = pPEHeader->NumberOfSections; //分节进行写入 LPVOID pFileBuffer_sec = pFileBuffer; LPVOID pImageBuffer_sec = pImageBuffer; //printf("pFileBuffer_sec: %x \n",pFileBuffer_sec); //printf("pImageBuffer_sec: %x \n",pImageBuffer_sec); for(int i=0;i<Section_Number;i++) { DWORD FileSizeOfRawData = pSectionHeader->SizeOfRawData; DWORD FilePointerToRawData = pSectionHeader->PointerToRawData; DWORD MemVirtualAddress = pSectionHeader->VirtualAddress; pFileBuffer_sec=(LPVOID)((DWORD)pFileBuffer+FilePointerToRawData); pImageBuffer_sec=(LPVOID)((DWORD)pImageBuffer+MemVirtualAddress); //printf("pFileBuffer_sec: %x \n",pFileBuffer_sec); //printf("pImageBuffer_sec: %x \n",pImageBuffer_sec); memcpy(pImageBuffer_sec,pFileBuffer_sec,FileSizeOfRawData); //下一个节表 pSectionHeader = (PIMAGE_SECTION_HEADER)((DWORD)pSectionHeader+40); } //写出 //WirteToFile(pImageBuffer,ImageSize,"c://image.exe"); return pImageBuffer; } LPVOID CopyImageBuffertoNewBuffer(LPVOID pImageBuffer) { return NULL; } BOOL MemeryTOFile(LPVOID pMemBuffer,LPSTR lpszFile) { 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; //Header信息 pDosHeader = (PIMAGE_DOS_HEADER)pMemBuffer; pNTHeader = (PIMAGE_NT_HEADERS)((DWORD)pMemBuffer+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); //将内存中的文件转入到File中 FILE *pFile = NULL; //打开文件 pFile = fopen(lpszFile,"a+b"); if(!pFile) { printf("无法打开文件EXE文件"); return FALSE; } //写header DWORD SIZE_HEADER = pOptionHeader->SizeOfHeaders; fwrite(pMemBuffer,SIZE_HEADER,1,pFile); //写节表 int Section_Number = pPEHeader->NumberOfSections; LPVOID pImageBuffer_sec = pMemBuffer; printf("pImageBuffer_SEC : %x \n",pImageBuffer_sec); for(int i=0;i<Section_Number;i++) { DWORD FileSizeOfRawData = pSectionHeader->SizeOfRawData; DWORD FilePointerToRawData = pSectionHeader->PointerToRawData; DWORD MemVirtualAddress = pSectionHeader->VirtualAddress; pImageBuffer_sec=(LPVOID)((DWORD)pMemBuffer+MemVirtualAddress); printf("pImageBuffer_SEC : %x \n",pImageBuffer_sec); fwrite(pImageBuffer_sec,FileSizeOfRawData,1,pFile); pSectionHeader = (PIMAGE_SECTION_HEADER)((DWORD)pSectionHeader+40); } //关闭文件 fclose(pFile); return TRUE; } DWORD RVAToFileOffset(LPVOID pFileBuffer,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(!pFileBuffer) { printf("文件读取失败\n"); return NULL; } //Header信息 pDosHeader = (PIMAGE_DOS_HEADER)pFileBuffer; 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); DWORD ImageSize = pOptionHeader->SizeOfImage; int Section_Number = pPEHeader->NumberOfSections; int i=0; for(i=0;i<Section_Number;i++) { printf("VirualSize : %x\n",pSectionHeader->Misc); printf("VirualAddress: %x\n",pSectionHeader->VirtualAddress); DWORD dumpVirualSize = pSectionHeader->Misc.VirtualSize; DWORD dumpVirualAddress = pSectionHeader->VirtualAddress; if(dwRva>=dumpVirualAddress && dwRva <=dumpVirualAddress+dumpVirualSize) { printf("地址在第:%d 节 %s \n",i+1,pSectionHeader->Name); break; } //下一个节表 pSectionHeader = (PIMAGE_SECTION_HEADER)((DWORD)pSectionHeader+40); } //确定是第i+1节 //确定偏移距离 DWORD fileOff = pSectionHeader->PointerToRawData + (dwRva-pSectionHeader->VirtualAddress); return fileOff; }
0则评论给“FileBuffer To ImageBuffer”