在PE中,新增节,添加代码
在PE中,新增节,添加代码
一、先判断节表后是否有空闲位置,添加节表信息,必须多出两个节表位置,最后以零结尾。
二、新增节后,需要修改以下信息
1、添加一个新节,可以复制一份,最好是拥有可执行属性的节,如.text。
2、在节表区,新增节的后面,填充一个节,用零填充。
3、修改标准PE头中节的数量。
4、修改SizeOfImage的大小。
5、在原有数据的后面,新增一个节的数据(内存对齐的整倍数)。
6、修正新增节表的属性。
三、新节各个属性修改说明
1、Name:名字随便修改,不能超过八个字节。
2、VirtualSize:申请的新节空间大小,比如1000
3、VirtualAddress:等于上一个节的VirtualAddress + SizeOfRawData
4、SizeOfRawData:设置可以和VirtualSize一样,比如1000
5、PointerToRawData:等于上一个节的PointerToRawData+ SizeOfRawData
6、PointerToRelocation:设置成零
7、PointerToLineNumbers:设置成零
8、NumberOfLineRelocations:设置成零
9、NumberOfLineNumbers:设置成零
10、Characteristics:块属性0x20000060 可以取上一个节表和本节表的属性值,进行异或 如x|y
标志(属性块) 常用特征值对照表:
[值:00000020h] [IMAGE_SCN_CNT_CODE // Section contains code.(包含可执行代码)]
[值:00000040h] [IMAGE_SCN_CNT_INITIALIZED_DATA // Section contains initialized data.(该块包含已初始化的数据)]
[值:00000080h] [IMAGE_SCN_CNT_UNINITIALIZED_DATA // Section contains uninitialized data.(该块包含未初始化的数据)]
[值:00000200h] [IMAGE_SCN_LNK_INFO // Section contains comments or some other type of information.]
[值:00000800h] [IMAGE_SCN_LNK_REMOVE // Section contents will not become part of image.]
[值:00001000h] [IMAGE_SCN_LNK_COMDAT // Section contents comdat.]
[值:00004000h] [IMAGE_SCN_NO_DEFER_SPEC_EXC // Reset speculative exceptions handling bits in the TLB entries for this section.]
[值:00008000h] [IMAGE_SCN_GPREL // Section content can be accessed relative to GP.]
[值:00500000h] [IMAGE_SCN_ALIGN_16BYTES // Default alignment if no others are specified.]
[值:01000000h] [IMAGE_SCN_LNK_NRELOC_OVFL // Section contains extended relocations.]
[值:02000000h] [IMAGE_SCN_MEM_DISCARDABLE // Section can be discarded.]
[值:04000000h] [IMAGE_SCN_MEM_NOT_CACHED // Section is not cachable.]
[值:08000000h] [IMAGE_SCN_MEM_NOT_PAGED // Section is not pageable.]
[值:10000000h] [IMAGE_SCN_MEM_SHARED // Section is shareable(该块为共享块).]
[值:20000000h] [IMAGE_SCN_MEM_EXECUTE // Section is executable.(该块可执行)]
[值:40000000h] [IMAGE_SCN_MEM_READ // Section is readable.(该块可读)]
[值:80000000h] [IMAGE_SCN_MEM_WRITE // Section is writeable.(该块可写)]
-----------------------------------------------------------------------------------------------------
- // mem.cpp : 定义控制台应用程序的入口点。
- //PE文件从文件加载到内存,再从内存读取,然后存盘到文件
- #include "stdafx.h"
- #include <windows.h>
- #include <winnt.h>
- //#define PATH "C:\\Windows\\System32\\notepad.exe"
- #define PATH "C:\\Users\\Administrator\\Desktop\\ipmsg.exe"
- #define MsgADD 0x75cffde6
- char Shellcode[] =
- {
- 0x6A, 0x00, 0x6A, 0x00, 0x6A, 0x00, 0x6A, 0x00,
- 0xE8, 0x00, 0x00, 0x00, 0x00,
- 0xE9, 0x00, 0x00, 0x00, 0x00
- };
- int Filelength(FILE *fp);
- int _tmain(int argc, _TCHAR* argv[])
- {
- FILE *Fp;
- fopen_s(&Fp, PATH, "rb");
- int FileSize = Filelength(Fp);//获取文件大小
- char * FileBuffer = (char *)malloc(FileSize);//申请存放文件的内存空间
- if (FileBuffer == NULL)
- {
- printf("申请iImageBuffer失败");
- }
- fread_s(FileBuffer, FileSize, 1, FileSize, Fp); //将文件复制到内存中
- //定位一下内存中的数据 各个头表
- //定位标准PE头
- PIMAGE_FILE_HEADER MyFileHeader;
- MyFileHeader = (PIMAGE_FILE_HEADER)(char *)(FileBuffer + *(int *)(FileBuffer + 0x3c) + 0x4);
- //定位可选PE头
- PIMAGE_OPTIONAL_HEADER MyOptionalHeader;
- MyOptionalHeader = (PIMAGE_OPTIONAL_HEADER)((char *)MyFileHeader + 0x14);
- //定位节表
- PIMAGE_SECTION_HEADER MySectionHeader;
- MySectionHeader = (PIMAGE_SECTION_HEADER)((char *)MyOptionalHeader + MyFileHeader->SizeOfOptionalHeader);
- //拉伸,也就是读到内存中的状态
- char * ImageBuffer = (char *)malloc(MyOptionalHeader->SizeOfImage+0x1000);//给拉伸申请内存空间
- ZeroMemory(ImageBuffer, MyOptionalHeader->SizeOfImage+0x1000);
- if (ImageBuffer == NULL)
- {
- printf("申请iImageBuffer失败");
- }
- memcpy(ImageBuffer, FileBuffer, MyOptionalHeader->SizeOfHeaders);
- for (int i = 0; i < MyFileHeader->NumberOfSections; i++)
- {
- memcpy(ImageBuffer + MySectionHeader->VirtualAddress, FileBuffer + MySectionHeader->PointerToRawData, MySectionHeader->SizeOfRawData);//
- MySectionHeader++;
- }
- //新增节开始
- PIMAGE_SECTION_HEADER AddSectionHeader;
- AddSectionHeader = MySectionHeader;
- MySectionHeader--;
- //AddSectionHeader->Name = "cyp";
- //AddSectionHeader->Name = { 0 };
- AddSectionHeader->Name[0] = '.'; AddSectionHeader->Name[1] = 'c'; AddSectionHeader->Name[2] = 'y'; AddSectionHeader->Name[3] = 'p';
- AddSectionHeader->Misc.VirtualSize = 0x1000;
- AddSectionHeader->VirtualAddress = MySectionHeader->VirtualAddress + MySectionHeader->SizeOfRawData;
- AddSectionHeader->SizeOfRawData = 0x1000;
- AddSectionHeader->PointerToRawData = MySectionHeader->PointerToRawData + MySectionHeader->SizeOfRawData;
- int x = (MySectionHeader - (MyFileHeader->NumberOfSections-1))->Characteristics;
- AddSectionHeader->Characteristics = x;
- MyFileHeader->NumberOfSections += 1;
- MyOptionalHeader->SizeOfImage + 0x1000;
- //新增节结束
- //添加代码到PE中
- MyFileHeader = (PIMAGE_FILE_HEADER)(char *)(ImageBuffer + *(int *)(ImageBuffer + 0x3c) + 0x4);
- MyOptionalHeader = (PIMAGE_OPTIONAL_HEADER)((char *)MyFileHeader + 0x14);
- MySectionHeader = (PIMAGE_SECTION_HEADER)((char *)MyOptionalHeader + MyFileHeader->SizeOfOptionalHeader);//重新指一下,前面动过了
- //E8后面的硬编码地址 =真正要到的地址 - E8的下一行或E8本行 +0x5
- char *CodeAdd = ImageBuffer + MySectionHeader->VirtualAddress + MySectionHeader->Misc.VirtualSize;//为要增加的代码确定位置
- memcpy(CodeAdd, Shellcode, sizeof(Shellcode));//把硬编码复制到指定位置
- int CallAdd = MsgADD - (MyOptionalHeader->ImageBase + ((int)(CodeAdd + 0xd) - (int)ImageBuffer));
- *(int *)(CodeAdd + 0x9) = CallAdd;//定位CALL函数位置
- int JmpAdd = MyOptionalHeader->ImageBase + MyOptionalHeader->AddressOfEntryPoint - (MyOptionalHeader->ImageBase + (CodeAdd + 0xd - ImageBuffer));//前面是真正要跳的地址 后面括号是下一条指令的地址
- *(int *)(CodeAdd + 0xe) = JmpAdd;//定位JMP 跳回位置,也就是修改程序入口
- MyOptionalHeader->AddressOfEntryPoint = CodeAdd - ImageBuffer;//重新定位程序入口处
- //添加代码到PE结束
- //压缩,为存盘做准备
- char *NewBuffer = (char *)malloc(FileSize+0x1000);//给压缩申请内存空间
- if (NewBuffer == NULL)
- {
- printf("申请iImageBuffer失败");
- }
- memcpy(NewBuffer, ImageBuffer, MyOptionalHeader->SizeOfHeaders);
- MySectionHeader = (PIMAGE_SECTION_HEADER)((char *)MyOptionalHeader + MyFileHeader->SizeOfOptionalHeader);//重新指一下,前面动过了
- for (int i = 0; i < MyFileHeader->NumberOfSections; i++)
- {
- memcpy(NewBuffer + MySectionHeader->PointerToRawData, ImageBuffer + MySectionHeader->VirtualAddress, MySectionHeader->SizeOfRawData);
- MySectionHeader++;
- }
- FILE *nFp;
- fopen_s(&nFp, "C:\\Users\\Administrator\\Desktop\\CYP.exe", "wb");
- fwrite(NewBuffer, FileSize, 1, nFp);
- //getchar();
- fclose(nFp);
- free(FileBuffer);
- free(ImageBuffer);
- free(NewBuffer);
- return 0;
- }
- //获取文件大小
- int Filelength(FILE *fp)
- {
- int num;
- fseek(fp, 0, SEEK_END);
- num = ftell(fp);
- fseek(fp, 0, SEEK_SET);
- return num;
- }
在PE中,新增节,添加代码的更多相关文章
- PE知识复习之PE文件空白区添加代码
PE知识复习之PE文件空白区添加代码 一丶简介 根据上面所讲PE知识.我们已经可以实现我们的一点手段了.比如PE的入口点位置.改为我们的入口位置.并且填写我们的代码.这个就是空白区添加代码. 我们也可 ...
- 【转】在Visual Studio中怎样快速添加代码段
原文网址:http://blog.csdn.net/yl2isoft/article/details/9735527 以前一直只知道,键入prop,再按两次tab键,会生成自动属性代码. 今天闲着无事 ...
- 在Zend Studio中为ThinkPHP添加代码自动提示功能
身边很多朋友都使用ThinkPHP或CodeIgniter等开发框架为自己的项目提高开发效率. 在得力于这些优秀框架良好的设计结构的同时,也头疼于代码的自动完成提示功能没有纯PHP网站那么完善了.经常 ...
- 零基础逆向工程20_PE结构04_任意节空白区_新增节_扩大节添加代码
向代码节添加代码实现 作者经过一周不断的失败,再思考以及无数次调试终于实现. 思路:八个步骤 1. 文件拷到文件缓冲区(FileBuffer) //图示见(零基础逆向工程18之PE加载过程) 2. 文 ...
- 向PE文件中空白处添加代码
// mem.cpp : 定义控制台应用程序的入口点. //PE文件从文件加载到内存,再从内存读取,然后存盘到文件 #include "stdafx.h" #include < ...
- <原创>在PE最后一节中插入补丁程序(附代码)
完整文件 http://files.cnblogs.com/Files/Gotogoo/在PE最后一节中插入补丁程序.zip 在PE文件最后一节中插入补丁程序,是最简单也是最有效的一种,因为PE最后 ...
- PE知识复习之PE新增节
PE知识复习之PE新增节 一丶为什么新增节.以及新增节的步骤 例如前几讲.我们的PE文件在空白区可以添加代码.但是这样是由一个弊端的.因为你的空白区节属性可能是只读的不能执行.如果你修改了属性.那么程 ...
- ES6 第七节 ES6中新增的数组知识(1)
目录 ES6 第七节 ES6中新增的数组知识(1) 第七节 ES6中新增的数组知识(1) JSON数组格式转换 Array.of()方法: find()实例方法: ES6 第七节 ES6中新增的数组知 ...
- netbeans中给jpanl添加背景图片制定代码的理解——匿名内部类继承父类
此测试是为了仿照在netbeans中给jpanl添加背景图片的制定代码的执行过程 在JpDemo中定义了个Car类的数据类型,但在给其赋值对象时使用了匿名内部类,继承了Car类,是其子类,并重写了父类 ...
随机推荐
- PHP代码审计4-漏洞挖掘思路
漏洞挖掘思路 漏洞形成的条件 1.变量可控制 2.变量可到达有利用价值的函数(危险函数) 漏洞造成的效果 漏洞的利用效果取决于最终的函数功能,变量进入什么样的函数就导致什么样的效果 危险函数 文件包含 ...
- 14,flask-sqlalchemy项目配置
基于一个flask项目,加入flask-SQLAlchemy 1.加入falsk-sqlalchemy第三方组件 from flask import Flask # 导入Flask-SQLAlchem ...
- Javacript实现倒计时
<!DOCTYPE html><html lang="en"><head> <meta charset="UTF-8" ...
- Maven学习 (五) Elipse中发布一个Maven项目到Tomcat
对于maven初学者的我,经常遇到一个问题就是,maven项目创建成功后,本来已经添加了jar的依赖,但是发布到Tomcat中就是没有jar包存在, 启动Tomcat总是报没有找到jar包,可项目结构 ...
- [转]ANDROID JNI之JAVA域与c域的互操作
本文讲述AndroidJava域与C域互操作:Java域调用c域的函数:c域访问Java域的属性和方法:c域生成的对象的保存与使用.重点讲解c域如何访问Java域. 虽然AndroidJNI实现中,c ...
- 剑指Offer - 九度1372 - 最大子向量和(连续子数组的最大和)
剑指Offer - 九度1372 - 最大子向量和(连续子数组的最大和)2013-11-23 16:25 题目描述: HZ偶尔会拿些专业问题来忽悠那些非计算机专业的同学.今天JOBDU测试组开完会后, ...
- 《Cracking the Coding Interview》——第12章:测试——题目1
2014-04-24 23:10 题目:找出下面代码里的错误. 解法:请看下面. 代码: // 12.1 What's wrong with the following code segment? # ...
- 【Python】Python PYQT4 GUI编程与exe打包
本篇文章承接http://www.cnblogs.com/zhang-zhi/p/7646923.html#3807385,上篇文章描述了对文本文件的简单处理,本章节结合PYQT4实现该功能的GUI图 ...
- SOA与WCF
背景: 高校平台马上就要进入编程阶段了,对于没怎么做过正式项目的我们来说,要学的东西实在太多了.一下子面对这么多学习资料时,我们也不能着急,还是踏踏实实,一个一个地去了解,其实他们都没那么神秘.这篇博 ...
- sql优化(转)
explain +sql分析sql语句执行效率 1.对查询进行优化,应尽量避免全表扫描,首先应考虑在 where 及 order by 涉及的列上建立索引. 2.应尽量避免在 where 子句中使用! ...