在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中,新增节,添加代码的更多相关文章

  1. PE知识复习之PE文件空白区添加代码

    PE知识复习之PE文件空白区添加代码 一丶简介 根据上面所讲PE知识.我们已经可以实现我们的一点手段了.比如PE的入口点位置.改为我们的入口位置.并且填写我们的代码.这个就是空白区添加代码. 我们也可 ...

  2. 【转】在Visual Studio中怎样快速添加代码段

    原文网址:http://blog.csdn.net/yl2isoft/article/details/9735527 以前一直只知道,键入prop,再按两次tab键,会生成自动属性代码. 今天闲着无事 ...

  3. 在Zend Studio中为ThinkPHP添加代码自动提示功能

    身边很多朋友都使用ThinkPHP或CodeIgniter等开发框架为自己的项目提高开发效率. 在得力于这些优秀框架良好的设计结构的同时,也头疼于代码的自动完成提示功能没有纯PHP网站那么完善了.经常 ...

  4. 零基础逆向工程20_PE结构04_任意节空白区_新增节_扩大节添加代码

    向代码节添加代码实现 作者经过一周不断的失败,再思考以及无数次调试终于实现. 思路:八个步骤 1. 文件拷到文件缓冲区(FileBuffer) //图示见(零基础逆向工程18之PE加载过程) 2. 文 ...

  5. 向PE文件中空白处添加代码

    // mem.cpp : 定义控制台应用程序的入口点. //PE文件从文件加载到内存,再从内存读取,然后存盘到文件 #include "stdafx.h" #include < ...

  6. <原创>在PE最后一节中插入补丁程序(附代码)

    完整文件  http://files.cnblogs.com/Files/Gotogoo/在PE最后一节中插入补丁程序.zip 在PE文件最后一节中插入补丁程序,是最简单也是最有效的一种,因为PE最后 ...

  7. PE知识复习之PE新增节

    PE知识复习之PE新增节 一丶为什么新增节.以及新增节的步骤 例如前几讲.我们的PE文件在空白区可以添加代码.但是这样是由一个弊端的.因为你的空白区节属性可能是只读的不能执行.如果你修改了属性.那么程 ...

  8. ES6 第七节 ES6中新增的数组知识(1)

    目录 ES6 第七节 ES6中新增的数组知识(1) 第七节 ES6中新增的数组知识(1) JSON数组格式转换 Array.of()方法: find()实例方法: ES6 第七节 ES6中新增的数组知 ...

  9. netbeans中给jpanl添加背景图片制定代码的理解——匿名内部类继承父类

    此测试是为了仿照在netbeans中给jpanl添加背景图片的制定代码的执行过程 在JpDemo中定义了个Car类的数据类型,但在给其赋值对象时使用了匿名内部类,继承了Car类,是其子类,并重写了父类 ...

随机推荐

  1. SpringMVC + MyBatis简单示例

    该项目基于Maven开发,该项目中包含了MyBatis自动创建表的功能,具体实现查阅MyBatis---自动创建表 源码下载 配置 maven支持pom.xml <project xmlns=& ...

  2. 阿里巴巴Java开发规约Eclipse插件安装及使用

    技术交流群:233513714 插件安装 环境:JDK1.8,Eclipse4+.有同学遇到过这样的情况,安装插件重启后,发现没有对应的菜单项,从日志上也看不到相关的异常信息,最后把JDK从1.6升级 ...

  3. idea无法新建maven项目

    之前用的都是eclipse,自从4月底入职新公司后,接触到了idea. 然后自己的电脑上也安装了idea,不过一直都没用,直到昨天打算开起来使用一下. 之后就是想新建一个maven项目,发现死活也新建 ...

  4. 《Cracking the Coding Interview》——第17章:普通题——题目11

    2014-04-29 00:00 题目:给定一个rand5()函数,能够返回0~4间的随机整数.要求实现rand7(),返回0~6之间的随机整数.该函数产生随机数必须概率相等. 解法:自己想了半天没想 ...

  5. 《Cracking the Coding Interview》——第1章:数组和字符串——题目7

    2014-03-18 01:55 题目:给定一个MxN矩阵,如果某个元素为0,则将对应的整行和整列置为0. 解法:单独挑出一行和一列作为标记数组.因为某元素为0就全部置为0,所以不论A[i][j]为0 ...

  6. leetcode 【 Remove Duplicates from Sorted List 】 python 实现

    题目: Given a sorted linked list, delete all duplicates such that each element appear only once. For e ...

  7. Canvas 图片平铺设置

    /** * 图片平铺 */ function initDemo7(){ var canvas = document.getElementById("demo7"); if (!ca ...

  8. 孤荷凌寒自学python第五十天第一次接触NoSql数据库_Firebase

    孤荷凌寒自学python第五十天第一次接触NoSql数据库_Firebase (完整学习过程屏幕记录视频地址在文末) 之前对关系型数据库的学习告一段落,虽然能力所限没有能够完全完成理想中的所有数据库操 ...

  9. cloud-init介绍及源码解读

    https://zhuanlan.zhihu.com/p/27664869 知乎大神写的  

  10. crmsh语法

    .查看配置信息 crm(live)# configure crm(live)configure# show node node1 node node2 property cib-bootstrap-o ...