两个函数的具体实现
直接上代码了, 懒得讲了
// 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; } 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); //直接定位函数的位置 WORD 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; }
0则评论给“GetFunctionAddrByName与GetFunctionAddrByOrdinals的实现”