完整文件  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. Zepto核心模块源代码分析

    一.Zepto核心模块架构 Zepto核心模块架构图 该图展示了Zepto核心模块架构代码的组织方式.主要分为私有变量.函数和暴露给用户的所有api. Zepto核心模块架构代码 该图展示了Zepto ...

  2. Java中的break循环——通过示例学习Java编程(13)

    作者:CHAITANYA SINGH 来源:https://www.koofun.com//pro/kfpostsdetail?kfpostsid=24 break语句通常用于以下两种情况: (A)使 ...

  3. I/O————对象流

    对象流指的是可以直接把一个对象以流的形式传输给其他的介质,比如硬盘 一个对象以流的形式进行传输,叫做序列化. 该对象所对应的类,必须是实现Serializable接口 对象的序列化与反序列化就是从文件 ...

  4. java初探之初始化

    首先明确,变量初始化是在任何方法(包括构造器)被调用之前进行的. 1.实例变量的初始化 实例变量只有当它所属的类实例化后才会存在,构造器被执行就意味着对象就被创建. 1.1.指定初始化. class ...

  5. JavaScript 的 parseInt 取整

    http://www.neoease.com/javascript-get-integer-via-parseint/ JavaScript 是弱类型语言, 为了保证数值的有效性, 在处理数值的时候, ...

  6. BZOJ 4242: 水壶 Kruskal+BFS

    4242: 水壶 Time Limit: 40 Sec  Memory Limit: 256 MBSubmit: 427  Solved: 112[Submit][Status][Discuss] D ...

  7. python基础教程总结2——字符串

    1.基本操作 序列操作:索引,分片,乘法,判断成员资格,长度,最值...... 注:字符串不可变,分片赋值不合法 2.字符串格式化 模板 格式化字符串时,Python使用一个字符串作为模板.模板中有格 ...

  8. Erlang程序设计(第2版)读书笔记(一)

    正如<代码的未来>中所说,为了充分利用多核,并发变成将成为未来发展的趋势,对于并发编程的支持,Erlang确实是不二之选,Erlang在国内仍然较为小众,经典书籍相对也要少很多,最终选择了 ...

  9. codeforecs Gym 100286B Blind Walk

    交互式程序,要用到一个函数fflush,它的作用是对标准输出流的清理,对stdout来说是及时地打印数据到屏幕上,一个事实:标准输出是以『行』为单位进行的,也即碰到\n才打印数据到屏幕.这就可能造成延 ...

  10. CPP-STL:vector的内存释放

    1. vector容器的内存自增长 与其他容器不同,其内存空间只会增长,不会减小.先来看看"C++ Primer"中怎么说:为了支持快速的随机访问,vector容器的元素以连续方式 ...