<原创>在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新建一个工作表.那么在这个章节里面,我将会给大家演示一下,如 ...
随机推荐
- String、String Buffer、String Builder
对于String.String Buffer.String Builder:我一直都只知道String是字符串常量,后两者是字符串变量: String和String Buffer是线程安全的,Stri ...
- 单机版mongodb
1.下载安装包 wget http://fastdl.mongodb.org/linux/mongodb-linux-i686-1.8.2.tgz 下载完成后解压缩压缩包 tar zxf mongod ...
- postgresql 存储过程动态插入数据 2
最近学习postgresql,正一个小活要用上,所以就开始学习了!然而,学习的过程极其艰辛,但却也充满了乐趣. 一般来说数据库的操作不外如何增,删,改,查,而首要的就是要添加数据到数据库中,因为以前的 ...
- struts2 ognl表达式访问值栈
1:简单的说,值栈是对应每一个请求对象的轻量级的数据存储中心,在这里统一管理着数据,供Action.Result.Interceptor等Struts2的其他部分使用,这样数据被集中管理起来而不凌乱. ...
- 事务回滚 DEMO
因为有些事物回滚 查询的时候 可能查出来空值 我们肯定不愿意把空值添加数据库里面 一般基本的是这么写 if (object_id('add_T_Disclose_DiscloseList', 'P' ...
- js构造方法
<!DOCTYPE html><html><head><meta charset="UTF-8"><title>Java ...
- 洛谷 U3348 A2-回文数
题目背景 方方方很喜欢回文数,于是就有了一道关于回文数的题目. 题目描述 求从小到大第n(1<=n<=10^18)个回文数. 注释:出题人认为回文数不包括0. 输入输出格式 输入格式: 一 ...
- Caused by: java.lang.IllegalStateException: javax.websocket.server.ServerContainer not available
java.lang.IllegalStateException: Failed to load ApplicationContext at org.springframework.test.co ...
- .net后台使用post方式对指定地址的方法传值并且获取结果的方法
/// <summary> /// .net 后台 post http地址请求 /// </summary> /// <param name="uri" ...
- UVA 1599, POJ 3092 Ideal Path 理想路径 (逆向BFS跑层次图)
大体思路是从终点反向做一次BFS得到一个层次图,然后从起点开始依次向更小的层跑,跑的时候选则字典序最小的,由于可能有多个满足条件的点,所以要把这层满足条件的点保存起来,在跑下一层.跑完一层就会得到这层 ...