<原创>在PE最后一节中插入补丁程序(附代码)
完整文件 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最后一节中插入补丁程序(附代码)的更多相关文章
- 网页中插入Flvplayer视频播放器代码
http://blog.csdn.net/china_skag/article/details/7424019 原地址:http://yuweiqiang.blog.163.com/blog/stat ...
- thinkphp中插入ueditor编辑器的代码
1.需要在header中加入以下js内容:<script type="text/javascript" src="{$smarty.const.__ROOT__}/ ...
- MapReduce中的排序(附代码)
在直接学习hadoop的排序之前还要了解一些基本知识. Hadoop的序列化和比较接口 Hadoop的序列化格式:Writable Writable是Hadoop自己的序列化格式,还要一个子接口是Wr ...
- html中插入flash代码详解(转载)
<object classid="clsid:D27CDB6E-AE6D-11cf-96B8-444553540000" codebase="http://down ...
- 在网页中插入背景音乐代码(html)
有两种 分别用<bgsound>和<embed></embed>标签,当用<embed>插入背景音乐时可以设置宽度和高度为0,隐藏播放器. 二者的参数如 ...
- 20145314郑凯杰《网络对抗技术》PE文件病毒捆绑(插入捆绑)的实现
20145314郑凯杰<网络对抗技术>PE文件病毒捆绑(插入捆绑)的实现 一.本节摘要 简介:每个应用程序内部都有一定的空间(因为文件对齐余留的00字段)可以被利用,这样就可以保证被插入的 ...
- 网页中插入swf动画(embed)
网页中插入swf动画(embed:[ɪm'bed]) 例题: <embed src="swf.sef" width="200" height=" ...
- 【原创+译文】官方文档中声明的如何创建抽屉导航栏(Navigation Drawer)
如需转载请注明出处:http://www.cnblogs.com/ghylzwsb/p/5831759.html 创建一个抽屉导航栏 抽屉式导航栏是显示在屏幕的左边缘,它是应用程序的主导航选项面板.它 ...
- 如何用Apache POI操作Excel文件-----如何在已有的Excel文件中插入一行新的数据?
在POI的第一节入门中,我们提供了两个简单的例子,一个是如何用Apache POI新建一个工作薄,另外一个例子是,如果用Apache POI新建一个工作表.那么在这个章节里面,我将会给大家演示一下,如 ...
随机推荐
- PHP+Mysql+jQuery找回密码
通常所说的密码找回功能不是真的能把忘记的密码找回,因为我们的密码是加密保存的,一般开发者会在验证用户信息后通过程序生成一个新密码或者生成一个特定的链接并发送邮件到用户邮箱,用户从邮箱链接到网站的重置密 ...
- MVC FileResult
你如何将文件传送给用户取决于你最开始如何存储它,如果你将文件存入数据库,你会用流的方式将文件返还给用户,如果你将文件存在硬盘中,你只需要提供一个超链接即可,或者也可以以流的方式.每当你需要以流的方式将 ...
- ListView 视图(View)
自定义视图,设置默认ListView,ListViewItems默认样式 public class VirtualStackPanelView : ViewBase { public static r ...
- @ConfigurationProperties
功能 将属性文件与一个Java类绑定,属性文件中的变量与Java类中的成员变量一一对应,无需完全一致. 如需将 @ConfigurationProperties 注解的目标类添加到Spring IOC ...
- css继承性
不可继承的:display.margin.border.padding.background.height.min-height.max- height.width.min-width.max-wid ...
- 零基础逆向工程11_C语言05_结构体
结构体小结 结构体是按照分配的大小,局部变量会自动数据对齐 1字节对齐,省空间,但cpu查找效率低 4字节对齐,不省空间,但cpu查找效率高 VC6默认的结构对齐大小 项目右键-> settin ...
- Centos离线安装Docker并加入到Swarm管理节点
以root用户登录 加入Swarm前需要在Swarm上生成Token,所以需要提前将Swarm集群搭建完成后,再运行以下命令将各虚机加入到swarm节点 下载docker离线安装包,并拷贝到/root ...
- 解决Mysql导入大数据出现gone away的问题
在用Mysql Yog或者PHPMyadmin等工具导入数据量大的sql文件时,会提示“gone away”,那么如何处理这个问题尼? 在Mysql对应的配置文件中my.ini文件中加入以下配置: # ...
- ssh连接github连不上
连接github报端口22连接不上: 输入命令展示出ssh_config内容后: vim /etc/ssh/ssh_config 或者使用open /etc/ssh/ssh_config命令在文本编辑 ...
- python爬虫之路——正则表达式初识
正则表达式:是一个特殊的符号系列,检查字符串是否与指定模式匹配. python中的re模块拥有全部的正则表达式功能. 判断字符: 类型: 数目:有无: 个数:单值 区间 离散 判 ...