免杀笔记 ---> PE

本来是想先把Shellcode Loader给更新了的,但是涉及到一些PE相关的知识,所以就先把PE给更了,后面再把Shellcode Loader 给补上。

声明:本文章内容来自于B站小甲鱼

1.PE的结构

首先我们要讲一个PE文件,就得知道它的结构,可以参考下面的这张照片

2.DOS头部

首先一个PE文件,就是它的DOS结构。 其中,需要我们去了解的,就是一开始的那个DOS标记以及我们执行的PE文件头

那么我们随便打开一个EXE来看一下。我门可以看见标志性的MZ

然后我们直接定位到3C这个位置,这里指向PE文件的头(写死的)  

可以看见在这个PE文件中,它的PE开始是在80这个位置

于是我们就去到80这个位置

3.IMAGE_NT_HEADERS

1.Signature

这个字段,是用来标志着这是一个真正的PE文件,从上面,我们跳到了这里,就能看见我们的Signature标识字段。

2.IMAGE_FILE_HEADER

这个结构如下

其中重要的,就是SizeOfOptionalHeader这个值,这个就决定了后面的IMAGE_OPTIONAL_HEADER32的大小

3.IMAGE_OPTIONAL_HEADER32

其中一些比较重要的结构

  • AddressOfEntryPoint 程序执行入口RVA  在偏移值为28的地方 

我们去那个偏移位置找一找(相对于PE头的偏移)DWORD类型 ,指向的是我们的14C

  • ImageBase

  • SectionAlignment和FileAlignment字段

其中FileAlignment默认是200,我们自己去PE文件找找是不是这么回事(它的偏移地址是3C)

而且他是DWORD类型,四个字节,我们在对应的地方确实是能看到是200!! 

  • DataDirectory(数组)

其实可以这样子理解  他定义了一个长度为16的数组,然后数组的每一个元素都是一个结构,这个结构里面都存储了两个元素,一个就是数据的起始RVA,另外一个就是数据块的长度

数组中的有些元素十分的重要(导入表,导出表,资源,重定位表,IAT表

当我们需要寻找特定的资源的时候,我们就可以去找到这个数组的第三个元素,获取到对应的RVA以及长度,当我们要查看PE文件导入了哪些DLL的API的时候,我们就可以去导入表里面获取RVA(Relative Virtual Address)和长度!!!!  

4.区块

接下来就是块表,首先他是这么一个结构

然后,我们来看name,像这种以.开头的(当然这个.不是必须的)

接下来就是相应的一些结构,比较重要一点的就是PointerToRawData 和 SizeOfRawData ,通过这两个,我们就能找到下一个块表的位置

除此,还有一个比较重要,这个标定了该区块的属性!!!

最后的判断,是通过存在的属性进行OR的操作判断的,比如我们看到它的characteristic是6000000的话,我们就知道是通过20(Code) OR 20000000(Execute) OR 40000000(Read) == (60000020)  这样就能判断这个对应的属性

对于区块,一般都有以下的类型

然后就是区块的对对齐

RVA

相对虚拟地址

目标RVA和文件偏移的计算

在处理PE文件的时候,任何的RVA必须经过文件的偏移的换算,才能用来定位并访问文件中的数据。

  1. 首先,我们要循环扫描每个区块在内存中的起始RVA,并且根据区块的大小,算出区块的结束RVA,判断目标的RVA是否落在该区块内
  2. 然后通过获取到了目标区块之后,用目标RVA减去起始的RVA,这样就得到了目标RVA相对于起始地址的偏移量RVA2
  3. 最后,根据该区块表在文件中所处的偏移地址,将这个值加上RV2,就得到了文件的偏移地址!!!

假设我们有一个虚拟地址666666,那么我们就要去区块中查找

通过定位,我们可以发现他在.reloc这个区块中

那么RVA2 = 666666 - 66000 = 666,然后我们看到这个区块在文件中的偏移地址在60E00

所以我们这个虚拟地址在物理内存中的地址就是60E00 + 666 = 61466 

5.导入表

说到导入表,我们肯定不会陌生,我们在一开始的PE头中,就讲过一个IMAGE_OPTIONAL_HEADER里面有一个特别重要的DataDirectory这个地方,里面放着我们的导入表!!!!

其中的第二个成员就是导入表,如果我们跳转到它的RVA之后,我们就能看见一个以IMAGE_IMPORT_DESCRIPTOR(简称IID)的数组开始的,每一个被加载进来的DLL文件都分别对应一个IID数组结构,当我们看到一个IID全为0的时候,就代表结束!!!!


对于每一个IID,它的结构如下:

它的长度为5个DWORD,其中重要的两个就是我们的FirstTrunk 和 OriginalFirstTrunk

6.IAT &&  IMAGE_IMPORT_BY_NAME

终于,我们学免杀要学的IAT表终于要出现了!!!!  不过在此之前,我们先来看一张图片

其中能看见IID的第一个DWORD OriginalFirstTrunk指向了INT表的IMAGE_THUNK_DATA

然后DWORD FirstThunk 指向了IAT表中的IMAGE_THUNK_DATA ,并且这两个都指向了IMAGE_IMPORT_BY_NAME这个表

其中,对于我们的IMAGE_THUNK_DATA

然后就是IMAGE_IMPORT_BY_NAME

IAT(Import Address Table)导入地址表

那么下面,我们就来举个栗子演示一下:

首先我们来找一个程序,直接看他的DataDirectory中的导入表的地址

然后定位到块中的 .idata中

我们可以追踪到之后发现它存在两个IID,即调用了两个动态连接库

并且我们去查看第一个IID的Original_First_Thunk,指向的是INT表中的IMAGE_THUNK_DATA,并且这个值是2A15C,但是这是一个RVA,所以我们要找到它的实际偏移我们用这个RVA减去.idata块的RVA 得到的RVA2再加上Raw Data offs 就是我们的实际偏移地址,2815C

然后又找到一个02A2DC ,我们在上面说过,如果开头是0的话,它的值是RVA,指向一个IMAGE_IMPORT_BY_NAME,所以,我们就还要去找282DC这个地方

这样,我们就找到了我们的真正的函数的地址(在此期间指针指向了两次),来看这么一个图(第一个盒子里面是ORIGINAL_FIRST_THUNK一开始写错了)

那么刚才我们讲了通过OriginalFirstThunk找,那么现在我们通过FirstThunk查找

首先还是找到iid中的FirstThunk,然后转换为实际偏移地址就是282AC

然后我们就去282AC,找到指向的实际偏移地址是282DC

然后再去282DC处找,发现282dc处也能找到我们的这个函数的真实位置

过程如下

然后我们去让这个程序运行起来,并且将他的内存dump出来,然后再去跟踪它的导入表

这时候我们再去跟踪IAT表,282AC这个部分。终于,我们就找到了这个函数的真正的地址

这时候,我们的IAT表就是这样的了(在内存中,IAT表不在需要通过名字索引,而是通过地址了)

然后本次的PE文件就到这了,当然了PE文件远不止这些,导入表,重定位表,资源等等,当日后在免杀中用到的时候,我们再相应进行更新。

下一篇Blog,我们就会更新对应的Shellcode Loader了!!!!

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

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

相关文章

SPI四种模式--极性与相位

SPI的四种模式:相位和极性 极性 定义时钟空闲状态: CPOL0:时钟线在空闲状态为低电平 CPOL1:时钟线在空闲状态为高电平 这个设置决定了设备不进行通信时时钟线的状态。 兼容性: 不同的SPI设备可能需要不同的时钟极性…

java.lang.classnotfoundexception jakarta.xml.bind.jaxbexception java 17问题

解决 <dependency><groupId>jakarta.xml.bind</groupId><artifactId>jakarta.xml.bind-api</artifactId><version>4.0.2</version> </dependency>参考&#xff1a; Handling NoClassDefFoundError for JAXBException in Jav…

【Linux开发实战指南】基于TCP、进程数据结构与SQL数据库:构建在线云词典系统(含注册、登录、查询、历史记录管理功能及源码分享)

目录 项目演示&#xff1a; 1. 主界面 技术讲解&#xff1a; TCP连接 进程的并发 链表 SQLite3 IO对文件的读写 功能实现 实现逻辑 我遇到的问题&#xff1a; 服务器端代码思路解析 必要条件 步骤详解 客户端代码思路解析 步骤详解 服务器源码如下&#xff1a;…

windows电脑如何运行python的定时任务

这里需要使用&#xff1a;windows系统设置-控制面板里的计划任务 1.打开计划任务之后&#xff0c;选择&#xff1a;创建基本任务 2.填写名称&#xff0c;这里根据自己具体的项目需求填写&#xff0c;然后点击下一步。 3.选择每日&#xff0c;再点击下一步 4.设置时间&…

Python 学习之常用第三方库(五)

Python 常用第三方库 Python 是一门功能强大的编程语言&#xff0c;其生态系统中包含了许多优秀的第三方库&#xff0c;这些库极大地扩展了 Python 的功能。以下是一些常用的 Python 第三方库&#xff1a; 1. NumPy&#xff1a; a. 用于数值计算的库&#xff0c;提供了大量的…

科普文:linux I/O原理、监控、和调优思路

Linux 文件系统 磁盘和文件系统的关系&#xff1a; 磁盘为系统提供了最基本的持久化存储。 文件系统则在磁盘的基础上&#xff0c;提供了一个用来管理文件的树状结构。 文件系统工作原理 索引节点和目录项 文件系统&#xff0c;本身是对存储设备上的文件&#xff0c;进行…

多维度多场景文档门户,鸿翼ECM文档云打造文档管理新范式

​在现代企业运营中&#xff0c;内容协作的效率直接影响到组织的整体表现和竞争力。传统的文档管理系统都是通过目录结构的方式进行文件管理&#xff0c;在实际业务中无法满足用户多视角、多维度、多场景的文档业务需求。因此&#xff0c;搭建结合文档体系的业务门户是许多企业…

策略模式入门:基本概念与应用

目录 策略模式策略模式结构策略模式应用场景策略模式优缺点练手题目题目描述输入描述输出描述题解 策略模式 策略模式&#xff0c;又称政策模式&#xff0c;是一种行为型设计模式&#xff0c;它能让你定义一系列算法&#xff0c;并将每种算法分别放入独立的类中&#xff0c;以…

数字研发·驱动变革 | 2024达索系统装备行业数字化研发专题研讨会成功举办

2024年6月28日&#xff0c;由百世慧举办的“数字研发驱动变革|2024达索系统装备行业数字化研发专题研讨会”在达索系统&#xff08;重庆&#xff09;智能制造创新中心成功举办。 随着全球制造业向着智能化、数字化转型&#xff0c;我国工业装备行业也面临着转型升级的压力和机遇…

Gym cuda error: invalid resource handle

gym模拟的时候&#xff0c; 出现问题&#xff1a; sim和gym的定义如下&#xff1a; from isaacgym import gymapi,gymtorch import math,random# 1. Simulation Setup gym gymapi.acquire_gym()# get default set of parameters sim_params gymapi.SimParams() sim_params.u…

网关,路由器,交换机

一、网关 (Gateway) 是一种设备&#xff0c;用于连接不同网络&#xff0c;能够转发数据包并翻译协议&#xff0c;允许不同类型的网络通信。网关通常工作在OSI模型的应用层或传输层&#xff0c;提供连接和路由服务。 应用场景例子&#xff1a; 在企业网络中&#xff0c;网关可…

四倍体和六倍体小麦抗赤霉病的比较研究

核心总结&#xff1a;四倍体和六倍体小麦抗赤霉病的比较研究 研究背景 小麦赤霉病&#xff08;Fusarium head blight, FHB&#xff09;由Fusarium graminearum引起&#xff0c;是全球范围内对小麦生产造成严重威胁的疾病。FHB感染不仅会显著降低粮食产量和质量&#xff0c;还…

2024年能在一个月内录用的EI检索会议CCPQT 2024

第三届计算、通信、感知与量子技术国际会议&#xff08;CCPQT 2024&#xff09;将于2024 年10月25日-10月27日在中国珠海召开。&#xff08;往届均已顺利见刊检索&#xff09; 会议信息 大会官网&#xff1a;http://www.ccpqt.org/ 会议地点&#xff1a;中国珠海 会议时间&…

企业多存储方式如何兼顾安全统一管理、便捷流畅访问的双向需求?

数据和文件存储是企业最基础的需求&#xff0c;常见的存储方式有磁盘存储、NAS存储、SAN存储、云存储、分布式存储、闪存存储等&#xff1b;随着企业规模的扩大、业务结构的复杂化&#xff0c;企业内部可能会同时出现多种存储方式、多个存储设备并行使用的情况。 这样的使用场景…

python之音频处理(1)语速快慢的改变

方案1&#xff1a;使用pydub 处理 from pydub import AudioSegment sound AudioSegment.from_file(r"D:\websiteDownload\我今天被一件事情搞得很烦.wav") print(sound.duration_seconds) rate 0.75 sound_with_altered_frame_rate sound._spawn(sound.raw_data,…

【启明智显技术分享】Model3C芯片电阻屏RTP配置、调试与测试指南

一、背景 本指南将详细介绍启明智显的Model3C芯片电阻屏RTP配置、调试与测试指南。无论您是电子爱好者、开发者还是工程师&#xff0c;这份指南都能助您快速上手并充分利用这款触摸屏的各项功能。 二、芯片介绍 Model3C是一款基于RISC-V的高性能、国产自主、工业级高清显示与…

java通过jts获取点在线段中的位置

在Java中&#xff0c;可以使用JTS&#xff08;Java Topology Suite&#xff09;库来获取点在线段的垂足点位置。以下是一个简单的示例代码&#xff0c;展示了如何使用JTS获取点到线段的垂足点位置&#xff1a; 首先&#xff0c;确保你的项目中包含了JTS库。 import org.locati…

面试篇-系统设计题总结

这里记录一些有趣的系统设计类的题目&#xff0c;一般大家比较喜欢出的设计类面试题目会和高可用系统相关比如秒杀和抢红包等。欢迎大家在评论中评论自己遇到的题目&#xff0c;本篇文章会持续更新。 1、设计一个抢红包系统 抢红包系统其实也是秒杀类中的一个场景&#xff0…

深度学习中的反向传播算法的原理

深度学习中的反向传播算法的原理&#xff0c;以及如何计算梯度 反向传播算法&#xff08;Backpropagation&#xff09;是深度学习中最核心的优化技术之一&#xff0c;用于训练神经网络。它基于链式法则&#xff0c;通过从输出层逆向计算误差并逐层传递到输入层来更新模型参数&…

类的动态加载-双亲委派模型

java反射基础 Java 基础 - 反射机制详解 | Java 全栈知识体系 (pdai.tech) 类的动态加载 参考链接&#xff1a;类的动态加载 构造是和实例化也就是对象相关的。 静态代码块是在初始化的时候就调用的 Class.forName();就会调用静态代码块 forName&#xff0c;加载类时默认…