博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
<原创>在PE最后一节中插入补丁程序(附代码)
阅读量:6977 次
发布时间:2019-06-27

本文共 7279 字,大约阅读时间需要 24 分钟。

完整文件  

在PE文件最后一节中插入补丁程序,是最简单也是最有效的一种,因为PE最后一节的数据在文件的末尾,将代码加到最后一节时,不需要修改太多的内容。

最近在学习python,没时间详细写这个了,有问题看代码,或者在评论区提问,或者看书《Windows PE权威指南》,讲的很详细。

1 #include "stdafx.h"  2 #include
3 4 char szTargetPath[MAX_PATH] = "D:\\Target.exe"; //目标文件的路径 5 char szPatchPath[MAX_PATH] = "D:\\helloworld_1.exe"; //补丁文件的路径 6 char szModifyPEPath[MAX_PATH]= "D:\\Modified_PE.exe"; //修改后生成新文件的路径 7 enum PATCH_FILE_INFO 8 { 9 FileAlignSectionSize, 10 RealSectionSize, 11 SectionRVA, 12 AddressOfEntryPoint, 13 FileAlignment 14 }; 15 16 PVOID GetFileBaseAddressAndSize(char* szFilePath,PULONG ulFileSize ); 17 BOOL InsertPatchFileToTargetFile(PVOID lpTargetMemory,PVOID lpPatchMemory,ULONG ulTargetSize); 18 DWORD GetFileInfo(PVOID FileBaseAddress,PATCH_FILE_INFO Type); 19 VOID ModifyParameter(PVOID FileBaseAddress,ULONG ulTargetSize,ULONG ulFlieAlignPatchCodeSize,ULONG ulRealPatchCodeSize,ULONG ulNewOEP); 20 ULONG GetPathCodeSectionRVA(PVOID lpPatchMemory); 21 ULONG Align(ULONG FileSize,ULONG ulAlignment); 22 ULONG FileAlign(ULONG FileSize,ULONG ulFileAlignment); 23 ULONG GetNewFileOEP(PVOID lpTargetMemory); 24 VOID ModifyPatchCodeJumpAddress(PVOID lpNewFileBaseAddress,ULONG NewFileSize,ULONG ULNewFileOEP,ULONG ulOldOEP,ULONG ulRealPatchCodeSize); 25 26 int _tmain(int argc, _TCHAR* argv[]) 27 { 28 PVOID lpPatchMemory = NULL; 29 PVOID lpTargetMemory = NULL; 30 ULONG ulPatchSize = 0; 31 ULONG ulTargetSize = 0; 32 33 lpTargetMemory = GetFileBaseAddressAndSize(szTargetPath,&ulTargetSize); 34 lpPatchMemory = GetFileBaseAddressAndSize(szPatchPath,&ulPatchSize); 35 36 InsertPatchFileToTargetFile(lpTargetMemory,lpPatchMemory,ulTargetSize); 37 38 return 0; 39 } 40 41 BOOL InsertPatchFileToTargetFile(PVOID lpTargetMemory,PVOID lpPatchMemory,ULONG ulTargetSize) 42 { 43 DWORD dwFileAlignPatchCodeSize = 0; 44 DWORD dwRealPatchCodeSize = 0; 45 ULONG ulPathCodeSectionRVA = 0; 46 ULONG ULNewFileOEP = 0; 47 ULONG ulOldOEP = 0; 48 ULONG ulFileAlignment = 0; 49 50 51 dwRealPatchCodeSize = GetFileInfo(lpPatchMemory,RealSectionSize); //获得Patch文件未对齐时的大小 52 ulPathCodeSectionRVA = GetFileInfo(lpPatchMemory,SectionRVA); //获得Patch文件所要加载节的RVA 53 ulOldOEP = GetFileInfo(lpTargetMemory,AddressOfEntryPoint); 54 ulFileAlignment = GetFileInfo(lpTargetMemory,FileAlignment); 55 ULNewFileOEP = GetNewFileOEP(lpTargetMemory); 56 dwFileAlignPatchCodeSize = Align(dwRealPatchCodeSize,ulFileAlignment); 57 58 PVOID NewFileBaseAddress = malloc(ulTargetSize+dwFileAlignPatchCodeSize); 59 memset(NewFileBaseAddress,0,ulTargetSize+dwFileAlignPatchCodeSize); 60 61 memcpy(NewFileBaseAddress,lpTargetMemory,ulTargetSize); 62 memcpy((PVOID)((ULONG_PTR)NewFileBaseAddress+ulTargetSize),(PVOID)((ULONG_PTR)lpPatchMemory+ulPathCodeSectionRVA),dwRealPatchCodeSize); 63 64 65 ModifyPatchCodeJumpAddress(NewFileBaseAddress,ulTargetSize+dwRealPatchCodeSize,ULNewFileOEP,ulOldOEP,dwRealPatchCodeSize); //修改PatchCode结尾E9跳转地址 66 67 ModifyParameter(NewFileBaseAddress,ulTargetSize,dwFileAlignPatchCodeSize,dwRealPatchCodeSize,ULNewFileOEP); //修改最后一节和PE头的参数 68 69 70 HANDLE hNewFile = CreateFileA(szModifyPEPath,GENERIC_READ|GENERIC_WRITE,FILE_SHARE_READ|FILE_SHARE_WRITE,NULL,CREATE_ALWAYS,FILE_ATTRIBUTE_ARCHIVE,NULL); 71 if(hNewFile == INVALID_HANDLE_VALUE) 72 { 73 printf("CreateFileA Failed!\r\n"); 74 return FALSE; 75 } 76 DWORD dwRet = 0; 77 if(WriteFile(hNewFile,NewFileBaseAddress,ulTargetSize+dwFileAlignPatchCodeSize,&dwRet,NULL) == 0) 78 { 79 printf("WriteFile Failed!\r\n"); 80 return FALSE; 81 } 82 else 83 { 84 printf("Succeed!\r\n"); 85 } 86 87 return TRUE; 88 89 90 } 91 ULONG GetNewFileOEP(PVOID lpTargetMemory) 92 { 93 PIMAGE_DOS_HEADER DosHead = (PIMAGE_DOS_HEADER)lpTargetMemory; 94 PIMAGE_NT_HEADERS NTHead = (PIMAGE_NT_HEADERS)((ULONG_PTR)DosHead+DosHead->e_lfanew); 95 PIMAGE_SECTION_HEADER SectionHead = (PIMAGE_SECTION_HEADER)((ULONG_PTR)NTHead+sizeof(IMAGE_NT_HEADERS)); 96 97 ULONG ulNumberOfSection = NTHead->FileHeader.NumberOfSections; 98 ULONG ulNewFileOEP = SectionHead[ulNumberOfSection-1].VirtualAddress+SectionHead[ulNumberOfSection-1].SizeOfRawData; 99 return ulNewFileOEP;100 }101 VOID ModifyPatchCodeJumpAddress(PVOID lpNewFileBaseAddress,ULONG NewFileSize,ULONG ULNewFileOEP,ULONG ulOldOEP,ULONG ulRealPatchCodeSize)102 {103 UCHAR JmpCode[] = "\x00\x00\x00\x00"; 104 *(int*)JmpCode = ( ulOldOEP + 1) - ( ULNewFileOEP + ulRealPatchCodeSize ); //+1越过E9105 memcpy((PVOID)((UCHAR*)lpNewFileBaseAddress + NewFileSize - 5),JmpCode,strlen((char*)JmpCode)); //看内存 E9后有5个非0字节,所以不是-4106 107 }108 109 VOID ModifyParameter(PVOID FileBaseAddress,ULONG ulTargetSize,ULONG ulFlieAlignPatchCodeSize,ULONG ulRealPatchCodeSize,ULONG ulNewOEP)110 {111 PIMAGE_DOS_HEADER DosHead = (PIMAGE_DOS_HEADER)FileBaseAddress;112 PIMAGE_NT_HEADERS NTHead = (PIMAGE_NT_HEADERS)((ULONG_PTR)DosHead+DosHead->e_lfanew);113 PIMAGE_SECTION_HEADER SectionHead = (PIMAGE_SECTION_HEADER)((ULONG_PTR)NTHead+sizeof(IMAGE_NT_HEADERS));114 115 ULONG MemoryAlignment = NTHead->OptionalHeader.SectionAlignment; 116 ULONG ulNumberOfSection = NTHead->FileHeader.NumberOfSections;117 118 SectionHead[ulNumberOfSection-1].Characteristics = 0x60000020;119 SectionHead[ulNumberOfSection-1].Misc.VirtualSize = SectionHead[ulNumberOfSection-1].SizeOfRawData + ulRealPatchCodeSize; 120 SectionHead[ulNumberOfSection-1].SizeOfRawData += ulFlieAlignPatchCodeSize;121 122 123 NTHead->OptionalHeader.SizeOfImage = Align(SectionHead[ulNumberOfSection-1].VirtualAddress+SectionHead[ulNumberOfSection-1].SizeOfRawData,MemoryAlignment);124 NTHead->OptionalHeader.AddressOfEntryPoint = ulNewOEP;125 }126 127 128 129 ULONG Align(ULONG FileSize,ULONG ulAlignment)130 {131 if(FileSize%ulAlignment != 0)132 {133 int Temp = FileSize/ulAlignment;134 return ulAlignment*(Temp+1);135 }136 else137 {138 return FileSize;139 }140 }141 DWORD GetFileInfo(PVOID FileBaseAddress,PATCH_FILE_INFO Type)142 {143 PIMAGE_DOS_HEADER DosHead = (PIMAGE_DOS_HEADER)FileBaseAddress;144 PIMAGE_NT_HEADERS NTHead = (PIMAGE_NT_HEADERS)((ULONG_PTR)DosHead+DosHead->e_lfanew);145 PIMAGE_SECTION_HEADER SectionHead = (PIMAGE_SECTION_HEADER)((ULONG_PTR)NTHead+sizeof(IMAGE_NT_HEADERS));146 147 DWORD dwEntryPoint = NTHead->OptionalHeader.AddressOfEntryPoint;148 DWORD dwRet = 0;149 if(Type == AddressOfEntryPoint)150 {151 dwRet = dwEntryPoint;152 }153 if(Type == FileAlignment)154 {155 dwRet = NTHead->OptionalHeader.FileAlignment;156 }157 158 for(int i=0;i
FileHeader.NumberOfSections;i++)159 {160 if(dwEntryPoint>=SectionHead[i].VirtualAddress && dwEntryPoint

 

转载于:https://www.cnblogs.com/Gotogoo/p/5266198.html

你可能感兴趣的文章
Centos 64位使用 yum 会安装两个相同软件包的解决方法
查看>>
Python 多线程抓取网页 牛人 use raw socket implement http request great
查看>>
脚本化 tmux — LinuxTOY
查看>>
《星际争霸2》引擎技术解析
查看>>
PowerDesigner 使用的一些技巧(转)
查看>>
POJ 2955 Brackets (区间DP)
查看>>
Mac中MacPorts安装和使用
查看>>
Appro DM8127 IPNC 挂载NFS遇到的问题及解决
查看>>
Delphi调用java开发的WebService,传入参数出错
查看>>
poj_2479 动态规划
查看>>
unity, monoDevelop ide 代码提示不起作用的解决方法
查看>>
MySQL 5.5.35 单机多实例配置详解
查看>>
iOS使用Security.framework进行RSA 加密解密签名和验证签名
查看>>
Java中正则Matcher类的matches()、lookAt()和find()的区别
查看>>
PHP获取毫秒时间戳,利用microtime()函数
查看>>
【ASP.NET Core】解决“The required antiforgery cookie "xxx" is not present”的错误
查看>>
C++ 纯虚方法
查看>>
.net内存回收与Dispose﹐Close﹐Finalize方法
查看>>
oracle update批量修改sql语句编写
查看>>
Web前端开发人员和设计师必读文章推荐【系列七】
查看>>