在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.(该块可写)]

-----------------------------------------------------------------------------------------------------

  1. // mem.cpp : 定义控制台应用程序的入口点。
  2. //PE文件从文件加载到内存,再从内存读取,然后存盘到文件
  3.  
  4. #include "stdafx.h"
  5. #include <windows.h>
  6. #include <winnt.h>
  7.  
  8. //#define PATH "C:\\Windows\\System32\\notepad.exe"
  9. #define PATH "C:\\Users\\Administrator\\Desktop\\ipmsg.exe"
  10. #define MsgADD 0x75cffde6
  11. char Shellcode[] =
  12. {
  13. 0x6A, 0x00, 0x6A, 0x00, 0x6A, 0x00, 0x6A, 0x00,
  14. 0xE8, 0x00, 0x00, 0x00, 0x00,
  15. 0xE9, 0x00, 0x00, 0x00, 0x00
  16. };
  17.  
  18. int Filelength(FILE *fp);
  19. int _tmain(int argc, _TCHAR* argv[])
  20. {
  21. FILE *Fp;
  22. fopen_s(&Fp, PATH, "rb");
  23. int FileSize = Filelength(Fp);//获取文件大小
  24. char * FileBuffer = (char *)malloc(FileSize);//申请存放文件的内存空间
  25. if (FileBuffer == NULL)
  26. {
  27. printf("申请iImageBuffer失败");
  28. }
  29. fread_s(FileBuffer, FileSize, 1, FileSize, Fp); //将文件复制到内存中
  30. //定位一下内存中的数据 各个头表
  31. //定位标准PE头
  32. PIMAGE_FILE_HEADER MyFileHeader;
  33. MyFileHeader = (PIMAGE_FILE_HEADER)(char *)(FileBuffer + *(int *)(FileBuffer + 0x3c) + 0x4);
  34. //定位可选PE头
  35. PIMAGE_OPTIONAL_HEADER MyOptionalHeader;
  36. MyOptionalHeader = (PIMAGE_OPTIONAL_HEADER)((char *)MyFileHeader + 0x14);
  37. //定位节表
  38. PIMAGE_SECTION_HEADER MySectionHeader;
  39. MySectionHeader = (PIMAGE_SECTION_HEADER)((char *)MyOptionalHeader + MyFileHeader->SizeOfOptionalHeader);
  40.  
  41. //拉伸,也就是读到内存中的状态
  42. char * ImageBuffer = (char *)malloc(MyOptionalHeader->SizeOfImage+0x1000);//给拉伸申请内存空间
  43. ZeroMemory(ImageBuffer, MyOptionalHeader->SizeOfImage+0x1000);
  44.  
  45. if (ImageBuffer == NULL)
  46. {
  47. printf("申请iImageBuffer失败");
  48. }
  49. memcpy(ImageBuffer, FileBuffer, MyOptionalHeader->SizeOfHeaders);
  50.  
  51. for (int i = 0; i < MyFileHeader->NumberOfSections; i++)
  52. {
  53. memcpy(ImageBuffer + MySectionHeader->VirtualAddress, FileBuffer + MySectionHeader->PointerToRawData, MySectionHeader->SizeOfRawData);//
  54. MySectionHeader++;
  55. }
  56. //新增节开始
  57. PIMAGE_SECTION_HEADER AddSectionHeader;
  58. AddSectionHeader = MySectionHeader;
  59. MySectionHeader--;
  60. //AddSectionHeader->Name = "cyp";
  61. //AddSectionHeader->Name = { 0 };
  62. AddSectionHeader->Name[0] = '.'; AddSectionHeader->Name[1] = 'c'; AddSectionHeader->Name[2] = 'y'; AddSectionHeader->Name[3] = 'p';
  63. AddSectionHeader->Misc.VirtualSize = 0x1000;
  64. AddSectionHeader->VirtualAddress = MySectionHeader->VirtualAddress + MySectionHeader->SizeOfRawData;
  65. AddSectionHeader->SizeOfRawData = 0x1000;
  66. AddSectionHeader->PointerToRawData = MySectionHeader->PointerToRawData + MySectionHeader->SizeOfRawData;
  67. int x = (MySectionHeader - (MyFileHeader->NumberOfSections-1))->Characteristics;
  68. AddSectionHeader->Characteristics = x;
  69. MyFileHeader->NumberOfSections += 1;
  70. MyOptionalHeader->SizeOfImage + 0x1000;
  71. //新增节结束
  72.  
  73. //添加代码到PE中
  74. MyFileHeader = (PIMAGE_FILE_HEADER)(char *)(ImageBuffer + *(int *)(ImageBuffer + 0x3c) + 0x4);
  75. MyOptionalHeader = (PIMAGE_OPTIONAL_HEADER)((char *)MyFileHeader + 0x14);
  76. MySectionHeader = (PIMAGE_SECTION_HEADER)((char *)MyOptionalHeader + MyFileHeader->SizeOfOptionalHeader);//重新指一下,前面动过了
  77.  
  78. //E8后面的硬编码地址 =真正要到的地址 - E8的下一行或E8本行 +0x5
  79. char *CodeAdd = ImageBuffer + MySectionHeader->VirtualAddress + MySectionHeader->Misc.VirtualSize;//为要增加的代码确定位置
  80. memcpy(CodeAdd, Shellcode, sizeof(Shellcode));//把硬编码复制到指定位置
  81. int CallAdd = MsgADD - (MyOptionalHeader->ImageBase + ((int)(CodeAdd + 0xd) - (int)ImageBuffer));
  82. *(int *)(CodeAdd + 0x9) = CallAdd;//定位CALL函数位置
  83. int JmpAdd = MyOptionalHeader->ImageBase + MyOptionalHeader->AddressOfEntryPoint - (MyOptionalHeader->ImageBase + (CodeAdd + 0xd - ImageBuffer));//前面是真正要跳的地址 后面括号是下一条指令的地址
  84. *(int *)(CodeAdd + 0xe) = JmpAdd;//定位JMP 跳回位置,也就是修改程序入口
  85. MyOptionalHeader->AddressOfEntryPoint = CodeAdd - ImageBuffer;//重新定位程序入口处
  86.  
  87. //添加代码到PE结束
  88.  
  89. //压缩,为存盘做准备
  90. char *NewBuffer = (char *)malloc(FileSize+0x1000);//给压缩申请内存空间
  91. if (NewBuffer == NULL)
  92. {
  93. printf("申请iImageBuffer失败");
  94. }
  95. memcpy(NewBuffer, ImageBuffer, MyOptionalHeader->SizeOfHeaders);
  96. MySectionHeader = (PIMAGE_SECTION_HEADER)((char *)MyOptionalHeader + MyFileHeader->SizeOfOptionalHeader);//重新指一下,前面动过了
  97.  
  98. for (int i = 0; i < MyFileHeader->NumberOfSections; i++)
  99. {
  100. memcpy(NewBuffer + MySectionHeader->PointerToRawData, ImageBuffer + MySectionHeader->VirtualAddress, MySectionHeader->SizeOfRawData);
  101. MySectionHeader++;
  102. }
  103. FILE *nFp;
  104. fopen_s(&nFp, "C:\\Users\\Administrator\\Desktop\\CYP.exe", "wb");
  105. fwrite(NewBuffer, FileSize, 1, nFp);
  106.  
  107. //getchar();
  108. fclose(nFp);
  109. free(FileBuffer);
  110. free(ImageBuffer);
  111. free(NewBuffer);
  112. return 0;
  113. }
  114.  
  115. //获取文件大小
  116.  
  117. int Filelength(FILE *fp)
  118. {
  119. int num;
  120. fseek(fp, 0, SEEK_END);
  121. num = ftell(fp);
  122. fseek(fp, 0, SEEK_SET);
  123. return num;
  124. }

在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. PHP代码审计4-漏洞挖掘思路

    漏洞挖掘思路 漏洞形成的条件 1.变量可控制 2.变量可到达有利用价值的函数(危险函数) 漏洞造成的效果 漏洞的利用效果取决于最终的函数功能,变量进入什么样的函数就导致什么样的效果 危险函数 文件包含 ...

  2. 14,flask-sqlalchemy项目配置

    基于一个flask项目,加入flask-SQLAlchemy 1.加入falsk-sqlalchemy第三方组件 from flask import Flask # 导入Flask-SQLAlchem ...

  3. Javacript实现倒计时

    <!DOCTYPE html><html lang="en"><head> <meta charset="UTF-8" ...

  4. Maven学习 (五) Elipse中发布一个Maven项目到Tomcat

    对于maven初学者的我,经常遇到一个问题就是,maven项目创建成功后,本来已经添加了jar的依赖,但是发布到Tomcat中就是没有jar包存在, 启动Tomcat总是报没有找到jar包,可项目结构 ...

  5. [转]ANDROID JNI之JAVA域与c域的互操作

    本文讲述AndroidJava域与C域互操作:Java域调用c域的函数:c域访问Java域的属性和方法:c域生成的对象的保存与使用.重点讲解c域如何访问Java域. 虽然AndroidJNI实现中,c ...

  6. 剑指Offer - 九度1372 - 最大子向量和(连续子数组的最大和)

    剑指Offer - 九度1372 - 最大子向量和(连续子数组的最大和)2013-11-23 16:25 题目描述: HZ偶尔会拿些专业问题来忽悠那些非计算机专业的同学.今天JOBDU测试组开完会后, ...

  7. 《Cracking the Coding Interview》——第12章:测试——题目1

    2014-04-24 23:10 题目:找出下面代码里的错误. 解法:请看下面. 代码: // 12.1 What's wrong with the following code segment? # ...

  8. 【Python】Python PYQT4 GUI编程与exe打包

    本篇文章承接http://www.cnblogs.com/zhang-zhi/p/7646923.html#3807385,上篇文章描述了对文本文件的简单处理,本章节结合PYQT4实现该功能的GUI图 ...

  9. SOA与WCF

    背景: 高校平台马上就要进入编程阶段了,对于没怎么做过正式项目的我们来说,要学的东西实在太多了.一下子面对这么多学习资料时,我们也不能着急,还是踏踏实实,一个一个地去了解,其实他们都没那么神秘.这篇博 ...

  10. sql优化(转)

    explain +sql分析sql语句执行效率 1.对查询进行优化,应尽量避免全表扫描,首先应考虑在 where 及 order by 涉及的列上建立索引. 2.应尽量避免在 where 子句中使用! ...