// PEOperate.cpp: implementation of the PEOperate class. // ////////////////////////////////////////////////////////////////////// #include "PEOperate.h" ////////////////////////////////////////////////////////////////////// // Construction/Destruction ////////////////////////////////////////////////////////////////////// #include "windows.h" #include "stdio.h" #include "string.h" #define MESSAGEBOXADDR 0x77D507EA #define SHELLCODELENGTH 0x12 BYTE shellCode[]={ 0x6A,00,0x6A,00,0x6A,00,0x6A,00, 0xE8,00,00,00,00, 0xE9,00,00,00,00 }; //加载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; } DWORD FileOffsetToRVA(LPVOID pFileBuffer,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(!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++) { DWORD dumpPointerToRawData = pSectionHeader->PointerToRawData; DWORD dumpSizeOfRaw = pSectionHeader->SizeOfRawData; if(dwFoa>=dumpPointerToRawData && dwFoa <=dumpPointerToRawData+dumpSizeOfRaw) { //printf("地址在第:%d 节 %s \n",i+1,pSectionHeader->Name); break; } //下一个节表 pSectionHeader = (PIMAGE_SECTION_HEADER)((DWORD)pSectionHeader+40); } //确定是第i+1节 //确定偏移距离 DWORD RVA = pSectionHeader->VirtualAddress + (dwFoa-pSectionHeader->PointerToRawData); return RVA; } void TestAddCodeInCodeSec(LPSTR lpszFile) { LPVOID pFileBuffer = NULL; pFileBuffer= ReadPEFile(lpszFile); if(!pFileBuffer) { printf("文件读取失败\n"); return; } 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 pImageBuffer = CopyFileBufferToImageBuffer(pFileBuffer); //Header信息 pDosHeader = (PIMAGE_DOS_HEADER)pImageBuffer; 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); //确定添加代码的位置 //1判断能否添加 if((pSectionHeader->SizeOfRawData-pSectionHeader->Misc.VirtualSize)<=SHELLCODELENGTH){ printf("空余字节大小不够添加shellCode\n"); free(pFileBuffer); return; } //size_t file_size = pSectionHeader->SizeOfRawData-pSectionHeader->Misc.VirtualSize; //printf("%x \n",file_size); //2代码加的位置 printf("pImageBuffer: %x\n",pImageBuffer); DWORD shellLocation = pSectionHeader->VirtualAddress + pSectionHeader->Misc.VirtualSize; //确定位置 LPVOID pShellLoc = (LPVOID)((DWORD)pImageBuffer + shellLocation); printf("pShellLoc: %x\n",pShellLoc); //拷贝初始化代码到内存 memcpy(pShellLoc,shellCode,SHELLCODELENGTH); //修改E8地址 DWORD pE8Content = MESSAGEBOXADDR - (((DWORD)pShellLoc+13 )- ((DWORD)pImageBuffer)+ pOptionHeader->ImageBase); *(PDWORD)((DWORD)pShellLoc+9)=pE8Content; //修改E9地址 DWORD pE9Content = (pOptionHeader->AddressOfEntryPoint+pOptionHeader->ImageBase) - (((DWORD)pShellLoc+0x12 )- ((DWORD)pImageBuffer)+ pOptionHeader->ImageBase); *(PDWORD)((DWORD)pShellLoc+14)=pE9Content; //修改OEP pOptionHeader->AddressOfEntryPoint = (DWORD)pShellLoc-(DWORD)pImageBuffer; //更改完的ImageBuffer,写出到File中 MemeryTOFile(pImageBuffer,"C://testShell.exe"); //释放 free(pFileBuffer); free(pImageBuffer); return; } void TestAddSecToFile(LPSTR lpszFile) { LPVOID pFileBuffer = NULL; pFileBuffer= ReadPEFile(lpszFile); if(!pFileBuffer) { printf("文件读取失败\n"); return; } 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; PIMAGE_SECTION_HEADER pSectionHeader_ADD = 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); pSectionHeader_ADD = pSectionHeader; //1 判断能否添加节 DWORD Header_size = pDosHeader->e_lfanew + 4 + 20 + pPEHeader->SizeOfOptionalHeader + pPEHeader->NumberOfSections*40; if(pOptionHeader->SizeOfHeaders-Header_size<80) { printf("没有可用空间填充节表\n"); free(pFileBuffer); return; } printf("空间:%d\n",pOptionHeader->SizeOfHeaders-Header_size); //添加一个节 //确定参数 PIMAGE_SECTION_HEADER pSectionHeader_LAST = (PIMAGE_SECTION_HEADER)((DWORD)pSectionHeader+(pPEHeader->NumberOfSections-1)*40); pSectionHeader_ADD=(PIMAGE_SECTION_HEADER)((DWORD)pSectionHeader_ADD+(pPEHeader->NumberOfSections)*40); //="NewSec"; strcpy((char*)pSectionHeader_ADD->Name,"NewSec"); pSectionHeader_ADD->Misc.VirtualSize = 0x1000; pSectionHeader_ADD->VirtualAddress = pOptionHeader->SizeOfImage; pSectionHeader_ADD->SizeOfRawData = 0x1000; pSectionHeader_ADD->PointerToRawData = pSectionHeader_LAST->PointerToRawData+pSectionHeader_LAST->SizeOfRawData; pSectionHeader_ADD->Characteristics = pSectionHeader->Characteristics; //填充0 LPVOID pSectionEND = (LPVOID)((DWORD)pSectionHeader_ADD+40); memset(pSectionEND,0,IMAGE_SIZEOF_SECTION_HEADER); printf("pFileBuffer: %x\n",pFileBuffer); printf("pSectionHeader: %x\n",pSectionHeader); printf("pSectionHeader_LAST: %x\n",pSectionHeader_LAST); printf("pSectionHeader_ADD: %x\n",pSectionHeader_ADD); printf("pSectionEND: %x\n",pSectionEND); //修改PE头信息 pPEHeader->NumberOfSections = pPEHeader->NumberOfSections +1; pOptionHeader->SizeOfImage = pOptionHeader->SizeOfImage+0x1000; //写入到文件 FILE *pOutFile = NULL; //打开文件 pOutFile = fopen("C://addSec.exe","a+b"); if(!pOutFile) { printf("无法打开文件EXE文件"); return; } //写出第一部分 printf("length: %x \n ",pSectionHeader_ADD->PointerToRawData+pSectionHeader_ADD->SizeOfRawData); size_t writeSize = fwrite(pFileBuffer,pSectionHeader_ADD->PointerToRawData,1,pOutFile); printf("WirteSize:%d\n",writeSize); //写出第二部分 LPVOID pNewBuffer=(LPVOID)malloc(0x1000); if(pNewBuffer==NULL) { printf("pNewBuffer分配空间失败\n"); return; } memset(pNewBuffer,0,0x1000); writeSize = fwrite(pNewBuffer,0x1000,1,pOutFile); //关闭文件 fclose(pOutFile); free(pFileBuffer); free(pNewBuffer); } void TestAddLastSectionToFile(LPSTR lpszFile) { LPVOID pFileBuffer = NULL; pFileBuffer= ReadPEFile(lpszFile); if(!pFileBuffer) { printf("文件读取失败\n"); return; } 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; PIMAGE_SECTION_HEADER pSectionHeader_LAST = 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); pSectionHeader_LAST = (PIMAGE_SECTION_HEADER)((DWORD)pSectionHeader+(pPEHeader->NumberOfSections-1)*40); int fileLength = pSectionHeader_LAST->PointerToRawData+pSectionHeader_LAST->SizeOfRawData; //更改ImageSize pOptionHeader->SizeOfImage = pOptionHeader->SizeOfImage+0x1000; //更改最后一个节的SizeOfRawData 以及 VirtualSize pSectionHeader_LAST->SizeOfRawData = pSectionHeader_LAST->SizeOfRawData+0x1000; pSectionHeader_LAST->Misc.VirtualSize = pSectionHeader_LAST->Misc.VirtualSize+0x1000; //写出文件 //写入到文件 FILE *pOutFile = NULL; //打开文件 pOutFile = fopen("C://addSecLength.exe","a+b"); if(!pOutFile) { printf("无法打开文件EXE文件"); return; } //写出第一部分 printf("length: %x \n ",fileLength); size_t writeSize = fwrite(pFileBuffer,fileLength,1,pOutFile); printf("WirteSize:%d\n",writeSize); //写出第二部分 LPVOID pNewBuffer=(LPVOID)malloc(0x1000); if(pNewBuffer==NULL) { printf("pNewBuffer分配空间失败\n"); return; } memset(pNewBuffer,0,0x1000); writeSize = fwrite(pNewBuffer,0x1000,1,pOutFile); //关闭文件 fclose(pOutFile); free(pFileBuffer); free(pNewBuffer); } DWORD Align(int size,int filesize) { if(size<=filesize) { return filesize; }else { int n=0; if(size%filesize == 0) { n = size/filesize; }else{ n = size/filesize; n=n+1; } return filesize*n; } } void TestChangeOneSec(LPSTR lpszFile) { LPVOID pFileBuffer = NULL; pFileBuffer= ReadPEFile(lpszFile); if(!pFileBuffer) { printf("文件读取失败\n"); return; } LPVOID pImageBuffer =NULL; pImageBuffer = CopyFileBufferToImageBuffer(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; PIMAGE_SECTION_HEADER pSectionHeader_LAST = NULL; //Header信息 pDosHeader = (PIMAGE_DOS_HEADER)pImageBuffer; 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); pSectionHeader_LAST = (PIMAGE_SECTION_HEADER)((DWORD)pSectionHeader+(pPEHeader->NumberOfSections-1)*40); //合并节的操作 DWORD LastSize = (pSectionHeader_LAST->SizeOfRawData > pSectionHeader_LAST->Misc.VirtualSize)?pSectionHeader_LAST->SizeOfRawData:pSectionHeader_LAST->Misc.VirtualSize; pSectionHeader->Misc.VirtualSize = pSectionHeader_LAST->VirtualAddress + LastSize - pSectionHeader->VirtualAddress; pSectionHeader->SizeOfRawData = pSectionHeader_LAST->VirtualAddress + LastSize - pSectionHeader->VirtualAddress; pSectionHeader->PointerToRawData = pSectionHeader->VirtualAddress; //设置属性值 //pSectionHeader->Characteristics DWORD MyCharacteristics = pSectionHeader->Characteristics; for(int k=0;k<pPEHeader->NumberOfSections;k++) { PIMAGE_SECTION_HEADER pSectionHeader_NEXT; pSectionHeader_NEXT= (PIMAGE_SECTION_HEADER)((DWORD)pSectionHeader+k*40); MyCharacteristics = MyCharacteristics |(pSectionHeader_NEXT->Characteristics); } printf("MyCharacteristics: %x \n",MyCharacteristics); pSectionHeader->Characteristics = MyCharacteristics; pPEHeader->NumberOfSections = 0x1; DWORD ImageSize = pOptionHeader->SizeOfImage; //直接写出到文件 WirteToFile(pImageBuffer,ImageSize,"C://hebing.exe"); } //IMAGE_DATA_DIRECTORY void printDirectoryData(LPSTR lpszFile) { LPVOID pFileBuffer = NULL; pFileBuffer= ReadPEFile(lpszFile); if(!pFileBuffer) { printf("文件读取失败\n"); return; } 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; PIMAGE_DATA_DIRECTORY DataDirectory=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); //定位Directory_Data; DataDirectory = pOptionHeader->DataDirectory; //IMAGE_DIRECTORY_ENTRY_EXPORT printf("IMAGE_DIRECTORY_ENTRY_EXPORT: Address: %x ,Size: %x \n",DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].VirtualAddress, DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].Size); printf("IMAGE_DIRECTORY_ENTRY_IMPORT: Address: %x ,Size: %x \n",DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].VirtualAddress, DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].Size); printf("IMAGE_DIRECTORY_ENTRY_RESOURCE: Address: %x ,Size: %x \n",DataDirectory[IMAGE_DIRECTORY_ENTRY_RESOURCE].VirtualAddress, DataDirectory[IMAGE_DIRECTORY_ENTRY_RESOURCE].Size); printf("IMAGE_DIRECTORY_ENTRY_EXCEPTION: Address: %x ,Size: %x \n",DataDirectory[IMAGE_DIRECTORY_ENTRY_EXCEPTION].VirtualAddress, DataDirectory[IMAGE_DIRECTORY_ENTRY_EXCEPTION].Size); printf("IMAGE_DIRECTORY_ENTRY_SECURITY: Address: %x ,Size: %x \n",DataDirectory[IMAGE_DIRECTORY_ENTRY_SECURITY].VirtualAddress, DataDirectory[IMAGE_DIRECTORY_ENTRY_SECURITY].Size); printf("IMAGE_DIRECTORY_ENTRY_BASERELOC: Address: %x ,Size: %x \n",DataDirectory[IMAGE_DIRECTORY_ENTRY_BASERELOC].VirtualAddress, DataDirectory[IMAGE_DIRECTORY_ENTRY_BASERELOC].Size); printf("IMAGE_DIRECTORY_ENTRY_DEBUG: Address: %x ,Size: %x \n",DataDirectory[IMAGE_DIRECTORY_ENTRY_DEBUG].VirtualAddress, DataDirectory[IMAGE_DIRECTORY_ENTRY_DEBUG].Size); printf("IMAGE_DIRECTORY_ENTRY_ARCHITECTURE: Address: %x ,Size: %x \n",DataDirectory[IMAGE_DIRECTORY_ENTRY_ARCHITECTURE].VirtualAddress, DataDirectory[IMAGE_DIRECTORY_ENTRY_ARCHITECTURE].Size); printf("IMAGE_DIRECTORY_ENTRY_GLOBALPTR: Address: %x ,Size: %x \n",DataDirectory[IMAGE_DIRECTORY_ENTRY_GLOBALPTR].VirtualAddress, DataDirectory[IMAGE_DIRECTORY_ENTRY_GLOBALPTR].Size); printf("IMAGE_DIRECTORY_ENTRY_TLS: Address: %x ,Size: %x \n",DataDirectory[IMAGE_DIRECTORY_ENTRY_TLS].VirtualAddress, DataDirectory[IMAGE_DIRECTORY_ENTRY_TLS].Size); printf("IMAGE_DIRECTORY_ENTRY_LOAD_CONFIG: Address: %x ,Size: %x \n",DataDirectory[IMAGE_DIRECTORY_ENTRY_LOAD_CONFIG].VirtualAddress, DataDirectory[IMAGE_DIRECTORY_ENTRY_LOAD_CONFIG].Size); printf("IMAGE_DIRECTORY_ENTRY_BOUND_IMPORT: Address: %x ,Size: %x \n",DataDirectory[IMAGE_DIRECTORY_ENTRY_BOUND_IMPORT].VirtualAddress, DataDirectory[IMAGE_DIRECTORY_ENTRY_BOUND_IMPORT].Size); printf("IMAGE_DIRECTORY_ENTRY_IAT: Address: %x ,Size: %x \n",DataDirectory[IMAGE_DIRECTORY_ENTRY_IAT].VirtualAddress, DataDirectory[IMAGE_DIRECTORY_ENTRY_IAT].Size); printf("IMAGE_DIRECTORY_ENTRY_DELAY_IMPORT: Address: %x ,Size: %x \n",DataDirectory[IMAGE_DIRECTORY_ENTRY_DELAY_IMPORT].VirtualAddress, DataDirectory[IMAGE_DIRECTORY_ENTRY_DELAY_IMPORT].Size); printf("IMAGE_DIRECTORY_ENTRY_COM_DESCRIPTOR: Address: %x ,Size: %x \n",DataDirectory[IMAGE_DIRECTORY_ENTRY_COM_DESCRIPTOR].VirtualAddress, DataDirectory[IMAGE_DIRECTORY_ENTRY_COM_DESCRIPTOR].Size); } void TestExportDirectory(LPSTR lpszFile) { LPVOID pFileBuffer = NULL; pFileBuffer= ReadPEFile(lpszFile); if(!pFileBuffer) { printf("文件读取失败\n"); return; } 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; PIMAGE_DATA_DIRECTORY DataDirectory=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); //定位Directory_Data; DataDirectory = pOptionHeader->DataDirectory; //导出表 printf("IMAGE_DIRECTORY_ENTRY_EXPORT: Address: %x ,Size: %x \n",DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].VirtualAddress, DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].Size); //DWORD RVAToFileOffset(LPVOID pFileBuffer,DWORD dwRva) DWORD FoA = RVAToFileOffset(pFileBuffer,0x2df10); //printf("%x \n",FoA); DWORD Export_Directory_Address = DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].VirtualAddress; DWORD Export_Directory_Size = DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].Size; FoA = RVAToFileOffset(pFileBuffer,Export_Directory_Address); /* typedef struct _IMAGE_EXPORT_DIRECTORY { DWORD Characteristics; DWORD TimeDateStamp; WORD MajorVersion; WORD MinorVersion; DWORD Name; //指向该导出表文件名字符串 DWORD Base; //导出函数起始序号 DWORD NumberOfFunctions; //所有导出函数的个数 DWORD NumberOfNames; //以函数名字导出的函数个数 DWORD AddressOfFunctions; // 导出函数地址表 RVA DWORD AddressOfNames; // 导出函数名称表 RVA DWORD AddressOfNameOrdinals; // 导出函数序号表 RVA } IMAGE_EXPORT_DIRECTORY, *PIMAGE_EXPORT_DIRECTORY; */ //定位导出表的位置 PIMAGE_EXPORT_DIRECTORY pExDirectory = NULL; pExDirectory = (PIMAGE_EXPORT_DIRECTORY)((DWORD)pFileBuffer + FoA); printf("Characteristics: %x\n",pExDirectory->Characteristics); printf("TimeDateStamp: %x\n",pExDirectory->TimeDateStamp); printf("MajorVersion: %x\n",pExDirectory->MajorVersion); printf("MinorVersion: %x\n",pExDirectory->MinorVersion); printf("Name: %x\n",pExDirectory->Name); printf("Base: %x\n",pExDirectory->Base); printf("NumberOfFunctions: %x\n",pExDirectory->NumberOfFunctions); printf("NumberOfNames: %x\n",pExDirectory->NumberOfNames); printf("AddressOfFunctions: %x\n",pExDirectory->AddressOfFunctions); printf("AddressOfNames: %x\n",pExDirectory->AddressOfNames); printf("AddressOfNameOrdinals: %x\n",pExDirectory->AddressOfNameOrdinals); printf("------------------------\n"); //输出函数地址表信息 //AddressOfFunctions DWORD ExAddressOfFunctions = pExDirectory->AddressOfFunctions; DWORD ExAddressOfFunctionsFoA = RVAToFileOffset(pFileBuffer,ExAddressOfFunctions); DWORD ExNumberOfFunctions = pExDirectory->NumberOfFunctions; PDWORD pExAddressOfFunctions = NULL; pExAddressOfFunctions = (PDWORD)((DWORD)pFileBuffer + ExAddressOfFunctionsFoA); //输出每个函数地址表信息 DWORD k =0; for(k=0;k<ExNumberOfFunctions;k++) { printf("%d : %x \n",k,*pExAddressOfFunctions); pExAddressOfFunctions++; } printf("------------------------\n"); //函数名称表 DWORD ExAddressOfNames = pExDirectory->AddressOfNames; DWORD ExAddressOfNamesFoA = RVAToFileOffset(pFileBuffer,ExAddressOfNames); DWORD ExNumberOfNames = pExDirectory->NumberOfNames; PDWORD pExAddressOfNames = NULL; pExAddressOfNames = (PDWORD)((DWORD)pFileBuffer + ExAddressOfNamesFoA); for(k=0;k<ExNumberOfNames;k++) { printf("%d : %x \n",k,*pExAddressOfNames); //函数名的地址转换为FoA ,输出函数名 PDWORD NameAddress = (PDWORD)RVAToFileOffset(pFileBuffer,*pExAddressOfNames); //输出函数名 printf("%s \n",(char*)((DWORD)pFileBuffer + (DWORD)NameAddress)); pExAddressOfNames++; } //函数序号表 printf("------------------------\n"); DWORD ExAddressOfNameOrdinals = pExDirectory->AddressOfNameOrdinals; DWORD ExAddressOfNameOrdinalsFoA = RVAToFileOffset(pFileBuffer,ExAddressOfNameOrdinals); ExNumberOfNames = pExDirectory->NumberOfNames; PWORD pExAddressOfNameOrdinals = NULL; pExAddressOfNameOrdinals = (PWORD)((DWORD)pFileBuffer + ExAddressOfNameOrdinalsFoA); for(k=0;k<ExNumberOfNames;k++) { printf("%d : %x \n",k,*pExAddressOfNameOrdinals); pExAddressOfNameOrdinals++; } } DWORD GetFunctionAddrByName(LPVOID pFileBuffer,LPSTR FunctionName) { //LPVOID pFileBuffer = NULL; //pFileBuffer= ReadPEFile(lpszFile); if(!pFileBuffer) { printf("文件读取失败\n"); return 0; } 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; PIMAGE_DATA_DIRECTORY DataDirectory=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); //定位Directory_Data; DataDirectory = pOptionHeader->DataDirectory; //导出表 printf("IMAGE_DIRECTORY_ENTRY_EXPORT: Address: %x ,Size: %x \n",DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].VirtualAddress, DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].Size); //DWORD RVAToFileOffset(LPVOID pFileBuffer,DWORD dwRva) DWORD FoA = RVAToFileOffset(pFileBuffer,0x2df10); //printf("%x \n",FoA); DWORD Export_Directory_Address = DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].VirtualAddress; DWORD Export_Directory_Size = DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].Size; FoA = RVAToFileOffset(pFileBuffer,Export_Directory_Address); //定位导出表的位置 PIMAGE_EXPORT_DIRECTORY pExDirectory = NULL; pExDirectory = (PIMAGE_EXPORT_DIRECTORY)((DWORD)pFileBuffer + FoA); printf("------------------------\n"); //输出每个函数地址表信息 WORD k =0; //函数名称表 DWORD ExAddressOfNames = pExDirectory->AddressOfNames; DWORD ExAddressOfNamesFoA = RVAToFileOffset(pFileBuffer,ExAddressOfNames); DWORD ExNumberOfNames = pExDirectory->NumberOfNames; PDWORD pExAddressOfNames = NULL; pExAddressOfNames = (PDWORD)((DWORD)pFileBuffer + ExAddressOfNamesFoA); for(k=0;k<ExNumberOfNames;k++) { //printf("%d : %x \n",k,*pExAddressOfNames); //函数名的地址转换为FoA ,输出函数名 PDWORD NameAddress = (PDWORD)RVAToFileOffset(pFileBuffer,*pExAddressOfNames); //输出函数名 //printf("%s \n",(char*)((DWORD)pFileBuffer + (DWORD)NameAddress)); char* s_name = (char*)((DWORD)pFileBuffer + (DWORD)NameAddress); WORD num = strcmp(FunctionName,s_name); if(num==0) { break; } pExAddressOfNames++; } //函数的位置k WORD Location_Fun = k; printf("Function: %s\n",FunctionName); printf("Location_Fun: %d \n",Location_Fun); //return 0; //函数序号表 DWORD ExAddressOfNameOrdinals = pExDirectory->AddressOfNameOrdinals; DWORD ExAddressOfNameOrdinalsFoA = RVAToFileOffset(pFileBuffer,ExAddressOfNameOrdinals); ExNumberOfNames = pExDirectory->NumberOfNames; PWORD pExAddressOfNameOrdinals = NULL; pExAddressOfNameOrdinals = (PWORD)((DWORD)pFileBuffer + ExAddressOfNameOrdinalsFoA); //函数表的序号 WORD NUM_FUN = pExAddressOfNameOrdinals[Location_Fun]; printf("NUM_FUN: %d \n",NUM_FUN); //return 0; //输出函数地址表信息 //AddressOfFunctions DWORD ExAddressOfFunctions = pExDirectory->AddressOfFunctions; DWORD ExAddressOfFunctionsFoA = RVAToFileOffset(pFileBuffer,ExAddressOfFunctions); DWORD ExNumberOfFunctions = pExDirectory->NumberOfFunctions; PDWORD pExAddressOfFunctions = NULL; pExAddressOfFunctions = (PDWORD)((DWORD)pFileBuffer + ExAddressOfFunctionsFoA); //确定函数的地址 DWORD Fun_Addr = pExAddressOfFunctions[NUM_FUN]; return Fun_Addr; } DWORD GetFunctionAddrByOrdinals(LPVOID pFileBuffer,WORD FunctionOrdinals) { if(!pFileBuffer) { printf("文件读取失败\n"); return 0; } 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; PIMAGE_DATA_DIRECTORY DataDirectory=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); //定位Directory_Data; DataDirectory = pOptionHeader->DataDirectory; //导出表 printf("IMAGE_DIRECTORY_ENTRY_EXPORT: Address: %x ,Size: %x \n",DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].VirtualAddress, DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].Size); //DWORD RVAToFileOffset(LPVOID pFileBuffer,DWORD dwRva) DWORD FoA = RVAToFileOffset(pFileBuffer,0x2df10); //printf("%x \n",FoA); DWORD Export_Directory_Address = DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].VirtualAddress; DWORD Export_Directory_Size = DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].Size; FoA = RVAToFileOffset(pFileBuffer,Export_Directory_Address); //定位导出表的位置 PIMAGE_EXPORT_DIRECTORY pExDirectory = NULL; pExDirectory = (PIMAGE_EXPORT_DIRECTORY)((DWORD)pFileBuffer + FoA); //直接定位函数的位置 DWORD Function_Index = FunctionOrdinals-pExDirectory->Base; //输出函数地址表信息 //AddressOfFunctions DWORD ExAddressOfFunctions = pExDirectory->AddressOfFunctions; DWORD ExAddressOfFunctionsFoA = RVAToFileOffset(pFileBuffer,ExAddressOfFunctions); DWORD ExNumberOfFunctions = pExDirectory->NumberOfFunctions; PDWORD pExAddressOfFunctions = NULL; pExAddressOfFunctions = (PDWORD)((DWORD)pFileBuffer + ExAddressOfFunctionsFoA); //确定函数的地址 DWORD Fun_Addr = pExAddressOfFunctions[Function_Index]; return Fun_Addr; //return 0; } void printDirectoryRelocTable(LPSTR lpszFile) { LPVOID pFileBuffer = NULL; pFileBuffer= ReadPEFile(lpszFile); if(!pFileBuffer) { printf("文件读取失败\n"); return; } 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; PIMAGE_DATA_DIRECTORY DataDirectory=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); //定位Directory_Data; DataDirectory = pOptionHeader->DataDirectory; //重定位表 printf("IMAGE_DIRECTORY_ENTRY_BASERELOC: Address: %x ,Size: %x \n",DataDirectory[IMAGE_DIRECTORY_ENTRY_BASERELOC].VirtualAddress, DataDirectory[IMAGE_DIRECTORY_ENTRY_BASERELOC].Size); //DWORD RVAToFileOffset(LPVOID pFileBuffer,DWORD dwRva) DWORD FoA = RVAToFileOffset(pFileBuffer,0x2df10); DWORD BaseReloc_Directory_Address = DataDirectory[IMAGE_DIRECTORY_ENTRY_BASERELOC].VirtualAddress; DWORD BaseReloc_Directory_Size = DataDirectory[IMAGE_DIRECTORY_ENTRY_BASERELOC].Size; FoA = RVAToFileOffset(pFileBuffer,BaseReloc_Directory_Address); //定位到第一个重定位块 PIMAGE_BASE_RELOCATION pRelocData = (PIMAGE_BASE_RELOCATION)((DWORD)pFileBuffer + FoA); //输出所有的标信息 while(pRelocData->VirtualAddress||pRelocData->SizeOfBlock) { DWORD RelocVirtualAddress = pRelocData->VirtualAddress; DWORD RelocSize = pRelocData->SizeOfBlock; printf("VirtualSize: %x ,Size: %x , Number: %x \n",RelocVirtualAddress,RelocSize,(RelocSize-8)/2); int k = (RelocSize-8)/2; PWORD pMyRelocAddress = NULL; pMyRelocAddress = (PWORD)((DWORD)pRelocData+8); for(int i=0;i<k;i++) { printf("第%x个 : 标志 : %x 偏移 : %x\n",i+1,pMyRelocAddress[i]&0xF000,RelocVirtualAddress+(pMyRelocAddress[i]&0x0FFF)); } pRelocData = (PIMAGE_BASE_RELOCATION)((DWORD)pRelocData + RelocSize); } } void TestMoveExportDirectory(LPSTR lpszFile) { /* 1 在DLL中新增一个节, 并返回新增的FOA 2 复制AddressOfFunctions 长度:4*NumberOfFunctions 3 复制AddressOfNameOrdinals 长度:NumberOfNames*2 4 复制AddressOfNames 长度:NumberOfNames*4 5 复制所有的函数名 长度不确定,复制时直接修复AddressOfNames 6 复制IMAGE_EXPORT_DIRECTORY结构 7 修复IMAGE_EXPORT_DIRECTORY结构中的 AddressOfFunctions AddressOfNameOrdinals AddressOfNames 8 修复目录中项的值,指向新的IMAGE_EXPORT_DIRECTORY */ } void TestMoveRelocDirectory(LPSTR lpszFile) { /* 1 新增一个节 2 把重定位的表 移动到那个节中 3 更改标志位 */ LPVOID pFileBuffer = NULL; pFileBuffer= ReadPEFile(lpszFile); if(!pFileBuffer) { printf("文件读取失败\n"); return; } 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; PIMAGE_SECTION_HEADER pSectionHeader_ADD = NULL; PIMAGE_DATA_DIRECTORY DataDirectory=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); pSectionHeader_ADD = pSectionHeader; //1 判断能否添加节 DWORD Header_size = pDosHeader->e_lfanew + 4 + 20 + pPEHeader->SizeOfOptionalHeader + pPEHeader->NumberOfSections*40; if(pOptionHeader->SizeOfHeaders-Header_size<80) { printf("没有可用空间填充节表\n"); free(pFileBuffer); return; } printf("空间:%d\n",pOptionHeader->SizeOfHeaders-Header_size); //添加一个节 //确定参数 PIMAGE_SECTION_HEADER pSectionHeader_LAST = (PIMAGE_SECTION_HEADER)((DWORD)pSectionHeader+(pPEHeader->NumberOfSections-1)*40); pSectionHeader_ADD=(PIMAGE_SECTION_HEADER)((DWORD)pSectionHeader_ADD+(pPEHeader->NumberOfSections)*40); //="NewSec"; strcpy((char*)pSectionHeader_ADD->Name,"NewSec"); pSectionHeader_ADD->Misc.VirtualSize = 0x2000; pSectionHeader_ADD->VirtualAddress = pOptionHeader->SizeOfImage; pSectionHeader_ADD->SizeOfRawData = 0x2000; pSectionHeader_ADD->PointerToRawData = pSectionHeader_LAST->PointerToRawData+pSectionHeader_LAST->SizeOfRawData; pSectionHeader_ADD->Characteristics = pSectionHeader->Characteristics; //填充0 LPVOID pSectionEND = (LPVOID)((DWORD)pSectionHeader_ADD+40); memset(pSectionEND,0,IMAGE_SIZEOF_SECTION_HEADER); //修改PE头信息 pPEHeader->NumberOfSections = pPEHeader->NumberOfSections +1; pOptionHeader->SizeOfImage = pOptionHeader->SizeOfImage+0x2000; //写入到文件 FILE *pOutFile = NULL; //打开文件 pOutFile = fopen("C://addSec.dll","a+b"); if(!pOutFile) { printf("无法打开文件EXE文件"); return; } //写出第一部分 printf("length: %x \n ",pSectionHeader_ADD->PointerToRawData+pSectionHeader_ADD->SizeOfRawData); size_t writeSize = fwrite(pFileBuffer,pSectionHeader_ADD->PointerToRawData,1,pOutFile); printf("WirteSize:%d\n",writeSize); //写出第二部分 LPVOID pNewBuffer=(LPVOID)malloc(0x2000); if(pNewBuffer==NULL) { printf("pNewBuffer分配空间失败\n"); return; } memset(pNewBuffer,0,0x2000); writeSize = fwrite(pNewBuffer,0x2000,1,pOutFile); //关闭文件 fclose(pOutFile); free(pFileBuffer); free(pNewBuffer); //读入添加好节的文件 pFileBuffer= ReadPEFile("C://addSec.dll"); //将重定位表的信息,放到最后一个节中 //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); //最后一个节 pSectionHeader_ADD=(PIMAGE_SECTION_HEADER)((DWORD)pSectionHeader+(pPEHeader->NumberOfSections-1)*40); //定位Directory_Data; DataDirectory = pOptionHeader->DataDirectory; //重定位表 printf("IMAGE_DIRECTORY_ENTRY_BASERELOC: Address: %x ,Size: %x \n",DataDirectory[IMAGE_DIRECTORY_ENTRY_BASERELOC].VirtualAddress, DataDirectory[IMAGE_DIRECTORY_ENTRY_BASERELOC].Size); //DWORD RVAToFileOffset(LPVOID pFileBuffer,DWORD dwRva) DWORD FoA = RVAToFileOffset(pFileBuffer,0x2df10); DWORD BaseReloc_Directory_Address = DataDirectory[IMAGE_DIRECTORY_ENTRY_BASERELOC].VirtualAddress; DWORD BaseReloc_Directory_Size = DataDirectory[IMAGE_DIRECTORY_ENTRY_BASERELOC].Size; FoA = RVAToFileOffset(pFileBuffer,BaseReloc_Directory_Address); //定位到第一个重定位块 PIMAGE_BASE_RELOCATION pRelocData = (PIMAGE_BASE_RELOCATION)((DWORD)pFileBuffer + FoA); PIMAGE_BASE_RELOCATION pRelocData_Start = (PIMAGE_BASE_RELOCATION)((DWORD)pFileBuffer + FoA); DWORD sizeOfRelocDirectory = 0; //计算重定位表的大小 while(pRelocData->VirtualAddress||pRelocData->SizeOfBlock) { DWORD RelocVirtualAddress = pRelocData->VirtualAddress; DWORD RelocSize = pRelocData->SizeOfBlock; sizeOfRelocDirectory = sizeOfRelocDirectory + RelocSize; pRelocData = (PIMAGE_BASE_RELOCATION)((DWORD)pRelocData + RelocSize); } //起始位置pRelocData //移动 PDWORD myRelocLoc = (PDWORD)pSectionHeader_ADD->PointerToRawData; printf("Reloc: %x , Size: %x \n",pRelocData,sizeOfRelocDirectory); //memcpy(myRelocLoc,pRelocData,sizeOfRelocDirectory); LPVOID destStart = (LPVOID)((DWORD)pFileBuffer + (DWORD)myRelocLoc); printf("pFileBuffer:%x, myRelocLoc: %x \n",pFileBuffer,destStart); LPVOID srcStart = (LPVOID)(pRelocData_Start); memcpy(destStart,srcStart,sizeOfRelocDirectory); //修改重定位表的参数 DataDirectory[IMAGE_DIRECTORY_ENTRY_BASERELOC].VirtualAddress = FileOffsetToRVA(pFileBuffer,pSectionHeader_ADD->PointerToRawData); //写出到dll中 DWORD FileSize = pSectionHeader_ADD->PointerToRawData + pSectionHeader_ADD->SizeOfRawData; WirteToFile(pFileBuffer,FileSize,"C://addNewSec.dll"); } void testUseReloc(LPSTR lpszFile) { LPVOID pFileBuffer = NULL; pFileBuffer= ReadPEFile(lpszFile); if(!pFileBuffer) { printf("文件读取失败\n"); return; } 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; PIMAGE_DATA_DIRECTORY DataDirectory=NULL; PIMAGE_SECTION_HEADER pSectionHeader_LAST = 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); pSectionHeader_LAST = (PIMAGE_SECTION_HEADER)((DWORD)pSectionHeader+(pPEHeader->NumberOfSections-1)*40); //定位Directory_Data; DataDirectory = pOptionHeader->DataDirectory; //重定位表 printf("IMAGE_DIRECTORY_ENTRY_BASERELOC: Address: %x ,Size: %x \n",DataDirectory[IMAGE_DIRECTORY_ENTRY_BASERELOC].VirtualAddress, DataDirectory[IMAGE_DIRECTORY_ENTRY_BASERELOC].Size); //DWORD RVAToFileOffset(LPVOID pFileBuffer,DWORD dwRva) DWORD FoA = RVAToFileOffset(pFileBuffer,0x2df10); DWORD BaseReloc_Directory_Address = DataDirectory[IMAGE_DIRECTORY_ENTRY_BASERELOC].VirtualAddress; DWORD BaseReloc_Directory_Size = DataDirectory[IMAGE_DIRECTORY_ENTRY_BASERELOC].Size; FoA = RVAToFileOffset(pFileBuffer,BaseReloc_Directory_Address); //定位到第一个重定位块 PIMAGE_BASE_RELOCATION pRelocData = (PIMAGE_BASE_RELOCATION)((DWORD)pFileBuffer + FoA); //输出所有的标信息 while(pRelocData->VirtualAddress||pRelocData->SizeOfBlock) { DWORD RelocVirtualAddress = pRelocData->VirtualAddress; DWORD RelocSize = pRelocData->SizeOfBlock; printf("VirtualSize: %x ,Size: %x , Number: %x \n",RelocVirtualAddress,RelocSize,(RelocSize-8)/2); int k = (RelocSize-8)/2; PWORD pMyRelocAddress = NULL; pMyRelocAddress = (PWORD)((DWORD)pRelocData+8); for(int i=0;i<k;i++) { printf("第%x个 : 标志 : %x 偏移 : %x\n",i+1,pMyRelocAddress[i]&0xF000,RelocVirtualAddress+(pMyRelocAddress[i]&0x0FFF)); //依次进行修改 DWORD changeRVA = RelocVirtualAddress+(pMyRelocAddress[i]&0x0FFF); DWORD changeFoa = RVAToFileOffset(pFileBuffer,changeRVA); printf("changeRVA:%x changeFoa: %x \n",changeRVA,changeFoa); if((pMyRelocAddress[i]&0xF000) == 0x3000) { //修改数据: PDWORD myAddress = (PDWORD)((DWORD)pFileBuffer + changeFoa); printf("myAddress: %x\n",*myAddress); *myAddress = *myAddress - 0x10000000 + 0x20000000; printf("change :myAddress: %x\n",*myAddress); } } pRelocData = (PIMAGE_BASE_RELOCATION)((DWORD)pRelocData + RelocSize); } //写出dll //确定大小 LPVOID pFileBuffer_Start = pFileBuffer; DWORD FileSize = pSectionHeader_LAST->PointerToRawData + pSectionHeader_LAST->SizeOfRawData; WirteToFile(pFileBuffer,FileSize,"C://changeDll.dll"); } void TestPrintImportDirectory(LPSTR lpszFile) { LPVOID pFileBuffer = NULL; pFileBuffer= ReadPEFile(lpszFile); if(!pFileBuffer) { printf("文件读取失败\n"); return; } 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; PIMAGE_SECTION_HEADER pSectionHeader_ADD = NULL; PIMAGE_DATA_DIRECTORY pDataDirectory = 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); pDataDirectory = pOptionHeader->DataDirectory; //IMAGE_DIRECTORY_ENTRY_IMPORT /* #define IMAGE_DIRECTORY_ENTRY_EXPORT 0 // Export Directory #define IMAGE_DIRECTORY_ENTRY_IMPORT 1 // Import Directory */ //确定导入表 //pImportDirectory = NULL; IMAGE_DATA_DIRECTORY pImportDirectory = pDataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT]; DWORD ImportVirtualAddress = pImportDirectory.VirtualAddress; DWORD ImportFoa = RVAToFileOffset(pFileBuffer,ImportVirtualAddress); printf("ImportVirtualAddress: %x \n",ImportVirtualAddress); printf("Size: %x \n",pImportDirectory.Size); printf("ImportFoa: %x \n",ImportFoa); //输出所有的导入表 //PIMAGE_THUNK_DATA32 pThunkData = NULL; //第一个导入表 PIMAGE_IMPORT_DESCRIPTOR pImportDes = NULL; pImportDes = (PIMAGE_IMPORT_DESCRIPTOR)((DWORD)pFileBuffer + ImportFoa); while(pImportDes->OriginalFirstThunk != 0x0 && pImportDes->FirstThunk != 0x0 ) { //输出所有的dll printf("OriginalFirstThunk: %x\n",pImportDes->OriginalFirstThunk); DWORD pNameAddress = RVAToFileOffset(pFileBuffer,pImportDes->Name); PSTR pDllName = (PSTR)((DWORD)pFileBuffer + pNameAddress); printf("name: %s \n",pDllName); printf("------------------------------------------\n"); //输出OriginalFirstThunk的信息 DWORD Thunk_Address = RVAToFileOffset(pFileBuffer,pImportDes->OriginalFirstThunk); PIMAGE_THUNK_DATA32 pThunkData = (PIMAGE_THUNK_DATA32)((DWORD)pFileBuffer + Thunk_Address); //根据pThunkData 的最高为来判断 DWORD ImportOrdinal = pThunkData->u1.Ordinal; while(ImportOrdinal) { //输出所有所有的信息 //#define IMAGE_ORDINAL_FLAG32 0x80000000 if(ImportOrdinal & IMAGE_ORDINAL_FLAG32) { printf("按序号导入:%x\n",ImportOrdinal&0x0FFF); }else { DWORD ImageNameAddress = RVAToFileOffset(pFileBuffer,ImportOrdinal); PIMAGE_IMPORT_BY_NAME pImageName = (PIMAGE_IMPORT_BY_NAME)(DWORD(pFileBuffer)+ImageNameAddress); printf("按名字导入:%x - %s \n",pImageName->Hint,pImageName->Name); } //向下移动 pThunkData = (PIMAGE_THUNK_DATA32)((DWORD)pThunkData + 4); ImportOrdinal = pThunkData->u1.Ordinal; } printf("------------------------------------------\n"); //printf("FirstThunk:%x \n",pImportDes->FirstThunk); DWORD pFirstThunk = (DWORD)pImportDes->FirstThunk; printf("FirstThunk:%x \n",pImportDes->FirstThunk); printf("------------------------------------------\n"); DWORD FirstThunk_Address = RVAToFileOffset(pFileBuffer,pFirstThunk); PIMAGE_THUNK_DATA32 pNewThunkData = (PIMAGE_THUNK_DATA32)((DWORD)pFileBuffer + FirstThunk_Address); DWORD newImportOrdinal = pNewThunkData->u1.Ordinal; while(newImportOrdinal) { //输出所有所有的信息 //#define IMAGE_ORDINAL_FLAG32 0x80000000 if(newImportOrdinal & IMAGE_ORDINAL_FLAG32) { printf("按序号导入:%x\n",newImportOrdinal&0x0FFF); }else { DWORD newImageNameAddress = RVAToFileOffset(pFileBuffer,newImportOrdinal); PIMAGE_IMPORT_BY_NAME pNewImageName = (PIMAGE_IMPORT_BY_NAME)(DWORD(pFileBuffer)+newImageNameAddress); printf("按名字导入:%x - %s \n",pNewImageName->Hint,pNewImageName->Name); } //向下移动 pNewThunkData = (PIMAGE_THUNK_DATA32)((DWORD)pNewThunkData + 4); newImportOrdinal = pNewThunkData->u1.Ordinal; } printf("------------------------------------------\n"); pImportDes = (PIMAGE_IMPORT_DESCRIPTOR)((DWORD)pImportDes + 20); //getchar(); } } void TestPrintBindImportDirectory(LPSTR lpszFile) { LPVOID pFileBuffer = NULL; pFileBuffer= ReadPEFile(lpszFile); if(!pFileBuffer) { printf("文件读取失败\n"); return; } 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; PIMAGE_SECTION_HEADER pSectionHeader_ADD = NULL; PIMAGE_DATA_DIRECTORY pDataDirectory = 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); pDataDirectory = pOptionHeader->DataDirectory; //IMAGE_DIRECTORY_ENTRY_IMPORT /* #define IMAGE_DIRECTORY_ENTRY_LOAD_CONFIG 10 // Load Configuration Directory #define IMAGE_DIRECTORY_ENTRY_BOUND_IMPORT 11 // Bound Import Directory in headers */ //确定导入表 //pImportDirectory = NULL; IMAGE_DATA_DIRECTORY pBindImportDirectory = pDataDirectory[IMAGE_DIRECTORY_ENTRY_BOUND_IMPORT]; DWORD BindImportVirtualAddress = pBindImportDirectory.VirtualAddress; DWORD BindImportFoa = BindImportVirtualAddress; /* printf("BindImportVirtualAddress: %x \n",BindImportVirtualAddress); printf("Size: %x \n",pBindImportDirectory.Size); printf("BindImportFoa: %x \n",BindImportFoa); */ PIMAGE_BOUND_IMPORT_DESCRIPTOR pBindImport = (PIMAGE_BOUND_IMPORT_DESCRIPTOR)((DWORD)pFileBuffer + BindImportFoa); while(pBindImport->TimeDateStamp !=0x0) { //输出第一个绑定 DWORD bindTime = pBindImport->TimeDateStamp; WORD ModuleName = pBindImport->OffsetModuleName; WORD numberModule = pBindImport->NumberOfModuleForwarderRefs; //输出名字 PSTR pModuleName = (PSTR)((DWORD)pFileBuffer+(DWORD)BindImportVirtualAddress+ModuleName); printf("ModuleName:%s \n",pModuleName); printf("--numberModule:%x \n",numberModule); for(int i=0;i<numberModule;i++) { PIMAGE_BOUND_FORWARDER_REF pBoundRef = (PIMAGE_BOUND_FORWARDER_REF)((DWORD)pBindImport+i*8); pBindImport = (PIMAGE_BOUND_IMPORT_DESCRIPTOR)((DWORD)pBindImport+i*8); //输出名字 DWORD refTime = pBoundRef->TimeDateStamp; WORD refName = pBoundRef->OffsetModuleName; PSTR pRefName = (PSTR)((DWORD)pFileBuffer+(DWORD)BindImportVirtualAddress+refName); printf(" RefName:%s \n",pRefName); } pBindImport = (PIMAGE_BOUND_IMPORT_DESCRIPTOR)((DWORD)pBindImport+8); } } void TestPrintResourceICO(LPSTR lpszFile) { LPVOID pFileBuffer = NULL; pFileBuffer= ReadPEFile(lpszFile); if(!pFileBuffer) { printf("文件读取失败\n"); return; } 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; PIMAGE_SECTION_HEADER pSectionHeader_ADD = NULL; PIMAGE_DATA_DIRECTORY pDataDirectory = 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); pDataDirectory = pOptionHeader->DataDirectory; //IMAGE_DATA_DIRECTORY pBindImportDirectory = pDataDirectory[IMAGE_DIRECTORY_ENTRY_BOUND_IMPORT]; IMAGE_DATA_DIRECTORY ResourceDirectory = pDataDirectory[IMAGE_DIRECTORY_ENTRY_RESOURCE]; DWORD ResourceVirtualAddress = ResourceDirectory.VirtualAddress; DWORD ResourceSize = ResourceDirectory.Size; printf("ResourceVirtualAddress : %x \n",ResourceVirtualAddress); printf("ResourceSize: %x \n",ResourceSize); /* typedef struct _IMAGE_RESOURCE_DIRECTORY { DWORD Characteristics; DWORD TimeDateStamp; WORD MajorVersion; WORD MinorVersion; WORD NumberOfNamedEntries; WORD NumberOfIdEntries; // IMAGE_RESOURCE_DIRECTORY_ENTRY DirectoryEntries[]; } IMAGE_RESOURCE_DIRECTORY, *PIMAGE_RESOURCE_DIRECTORY; //第一个导入表 PIMAGE_IMPORT_DESCRIPTOR pImportDes = NULL; pImportDes = (PIMAGE_IMPORT_DESCRIPTOR)((DWORD)pFileBuffer + ImportFoa); */ DWORD dwFoa = RVAToFileOffset(pFileBuffer,ResourceVirtualAddress); PIMAGE_RESOURCE_DIRECTORY pResource = (PIMAGE_RESOURCE_DIRECTORY)((DWORD)pFileBuffer + dwFoa); //输出PIMAGE_RESOURCE_DIRECTORY 的信息 printf("NumberOfNamedEntries: %x \n",pResource->NumberOfNamedEntries); printf("NumberOfIdEntries: %x \n",pResource->NumberOfIdEntries); //第一层类型的解析 //第一个资源表 PIMAGE_RESOURCE_DIRECTORY_ENTRY pResdirectoryEntry = (PIMAGE_RESOURCE_DIRECTORY_ENTRY)((DWORD)pResource + sizeof(IMAGE_RESOURCE_DIRECTORY)); DWORD NumberOfResType = pResource->NumberOfNamedEntries + pResource->NumberOfIdEntries; //找到图标资源 PIMAGE_RESOURCE_DIRECTORY pResICODir=NULL; for(DWORD i=0;i<NumberOfResType;i++) { //解析内容: DWORD NameIsString = pResdirectoryEntry->NameIsString; DWORD ResName = pResdirectoryEntry->Name; DWORD OffsetToData = pResdirectoryEntry->OffsetToData; DWORD DataIsDirectory = pResdirectoryEntry->DataIsDirectory; //printf("Info: %d -NameIsString: %d - Name: %x -- OffToDa: %x - IsD - %d \n",i+1, //NameIsString,ResName,OffsetToData,DataIsDirectory); if(ResName == 0x3) { //PIMAGE_RESOURCE_DIRECTORY pResource = (PIMAGE_RESOURCE_DIRECTORY)((DWORD)pFileBuffer + dwFoa); pResICODir = (PIMAGE_RESOURCE_DIRECTORY)((DWORD)pResource +pResdirectoryEntry->OffsetToDirectory); break; } pResdirectoryEntry = (PIMAGE_RESOURCE_DIRECTORY_ENTRY)((DWORD)pResdirectoryEntry + 8); } //IMAGE_RESOURCE_DIR_STRING_U; /* NameIsString = 1 的时候指向的结构 typedef struct _IMAGE_RESOURCE_DIR_STRING_U { WORD Length; WCHAR NameString[ 1 ]; } IMAGE_RESOURCE_DIR_STRING_U, *PIMAGE_RESOURCE_DIR_STRING_U; */ //确定图标的地址,找第二层 DWORD NumberOffICO = pResICODir->NumberOfIdEntries + pResICODir->NumberOfNamedEntries; printf("NumberOffICO : %d \n",NumberOffICO); /* typedef struct _IMAGE_RESOURCE_DIRECTORY_ENTRY { union { struct { DWORD NameOffset:31; DWORD NameIsString:1; }; DWORD Name; WORD Id; }; union { DWORD OffsetToData; struct { DWORD OffsetToDirectory:31; DWORD DataIsDirectory:1; }; }; } IMAGE_RESOURCE_DIRECTORY_ENTRY, *PIMAGE_RESOURCE_DIRECTORY_ENTRY; */ //第一个图标描述 PIMAGE_RESOURCE_DIRECTORY_ENTRY pICOEntry = (PIMAGE_RESOURCE_DIRECTORY_ENTRY)((DWORD)pResICODir + sizeof(IMAGE_RESOURCE_DIRECTORY)); PIMAGE_RESOURCE_DIRECTORY pICOContent = NULL; for(DWORD j = 0;j<NumberOffICO;j++) { //解析内容: DWORD NameIsString = pICOEntry->NameIsString; DWORD ResName = pICOEntry->Name; DWORD OffsetToData = pICOEntry->OffsetToData; DWORD DataIsDirectory = pICOEntry->DataIsDirectory; printf("Info: %d -NameIsString: %d - Name: %x -- OffToDa: %x - IsD - %d \n",i+1, NameIsString,ResName,OffsetToData,DataIsDirectory); //依次解析页码表 pICOContent = (PIMAGE_RESOURCE_DIRECTORY)((DWORD)pResource +pICOEntry->OffsetToDirectory); //页码表解析 DWORD NumberOfICOContent = pICOContent->NumberOfIdEntries + pICOContent->NumberOfNamedEntries; printf("NumberOfICOContent: %d \n",NumberOfICOContent); //图标测试只有一个,不循环测试 //找到关键点: PIMAGE_RESOURCE_DIRECTORY_ENTRY pICOGetVS = (PIMAGE_RESOURCE_DIRECTORY_ENTRY)((DWORD)pICOContent + sizeof(IMAGE_RESOURCE_DIRECTORY)); //找到图标资源的VistrualAddress 和 Size PIMAGE_DATA_DIRECTORY pDataIco = (PIMAGE_DATA_DIRECTORY)((DWORD)pResource + pICOGetVS->OffsetToDirectory); //输出每个图标信息 printf("VirtualAddress: %x, Size: %x \n",pDataIco->VirtualAddress,pDataIco->Size); pICOEntry = (PIMAGE_RESOURCE_DIRECTORY_ENTRY)((DWORD)pICOEntry + 8); } }