完整文件  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. HBuilder配置sass

    参考: https://www.cnblogs.com/padding1015/p/7133811.html 如果期间报错,参考步骤7,然后再重新安装配置 预编译配置--no-cache %FileN ...

  2. springIOC+Mysql+springmvc事务测试题总结

    1.关于http1.1和1.0的长连接和短连接 两个都支持长连接和短连接 http1.0默认为短连接,也就是说,浏览器和服务器每进行一次HTTP操作,就建立一次连接,任务结束就中断连接 http1.1 ...

  3. JAVA基础之线程

    个人理解: 在相同的进程也就是运行同样的程序的前提下,线程越多效率越快!当然硬件也是个障碍!为了提高效率,可以多创建线程,但是也不是越多越好,这就需要了线程池进行管理!需要知道的线程实现的方法:继承T ...

  4. Java基础:(六)关键字

    一.final 数据: 声明数据为常量,可以是编译时常量,也可以是在运行时被初始化后不能被改变的常量. 对于基本类型,final使数值不变: 对于引用类型,final使引用不变,也就不能引用其他对象, ...

  5. AJPFX关于JDK,JRE,JVM的区别与联系

    很多朋友可能跟我一样,对JDK,JRE,JVM这三者的联系与区别,一直都是模模糊糊的. 今天我们来整理下三者的关系. JDK : Java Development ToolKit(Java开发工具包) ...

  6. web标准、可用性、可访问性

    前言:大家不难发现,只要是招聘UED相关的岗位,如前端开发工程师.交互设计师.用户研究员甚至视觉设计师,一般都对web标准.可用性和可访问性的理解有要求.那么到底什么是web标准.可用性.可访问性呢? ...

  7. 【extjs6学习笔记】1.1 初始:创建项目

    创建工作空间 sencha generate workspace /path/to/workspace 使用sencha创建应用 sencha -sdk /path/to/sdk generate a ...

  8. 判断JS数据类型的几种方法

    原文转自http://www.cnblogs.com/onepixel/p/5126046.html! 说到数据类型,我们先说一下JavaScript 中常见的几种数据类型: 基本类型:string, ...

  9. 洛谷 P1057 传球游戏

    题目描述 上体育课的时候,小蛮的老师经常带着同学们一起做游戏.这次,老师带着同学们一起做传球游戏. 游戏规则是这样的:n个同学站成一个圆圈,其中的一个同学手里拿着一个球,当老师吹哨子时开始传球,每个同 ...

  10. 洛谷 P1588 丢失的牛

    题目描述 FJ丢失了他的一头牛,他决定追回他的牛.已知FJ和牛在一条直线上,初始位置分别为x和y,假定牛在原地不动.FJ的行走方式很特别:他每一次可以前进一步.后退一步或者直接走到2*x的位置.计算他 ...