zoukankan      html  css  js  c++  java
  • <原创>在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!
    ");
     74         return FALSE;
     75     }
     76     DWORD dwRet = 0;
     77     if(WriteFile(hNewFile,NewFileBaseAddress,ulTargetSize+dwFileAlignPatchCodeSize,&dwRet,NULL) == 0)                  
     78     {
     79         printf("WriteFile Failed!
    ");
     80         return FALSE;
     81     }
     82     else
     83     {
     84         printf("Succeed!
    ");
     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[] = "x00x00x00x00";    
    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!
    ");
    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!
    ");
    194         return NULL;
    195     }
    196     *ulFileSize  = GetFileSize(hFile,NULL);
    197 
    198     if (!(*ulFileSize))
    199     {
    200         printf("GetFileSize Failed!
    ");
    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!
    ");
    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!
    ");
    225         return NULL;
    226     }
    227 
    228     return FileBaseAddress;
    229 }
  • 相关阅读:
    ES分页
    在github上使用workflow构建docker镜像并推送阿里云
    xxl-job滥用netty导致的问题和解决方案
    使用netty实现socks5协议
    docker日志设置
    关于我
    友情链接
    分布式任务调度系统:xxl-job
    SpringBoot自定义配置以及IDEA配置提示
    frp穿透内网使用vsftpd服务
  • 原文地址:https://www.cnblogs.com/Gotogoo/p/5266198.html
Copyright © 2011-2022 走看看