2.11 PE结构:添加新的节区

news2024/11/28 12:39:05

在可执行PE文件中,节(section)是文件的组成部分之一,用于存储特定类型的数据。每个节都具有特定的作用和属性,通常来说一个正常的程序在被编译器创建后会生成一些固定的节,通过将数据组织在不同的节中,可执行文件可以更好地管理和区分不同类型的数据,并为运行时提供必要的信息和功能。节的作用是对可执行文件进行有效的分段和管理,以便操作系统和加载器可以正确加载和执行程序。

可执行文件常用的节包括了:

节名作用功能说明权限
.text代码节包含可执行代码,例如程序的指令和函数体执行和读取
.data数据节包含程序的全局和静态变量的初始化数据。读取和写入
.rdata只读数据节包含只读的静态数据,如常量字符串和只读的全局变量。只读
.idata导入表节包含程序所依赖的外部函数和符号的引用信息,用于动态链接。读取和写入
.edata导出表节包含程序导出的函数和符号的信息,用于供其他程序或模块使用。读取
.rsrc资源节包含程序所使用的资源数据,如图标、位图、字符串等。读取
.reloc重定位节包含程序的重定位信息,用于在加载时修正代码和数据的内存地址。读取和写入

当然了并不是每一个标准的PE文件都具备这些节,某些程序可能会使用特殊的PE编辑工具新增一些特殊的节,或者当程序被加密压缩后该程序的节区也会发生不同的变化,对于新增节来说需要具备如下几个关键步骤:

  • 计算新节的偏移量和大小:确定要添加的新节的偏移量和大小。偏移量是新节在文件中的位置,大小是新节的长度。
  • 更新PE文件头:修改PE文件头中的相关字段,更新文件头中的NumberOfSections字段和SizeOfImage字段。
  • 创建新节:在PE文件末尾添加新的节表项,并填充新节的各个字段,例如名称、虚拟大小、文件大小、内存对齐等。

对于操作PE文件来说,在头文件中需要引入ImageHlp.h并且包含#pragma comment(lib,"Imagehlp.lib")库,该库提供了用于处理PE文件的函数和结构体,是Image Help Library库的一部分,读者可自行在项目内引入这个库。

当引入后我们来实现第一个功能,为可执行文件分配空间,如下AllocateSpace函数,该函数通过使用CreateFileA打开一个文件,并调用SetFilePointer将文件指针移动到FILE_END文件末尾处,接着通过循环的方式WriteFile填充开辟空间。

// 计算取整
DWORD AlignSize(int nSecSize, DWORD Alignment)
{
  int nSize = nSecSize;
  if (nSize %Alignment != 0)
  {
    nSecSize = (nSize / Alignment + 1) * Alignment;
  }
  return nSecSize;
}

// 为可执行文件分配空间
DWORD AllocateSpace(char *FileName, int FileSize)
{
  HANDLE hFile = CreateFileA(FileName, GENERIC_READ | GENERIC_WRITE, FILE_SHARE_WRITE |
    FILE_SHARE_READ, NULL, OPEN_ALWAYS, NULL, NULL);

  DWORD ret = SetFilePointer(hFile, 0, 0, FILE_END);
  if (ret != NULL)
  {
    for (int x = 0; x < FileSize; x++)
    {
      WriteFile(hFile, "", 1, 0, 0);
    }
    CloseHandle(hFile);
  }
  return ret;
}

上述程序的使用方法很简单,通过AllocateSpace("d://lyshark.exe",4096)传入两个参数,分别是需要开辟空间的进程,以及开辟空间的长度,该长度可以与节区内的大小保持一致,当程序执行后则返回开辟位置,读者可使用WinHex工具跳转到程序末尾自行查看,如下图所示;

接着我们来实现添加节区功能,如下代码ImplantSection则可实现增加新节功能,该函数传入三个参数,分别是可执行文件地址,节区名称,以及节区长度,程序中通过映射方式打开文件,分别寻找到当前节表首地址,以及节的数量,通过复制一个节,并对该节内存参数进行更新(节内存大小,节文件大小,节内存属性)等,当这些数据被更正后,则加下来就是保存文件,并返回pTmpSec->PointerToRawData节所在文件地址。

// 计算取整
DWORD AlignSize(int nSecSize, DWORD Alignment)
{
  int nSize = nSecSize;
  if (nSize %Alignment != 0)
  {
    nSecSize = (nSize / Alignment + 1) * Alignment;
  }
  return nSecSize;
}

// 添加新的节区 szFileName = 打开exe文件 szSecName = 节名称 nSecSize = 节大小
DWORD ImplantSection(LPSTR szFileName, char szSecName[8], int nSecSize)
{
  HANDLE m_hFile = CreateFileA(szFileName, GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ,
    NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);

  HANDLE m_hMap = CreateFileMapping(m_hFile, NULL, PAGE_READWRITE, 0, 0, 0);
  HANDLE m_lpBase = MapViewOfFile(m_hMap, FILE_MAP_READ | FILE_SHARE_WRITE, 0, 0, 0);

  // ------------------------------------------------------------------------
  // 定位到DOS/NT头部
  // ------------------------------------------------------------------------
  // 定位DOS头
  PIMAGE_DOS_HEADER m_pDosHdr = (PIMAGE_DOS_HEADER)m_lpBase;
  printf("[-] 当前DOS头: 0x%08X \n", m_pDosHdr);
  // 定位NT头
  PIMAGE_NT_HEADERS m_pNtHdr = (PIMAGE_NT_HEADERS)((DWORD)m_lpBase + m_pDosHdr->e_lfanew);
  printf("[-] 当前NT头: 0x%08X \n", m_pNtHdr);
  // 定位节表首地址
  PIMAGE_SECTION_HEADER m_pSecHdr = (PIMAGE_SECTION_HEADER)((DWORD)&(m_pNtHdr->OptionalHeader) +
    m_pNtHdr->FileHeader.SizeOfOptionalHeader);
  printf("[-] 定位当前节表首地址: 0x%08X \n", m_pSecHdr);
  // 定位节区数量
  int nSecNum = m_pNtHdr->FileHeader.NumberOfSections;
  DWORD dwFileAlignment = m_pNtHdr->OptionalHeader.FileAlignment;
  DWORD dwSecAlignment = m_pNtHdr->OptionalHeader.SectionAlignment;
  PIMAGE_SECTION_HEADER pTmpSec = m_pSecHdr + nSecNum;

  // 复制节名
  strncpy((char *)pTmpSec->Name, szSecName, 7);
  printf("[+] 拷贝节名称: %s \n", szSecName);

  // ------------------------------------------------------------------------
  // 节的内存大小
  // ------------------------------------------------------------------------
  pTmpSec->Misc.VirtualSize = AlignSize(nSecSize, dwSecAlignment);
  printf("[+] 节表内存大小: %d \n", nSecSize);
  // 节的内存起始位置
  pTmpSec->VirtualAddress = m_pSecHdr[nSecNum - 1].VirtualAddress +
    AlignSize(m_pSecHdr[nSecNum - 1].Misc.VirtualSize, dwSecAlignment);
  printf("[+] 节内存起始位置: 0x%08X \n", pTmpSec->VirtualAddress);

  // ------------------------------------------------------------------------
  // 节的文件大小
  // ------------------------------------------------------------------------
  pTmpSec->SizeOfRawData = AlignSize(nSecSize, dwFileAlignment);
  printf("[-] 节的文件大小: %d \n", pTmpSec->SizeOfRawData);

  // 节的文件起始位置,这里直接在文件末尾分配空间
  pTmpSec->PointerToRawData = SetFilePointer(m_hFile, 0, 0, FILE_END);
  printf("[-] 节的文件起始位置: 0x%08X \n", pTmpSec->PointerToRawData);
  // 这里开始循环在文件末尾分配nSecSize存储空间
  for (int x = 0; x < nSecSize; x++)
    WriteFile(m_hFile, "", 1, 0, 0);

  // ------------------------------------------------------------------------
  // 节访问属性,设置内存属性为可读可执行代码段
  // ------------------------------------------------------------------------
  pTmpSec->Characteristics = 0xE0000020;
  // 修正节区数量
  m_pNtHdr->FileHeader.NumberOfSections++;
  // 修正映像大小
  m_pNtHdr->OptionalHeader.SizeOfImage += pTmpSec->Misc.VirtualSize;
  FlushViewOfFile(m_lpBase, 0);
  
  return pTmpSec->PointerToRawData;
}

读者可自行调用上述函数,通过ImplantSection("d://Win32Project.exe", ".hack", 4096)传值,此时分别传入参数为需要修改的文件名,需要增加的节名称,以及创建节长度,在运行后读者可自行观察是否创建成功,如下图所示;

本文作者: 王瑞
本文链接: https://www.lyshark.com/post/19540578.html
版权声明: 本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/992410.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

微信小程序接入隐私弹窗说明及详细过程

相信各位做小程序的小伙伴在微信小程序后台应该都接到了官方通知的小程序隐私新规&#xff0c;如果还未收到的小程序可以看一下&#xff1a; 为规范开发者的用户个人信息处理行为&#xff0c;保障用户合法权益&#xff0c;自2023年9月15日起&#xff0c;对于涉及处理用户个人信…

OpenCV 09(形态学)

一、形态学 形态学指一系列处理图像 形状特征 的图像处理技术. 形态学的基本思想是利用一种特殊的结构元(本质上就是卷积核)来测量或提取输入图像中相应的形状或特征&#xff0c;以便进一步进行图像分析和目标识别。这些处理方法基本是对二进制图像进行处理, 即黑白图像卷积核…

JUC编程中锁引发的“见解”

JUC编程中锁引发的“见解” 一大早就在想锁是干嘛的&#xff1f;什么情况下要用锁&#xff1f;想了很多&#xff0c;下面的所有表述都是就是我的思考流程&#xff0c;欢迎所有人一起讨论、更正。 文章目录 JUC编程中锁引发的“见解”1、什么是JUC编程?2、JUC编程中什么情况下需…

C/C++之链表的建立

个人主页&#xff1a;点我进入主页 专栏分类&#xff1a;C语言初阶 C语言程序设计————KTV C语言小游戏 C语言进阶 C语言刷题 欢迎大家点赞&#xff0c;评论&#xff0c;收藏。 一起努力&#xff0c;一起奔赴大厂。 目录 1.头插 1.1简介 1.2代码实现头插 …

二维数组前缀和(JAVA)

力扣&#xff08;LeetCode&#xff09;官网 - 全球极客挚爱的技术成长平台 暴力 双层for循环&#xff0c;遍历子矩阵。 前缀和算法&#xff1a; class NumMatrix {private int sum[][];private int matrix[][];public NumMatrix(int[][] matrix) {this.matrixmatrix;int row…

AI 帮我写代码——Amazon CodeWhisperer 初体验

文章作者&#xff1a;游凯超 人工智能的突破和变革正在深刻地改变我们的生活。从智能手机到自动驾驶汽车&#xff0c;AI 的应用已经深入到我们生活的方方面面。而在编程领域&#xff0c;AI 的崭新尝试正在开启一场革命。Amazon CodeWhisperer&#xff0c;作为亚马逊云科技的一款…

【高德地图】 覆盖物/画点/画折线/画多边形/画矩形/画圆

官方示例 https://lbs.amap.com/demo/javascript-api/example/mouse-operate-map/mouse-draw-overlayers <!doctype html> <html lang"en"><head><meta charset"utf-8"><meta http-equiv"X-UA-Compatible" content…

07_瑞萨GUI(LVGL)移植实战教程之LVGL对接EC11旋转编码器驱动

本系列教程配套出有视频教程&#xff0c;观看地址&#xff1a;https://www.bilibili.com/video/BV1gV4y1e7Sg 7. LVGL对接EC11旋转编码器驱动 本次实验我们向LVGL库中对接EC11旋转编码器驱动&#xff0c;让我们能通过EC11旋转编码器操作UI。 7.1 复制工程 上次实验得出的工…

一文读懂Swin-Transformer

系列文章目录 记录CV领域大模型的学习历程&#xff0c;欢迎大家一起讨论&#xff0c;互相学习。 ViT,DETR(一),DETR(二)DETR(三) 文章目录 系列文章目录前言一、整体框架1.Patch Embedding2.Patch Merging3.Swin Transformer Block3.1 Window Partition/Reverse3.2 Window-MSA…

C#__文件操作之FileInfo和DirectoryInfo

// 代码&#xff08;含注释&#xff09; class Program{static void Main(string[] args){// FileInfo 文件操作FileInfo myFile new FileInfo("D:\C#编程\文件操作之FileInfo和DirectoryInfo\TextFile1.txt");// 实例方法// myFile.CopyTo("D:\C#编程\文件操作…

空中跳一跳

欢迎来到程序小院 空中跳一跳 玩法&#xff1a; 跳一跳长按鼠标左键&#xff0c;松开鼠标进行跳跃&#xff0c;跳到下一个格子中&#xff0c;进行分数统计&#xff0c;三次生命机会&#xff0c;格子中也会有爱心出现&#xff0c;吃掉安心增加一次生命哦^^。开始游戏https://ww…

第19章 并发与竞争实验(iTOP-RK3568开发板驱动开发指南 )

在前面章节的学习中&#xff0c;相信大家已经对用户空间与内核空间数据传递进行了实验&#xff0c;假如要传递的数据被存放在了全局变量&#xff0c;该数据就可以作为共享资源被多个任务共同读写&#xff0c;从而造成数据的错误传输&#xff0c;多个程序同时访问一个共享资源产…

取个好名,是一生中极为重要之事

我们每十年一大运&#xff0c;五年一小运。每交次大运时&#xff0c;就会改变一次你身边的一切环境。每个大运&#xff0c;都会把你带入不同的风景&#xff0c;人生想要须尽欢&#xff0c;就不要太在意外在的一切&#xff0c;永远向内求。有志同道合的人就一起上路&#xff0c;…

《Tree of Thoughts: Deliberate Problem Solving with Large Language Models》中文翻译

《Tree of Thoughts: Deliberate Problem Solving with Large Language Models》- 思维树&#xff1a;用大型语言模型有意识地解决问题 论文信息摘要1. 介绍2. 背景3. 思想树&#xff1a;用 LM 有意识地解决问题4. 实验4.1 24 人游戏4.2 创意写作4.3 迷你填字游戏 5. 相关工作6…

语音芯片NRK3302 在按摩仪上的应用

在当今生活节奏快&#xff0c;生活压力大的现代社会。按摩仪已逐渐成为人们生活中不可或缺的日常用品&#xff0c;人们需要一个能够随时放松身体的工具。智能按摩仪应运而生&#xff0c;在按摩仪中加入语音芯片&#xff0c;让按摩仪变得更加智能&#xff0c;使用起来更加便利化…

私有云不是真正的云计算!

大数据产业创新服务媒体 ——聚焦数据 改变商业 中国云计算遇到困境&#xff0c;IaaS层面&#xff0c;阿里云、腾讯云等增长乏力&#xff1b;SaaS没有发展起来。反观美国&#xff0c;整个云计算蓬勃发展&#xff0c;AWS、微软云、谷歌云体量更大&#xff0c;增速却不低&#x…

YOLO目标检测——工地安全帽识别检测数据集+已标注yolo格式标签下载分享

实际项目应用&#xff1a;目标检测工地安全帽识别检测数据集在工地安全监测、工地管理、安全培训和教育、违规检测和预警以及安全统计和分析等领域都有着广泛的应用。通过准确识别和检测工人是否佩戴安全帽&#xff0c;可以帮助提高工地的安全性和管理效率&#xff0c;减少事故…

通过finalshell快速在ubuntu上安装jdk1.8

这篇文章主要介绍一下怎么通过finalshell连接ubuntu&#xff0c;然后在ubuntu上安装jdk1.8&#xff0c;让不熟悉linux操作系统的童鞋也能快速地完成安装。 目录 一、准备一台虚拟机 二、安装finalshell远程连接工具 三、获取ubuntu虚拟机的ip地址 四、通过finalshell连接u…

Spring以及SpringBoot/SpringCloud注解

一、SpringBoot/Spring 1、SpringBootApplication 包含Configuration、EnableAutoConfiguration、ComponentScan通常在主类上 其中ComponentScan让Spring Boot扫描到Configuration类并把它加入到程序上下文&#xff0c;如果扫描到有Component Controller Service等这些注解的…

vscode配置conda环境

vscode配置conda环境 写在最前面安装vscodeanaconda3 配置vscode中文vscode配置anaconda环境步骤 新建.ipynb项目 写在最前面 之前一直是jupyter notebookpycharm 帮朋友配置环境的时候发现&#xff1a;vscode结合了cell自动补齐&#xff0c;狠狠心动了 于是安装配置vscode 参…