<原创>在PE最后一节中插入补丁程序(附代码)

完整文件  https://files.cnblogs.com/Files/Gotogoo/在PE最后一节中插入补丁程序.zip

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

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

  1 #include "stdafx.h"
  2 #include<Windows.h>
  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越过E9
105     memcpy((PVOID)((UCHAR*)lpNewFileBaseAddress + NewFileSize - 5),JmpCode,strlen((char*)JmpCode));    //看内存  E9后有5个非0字节,所以不是-4
106     
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     else
137     {
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<NTHead->FileHeader.NumberOfSections;i++)
159     {
160         if(dwEntryPoint>=SectionHead[i].VirtualAddress && dwEntryPoint<SectionHead[i].VirtualAddress+SectionHead[i].SizeOfRawData)
161         {
162 
163             if(Type == RealSectionSize)
164             {
165                 dwRet = SectionHead[i].Misc.VirtualSize;
166             }
167             if(Type == SectionRVA)
168             {
169                 dwRet = SectionHead[i].PointerToRawData;
170             }                    
171                         
172         }    
173         
174     }
175 
176     if(dwRet == NULL)
177     {
178         printf("GetFileInfo Failed!\r\n");
179     }
180 
181     return dwRet;
182 
183 }
184 
185 PVOID GetFileBaseAddressAndSize(char* szFilePath,PULONG ulFileSize )
186 {
187     HANDLE hFile = CreateFileA(szFilePath,
188         GENERIC_READ|GENERIC_WRITE,FILE_SHARE_WRITE|FILE_SHARE_WRITE,NULL,
189         OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL,NULL);
190 
191     if (hFile==INVALID_HANDLE_VALUE)
192     {
193         printf("CreateFile Failed!\r\n");
194         return NULL;
195     }
196     *ulFileSize  = GetFileSize(hFile,NULL);
197 
198     if (!(*ulFileSize))
199     {
200         printf("GetFileSize Failed!\r\n");
201         CloseHandle(hFile);
202         return NULL;
203     }
204     HANDLE hMapFile = CreateFileMapping(
205         hFile,
206         NULL,
207         PAGE_READWRITE, 
208         0,
209         0,              
210         NULL);
211 
212     if (hMapFile == INVALID_HANDLE_VALUE)
213     {
214         printf("CreateFileMapping Failed!\r\n");
215         CloseHandle(hFile);
216         return NULL;
217     }
218 
219     PVOID FileBaseAddress = MapViewOfFile(hMapFile,FILE_MAP_ALL_ACCESS,NULL,NULL,NULL);
220     if (FileBaseAddress == NULL)
221     {
222         CloseHandle(hFile);
223         CloseHandle(hMapFile);
224         printf("MapViewOfFile Failed!\r\n");
225         return NULL;
226     }
227 
228     return FileBaseAddress;
229 }

 

posted @ 2016-03-16 10:18  Gotogoo  阅读(837)  评论(0编辑  收藏  举报