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

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

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

 #include "stdafx.h"
#include<Windows.h> char szTargetPath[MAX_PATH] = "D:\\Target.exe"; //目标文件的路径
char szPatchPath[MAX_PATH] = "D:\\helloworld_1.exe"; //补丁文件的路径
char szModifyPEPath[MAX_PATH]= "D:\\Modified_PE.exe"; //修改后生成新文件的路径
enum PATCH_FILE_INFO
{
FileAlignSectionSize,
RealSectionSize,
SectionRVA,
AddressOfEntryPoint,
FileAlignment
}; PVOID GetFileBaseAddressAndSize(char* szFilePath,PULONG ulFileSize );
BOOL InsertPatchFileToTargetFile(PVOID lpTargetMemory,PVOID lpPatchMemory,ULONG ulTargetSize);
DWORD GetFileInfo(PVOID FileBaseAddress,PATCH_FILE_INFO Type);
VOID ModifyParameter(PVOID FileBaseAddress,ULONG ulTargetSize,ULONG ulFlieAlignPatchCodeSize,ULONG ulRealPatchCodeSize,ULONG ulNewOEP);
ULONG GetPathCodeSectionRVA(PVOID lpPatchMemory);
ULONG Align(ULONG FileSize,ULONG ulAlignment);
ULONG FileAlign(ULONG FileSize,ULONG ulFileAlignment);
ULONG GetNewFileOEP(PVOID lpTargetMemory);
VOID ModifyPatchCodeJumpAddress(PVOID lpNewFileBaseAddress,ULONG NewFileSize,ULONG ULNewFileOEP,ULONG ulOldOEP,ULONG ulRealPatchCodeSize); int _tmain(int argc, _TCHAR* argv[])
{
PVOID lpPatchMemory = NULL;
PVOID lpTargetMemory = NULL;
ULONG ulPatchSize = ;
ULONG ulTargetSize = ; lpTargetMemory = GetFileBaseAddressAndSize(szTargetPath,&ulTargetSize);
lpPatchMemory = GetFileBaseAddressAndSize(szPatchPath,&ulPatchSize); InsertPatchFileToTargetFile(lpTargetMemory,lpPatchMemory,ulTargetSize); return ;
} BOOL InsertPatchFileToTargetFile(PVOID lpTargetMemory,PVOID lpPatchMemory,ULONG ulTargetSize)
{
DWORD dwFileAlignPatchCodeSize = ;
DWORD dwRealPatchCodeSize = ;
ULONG ulPathCodeSectionRVA = ;
ULONG ULNewFileOEP = ;
ULONG ulOldOEP = ;
ULONG ulFileAlignment = ; dwRealPatchCodeSize = GetFileInfo(lpPatchMemory,RealSectionSize); //获得Patch文件未对齐时的大小
ulPathCodeSectionRVA = GetFileInfo(lpPatchMemory,SectionRVA); //获得Patch文件所要加载节的RVA
ulOldOEP = GetFileInfo(lpTargetMemory,AddressOfEntryPoint);
ulFileAlignment = GetFileInfo(lpTargetMemory,FileAlignment);
ULNewFileOEP = GetNewFileOEP(lpTargetMemory);
dwFileAlignPatchCodeSize = Align(dwRealPatchCodeSize,ulFileAlignment); PVOID NewFileBaseAddress = malloc(ulTargetSize+dwFileAlignPatchCodeSize);
memset(NewFileBaseAddress,,ulTargetSize+dwFileAlignPatchCodeSize); memcpy(NewFileBaseAddress,lpTargetMemory,ulTargetSize);
memcpy((PVOID)((ULONG_PTR)NewFileBaseAddress+ulTargetSize),(PVOID)((ULONG_PTR)lpPatchMemory+ulPathCodeSectionRVA),dwRealPatchCodeSize); ModifyPatchCodeJumpAddress(NewFileBaseAddress,ulTargetSize+dwRealPatchCodeSize,ULNewFileOEP,ulOldOEP,dwRealPatchCodeSize); //修改PatchCode结尾E9跳转地址 ModifyParameter(NewFileBaseAddress,ulTargetSize,dwFileAlignPatchCodeSize,dwRealPatchCodeSize,ULNewFileOEP); //修改最后一节和PE头的参数 HANDLE hNewFile = CreateFileA(szModifyPEPath,GENERIC_READ|GENERIC_WRITE,FILE_SHARE_READ|FILE_SHARE_WRITE,NULL,CREATE_ALWAYS,FILE_ATTRIBUTE_ARCHIVE,NULL);
if(hNewFile == INVALID_HANDLE_VALUE)
{
printf("CreateFileA Failed!\r\n");
return FALSE;
}
DWORD dwRet = ;
if(WriteFile(hNewFile,NewFileBaseAddress,ulTargetSize+dwFileAlignPatchCodeSize,&dwRet,NULL) == )
{
printf("WriteFile Failed!\r\n");
return FALSE;
}
else
{
printf("Succeed!\r\n");
} return TRUE; }
ULONG GetNewFileOEP(PVOID lpTargetMemory)
{
PIMAGE_DOS_HEADER DosHead = (PIMAGE_DOS_HEADER)lpTargetMemory;
PIMAGE_NT_HEADERS NTHead = (PIMAGE_NT_HEADERS)((ULONG_PTR)DosHead+DosHead->e_lfanew);
PIMAGE_SECTION_HEADER SectionHead = (PIMAGE_SECTION_HEADER)((ULONG_PTR)NTHead+sizeof(IMAGE_NT_HEADERS)); ULONG ulNumberOfSection = NTHead->FileHeader.NumberOfSections;
ULONG ulNewFileOEP = SectionHead[ulNumberOfSection-].VirtualAddress+SectionHead[ulNumberOfSection-].SizeOfRawData;
return ulNewFileOEP;
}
VOID ModifyPatchCodeJumpAddress(PVOID lpNewFileBaseAddress,ULONG NewFileSize,ULONG ULNewFileOEP,ULONG ulOldOEP,ULONG ulRealPatchCodeSize)
{
UCHAR JmpCode[] = "\x00\x00\x00\x00";
*(int*)JmpCode = ( ulOldOEP + ) - ( ULNewFileOEP + ulRealPatchCodeSize ); //+1越过E9
memcpy((PVOID)((UCHAR*)lpNewFileBaseAddress + NewFileSize - ),JmpCode,strlen((char*)JmpCode)); //看内存 E9后有5个非0字节,所以不是-4 } VOID ModifyParameter(PVOID FileBaseAddress,ULONG ulTargetSize,ULONG ulFlieAlignPatchCodeSize,ULONG ulRealPatchCodeSize,ULONG ulNewOEP)
{
PIMAGE_DOS_HEADER DosHead = (PIMAGE_DOS_HEADER)FileBaseAddress;
PIMAGE_NT_HEADERS NTHead = (PIMAGE_NT_HEADERS)((ULONG_PTR)DosHead+DosHead->e_lfanew);
PIMAGE_SECTION_HEADER SectionHead = (PIMAGE_SECTION_HEADER)((ULONG_PTR)NTHead+sizeof(IMAGE_NT_HEADERS)); ULONG MemoryAlignment = NTHead->OptionalHeader.SectionAlignment;
ULONG ulNumberOfSection = NTHead->FileHeader.NumberOfSections; SectionHead[ulNumberOfSection-].Characteristics = 0x60000020;
SectionHead[ulNumberOfSection-].Misc.VirtualSize = SectionHead[ulNumberOfSection-].SizeOfRawData + ulRealPatchCodeSize;
SectionHead[ulNumberOfSection-].SizeOfRawData += ulFlieAlignPatchCodeSize; NTHead->OptionalHeader.SizeOfImage = Align(SectionHead[ulNumberOfSection-].VirtualAddress+SectionHead[ulNumberOfSection-].SizeOfRawData,MemoryAlignment);
NTHead->OptionalHeader.AddressOfEntryPoint = ulNewOEP;
} ULONG Align(ULONG FileSize,ULONG ulAlignment)
{
if(FileSize%ulAlignment != )
{
int Temp = FileSize/ulAlignment;
return ulAlignment*(Temp+);
}
else
{
return FileSize;
}
}
DWORD GetFileInfo(PVOID FileBaseAddress,PATCH_FILE_INFO Type)
{
PIMAGE_DOS_HEADER DosHead = (PIMAGE_DOS_HEADER)FileBaseAddress;
PIMAGE_NT_HEADERS NTHead = (PIMAGE_NT_HEADERS)((ULONG_PTR)DosHead+DosHead->e_lfanew);
PIMAGE_SECTION_HEADER SectionHead = (PIMAGE_SECTION_HEADER)((ULONG_PTR)NTHead+sizeof(IMAGE_NT_HEADERS)); DWORD dwEntryPoint = NTHead->OptionalHeader.AddressOfEntryPoint;
DWORD dwRet = ;
if(Type == AddressOfEntryPoint)
{
dwRet = dwEntryPoint;
}
if(Type == FileAlignment)
{
dwRet = NTHead->OptionalHeader.FileAlignment;
} for(int i=;i<NTHead->FileHeader.NumberOfSections;i++)
{
if(dwEntryPoint>=SectionHead[i].VirtualAddress && dwEntryPoint<SectionHead[i].VirtualAddress+SectionHead[i].SizeOfRawData)
{ if(Type == RealSectionSize)
{
dwRet = SectionHead[i].Misc.VirtualSize;
}
if(Type == SectionRVA)
{
dwRet = SectionHead[i].PointerToRawData;
} } } if(dwRet == NULL)
{
printf("GetFileInfo Failed!\r\n");
} return dwRet; } PVOID GetFileBaseAddressAndSize(char* szFilePath,PULONG ulFileSize )
{
HANDLE hFile = CreateFileA(szFilePath,
GENERIC_READ|GENERIC_WRITE,FILE_SHARE_WRITE|FILE_SHARE_WRITE,NULL,
OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL,NULL); if (hFile==INVALID_HANDLE_VALUE)
{
printf("CreateFile Failed!\r\n");
return NULL;
}
*ulFileSize = GetFileSize(hFile,NULL); if (!(*ulFileSize))
{
printf("GetFileSize Failed!\r\n");
CloseHandle(hFile);
return NULL;
}
HANDLE hMapFile = CreateFileMapping(
hFile,
NULL,
PAGE_READWRITE,
,
,
NULL); if (hMapFile == INVALID_HANDLE_VALUE)
{
printf("CreateFileMapping Failed!\r\n");
CloseHandle(hFile);
return NULL;
} PVOID FileBaseAddress = MapViewOfFile(hMapFile,FILE_MAP_ALL_ACCESS,NULL,NULL,NULL);
if (FileBaseAddress == NULL)
{
CloseHandle(hFile);
CloseHandle(hMapFile);
printf("MapViewOfFile Failed!\r\n");
return NULL;
} return FileBaseAddress;
}

<原创>在PE最后一节中插入补丁程序(附代码)的更多相关文章

  1. 网页中插入Flvplayer视频播放器代码

    http://blog.csdn.net/china_skag/article/details/7424019 原地址:http://yuweiqiang.blog.163.com/blog/stat ...

  2. thinkphp中插入ueditor编辑器的代码

    1.需要在header中加入以下js内容:<script type="text/javascript" src="{$smarty.const.__ROOT__}/ ...

  3. MapReduce中的排序(附代码)

    在直接学习hadoop的排序之前还要了解一些基本知识. Hadoop的序列化和比较接口 Hadoop的序列化格式:Writable Writable是Hadoop自己的序列化格式,还要一个子接口是Wr ...

  4. html中插入flash代码详解(转载)

    <object classid="clsid:D27CDB6E-AE6D-11cf-96B8-444553540000" codebase="http://down ...

  5. 在网页中插入背景音乐代码(html)

    有两种 分别用<bgsound>和<embed></embed>标签,当用<embed>插入背景音乐时可以设置宽度和高度为0,隐藏播放器. 二者的参数如 ...

  6. 20145314郑凯杰《网络对抗技术》PE文件病毒捆绑(插入捆绑)的实现

    20145314郑凯杰<网络对抗技术>PE文件病毒捆绑(插入捆绑)的实现 一.本节摘要 简介:每个应用程序内部都有一定的空间(因为文件对齐余留的00字段)可以被利用,这样就可以保证被插入的 ...

  7. 网页中插入swf动画(embed)

    网页中插入swf动画(embed:[ɪm'bed]) 例题: <embed src="swf.sef" width="200" height=" ...

  8. 【原创+译文】官方文档中声明的如何创建抽屉导航栏(Navigation Drawer)

    如需转载请注明出处:http://www.cnblogs.com/ghylzwsb/p/5831759.html 创建一个抽屉导航栏 抽屉式导航栏是显示在屏幕的左边缘,它是应用程序的主导航选项面板.它 ...

  9. 如何用Apache POI操作Excel文件-----如何在已有的Excel文件中插入一行新的数据?

    在POI的第一节入门中,我们提供了两个简单的例子,一个是如何用Apache POI新建一个工作薄,另外一个例子是,如果用Apache POI新建一个工作表.那么在这个章节里面,我将会给大家演示一下,如 ...

随机推荐

  1. Java 8特性尝鲜:新新IO

    Java 8特性尝鲜:新新IO 在这个专题前面的文章中,我们已经看到,使用Java8的lambda表达式对现有的JDK1.2 I/O库的提升,主要是可以使用lambda表达式来构造java.io.Fi ...

  2. WebStorm技巧-在安卓手机上运行Ionic程序

    打开菜单项 Run -> Run-   选择 Edit Configurations-   添加一个 PhoneGap/Cordova 配置项,命名如: Ionic Android, 并输入相关 ...

  3. DetachedCriteria的简单使用

    一. DetachedCriteria使得hibernate能够对查询条件进行面向对象的方式来组装.其创建方式有两种: 1.1直接用class创建:DetachedCriteria criteria  ...

  4. Kendo MVVM 数据绑定(二) Checked

    Kendo MVVM 数据绑定(二) Checked Checked 绑定用在 checkbox ()或 radio button ()上.注意: checked 绑定只适用于支持 checked 的 ...

  5. Word通配符

    通配符模式下: ^13表示回车,^32表示空格 第一步,使用通配符替换掉无关文本 M?G-C??[A-Z]{1,20}_[A-Z]{1,20}_201?????_?? VirtualTrial[0-9 ...

  6. jsp之获传统方式取后台数据

    1.建立模型对象: package com.java.model; public class Student { private String name; private int age; publi ...

  7. HDU 5501 The Highest Mark (贪心+DP,经典)

    题意: 有n道题目,每道题目的初始分数为Ai,分数每分钟减少Bi,完成此题需要Ci分钟,问在t分钟内最多能获得多少分? 思路: 好题~ 如果没有B的话,就是一道裸的01背包的题目了.每道题目的得分为: ...

  8. Java 变量及基本数据类型

    1.Java变量 1.1 变量的概念 内存中开辟的一块存储空间,用于存放运算过程中需要用到的数据: 该区域有自己的名称(变量名)和类型(数据类型): 该区域的数据可以在同一类型范围内不断变化: 1) ...

  9. UVA 11491 Erasing and Winning 奖品的价值 (贪心)

    题意:给你一个n位整数,让你删掉d个数字,剩下的数字要尽量大. 题解:因为最后数字位数是确定的,而且低位数字对答案的贡献是一定不及高位数字的,所以优先选择选最大且最靠左边的数字,但是有一个限制,选完这 ...

  10. Android(java)学习笔记137:ListView编写步骤(重点)

    1.ListView在我们的手机android编写程序中使用是十分广泛的,比如如下图中 短信 和 手机设置 都是ListView的效果: 手机设置:             短信:    2.正因为这 ...