PE文件结构2(实现PE文件载入)
现在我们已经学完了PE文件格式,但是尚还停留在纸上谈兵的阶段,作为Windows系统上的可执行文件格式,PE文件结构总是和结构体,指针等紧密联系在一起的。理解它的最好方法就是通过写一个类似LordPE的程序来帮助我们理解PE文件结构的底层实现逻辑。计算机到底是如何实现对于PE文件结构的读取和分析的,到底是怎么找到每一个数据的地址的,这是为我们今天研究的关键。
问题关键
1.如何读取导入文件
2.如何找到每个结构体的地址
3.熟悉PE文件结构对应的结构体(参考PE文件结构1)
一. 如何读取文件
首先通过CreatFileA函数打开文件;然后通过HeapAlloc函数分配空间;最后经过ReadFile函数读取文件内容至指定空间。这几个与文件有关的WindowsAPI函数是我们处理PE文件的关键。
二. 找到每个关键结构体的指针
在PE文件结构1当中已经介绍了,PE文件结构的每个组成部分都有其对应的结构体,那么只要我们熟悉了结构体的组成然后找到每个结构体对应的指针,那么问题也就解决了。
现在依次介绍每个部分对应指针应该如何寻址:
DOS首部:dosHeader = (PIMAGE_DOS_HEADER)lpBuffer;这里的lpBuffer其实就是文件的起始句柄了,PE文件是从DOS首部开始的,所以只要将起始句柄类型转化一下为对应的指针即可。
PE文件首部:ntHeader = (PIMAGE_NT_HEADERS)(lpBuffer + dosHeader->e_lfanew);这里就是一个RVA和VA的概念了,相对于文件起始地址为RVA也就是dosHeader->e_lfanew,加上文件的起始地址后才是我们可以用来寻址的指针。
ntHeader->FileHeader.Machine;
ntHeader->OptionalHeader.Magic;
由于PE文件首部内部还包含了两个结构体,这里举两个例子。
区块首部:imageSectionHeaderStruct = (PIMAGE_SECTION_HEADER)((DWORD)lpBuffer + dosHeader->e_lfanew + sizeof(IMAGE_NT_HEADERS32));要找到区块表的首部地址就需要先找到PE文件首部地址再加上PE文件首部大小,即为对应的区块首部地址。
由于节块的数目是不一定的,需要通过循环将其依次打印。
for (int i = 0; i < numSections; i++)
{
printf("SECTION HEADER #%d\n", i);
printf("\t%s\n", imageSectionHeaderStruct->Name);
printf("\t\tVirtual Size: 0x%x\n", imageSectionHeaderStruct->Misc.VirtualSize);
printf("\t\tVirtual Address: 0x%x\n", imageSectionHeaderStruct->VirtualAddress);
printf("\t\tRaw Size: 0x%x\n", imageSectionHeaderStruct->SizeOfRawData);
printf("\t\tRaw Address: 0x%x\n", imageSectionHeaderStruct->PointerToRawData);
printf("\t\tReloc Address: 0x%x\n", imageSectionHeaderStruct->PointerToRelocations);
printf("\t\tRelocations Number: 0x%x\n", imageSectionHeaderStruct->NumberOfRelocations);
printf("\t\tLine Numbers: 0x%x\n", imageSectionHeaderStruct->NumberOfLinenumbers);
printf("\t\tCharacteristics: 0x%x\n", imageSectionHeaderStruct->Characteristics);
imageSectionHeaderStruct++;
}
三. 导入表等的打印
导入表,导出表和资源表相对来说就比较麻烦一点,需要先在数据目录表当中寻找对应地址,然后再去数据段找到相应数据打印。
这里以导入表为例:
IMAGE_IMPORT_DESCRIPTOR* ImportTables = (IMAGE_IMPORT_DESCRIPTOR)(RTF(rvaaddr) + pBegin); 这里我们先找到导入表的数据目录表对应的地址。 2. 然后找到对应的IAT地址,即int firstthunk = (int)ImportTables2->FirstThunkl;```这就是我们需要找的地址,之后依次打印即可。
感兴趣的可以查看https://github.com/FULLSHADE/pe-Parser。
PE文件结构2(实现PE文件载入)的更多相关文章
- PE文件结构详解(一)基本概念
PE(Portable Execute) 文件是Windows下可执行文件的总称,常见的有DLL,EXE,OCX,SYS等,事实上,一个文件是否是PE文件与其扩展名无关,PE文件可以是任 何扩展名.那 ...
- 再探.NET的PE文件结构(安全篇)
一.开篇 首先写在前面,这篇文章源于个人的研究和探索,由于.NET有自己的反射机制,可以清楚的将源码反射出来,这样你的软件就很容易被破解,当然这篇文章不会说怎么样保护你的软件不被破解,相反是借用一个软 ...
- PE文件结构(四) 输出表
PE文件结构(四) 參考 书:<加密与解密> 视频:小甲鱼 解密系列 视频 输出表 一般来说输出表存在于dll中.输出表提供了 文件里函数的名字跟这些函数的地址, PE装载器通过输出表来改 ...
- PE文件结构(五岁以下儿童)基地搬迁
PE文件结构(五岁以下儿童) 參考 书:<加密与解密> 视频:小甲鱼 解密系列 视频 基址重定位 链接器生成一个PE文件时,它会如果程序被装入时使用的默认ImageBase基地址(VC默认 ...
- COFF/PE文件结构
COFF/PE文件结构 原创 C++应用程序在Windows下的编译.链接(二)COFF/PE文件结构 2.1概述 在windows操作系统下,可执行文件的存储格式是PE格式:在Linux操作系统下, ...
- PE文件结构及其加载机制
一.PE文件结构 PE即Portable Executable,是win32环境自身所带的执行体文件格式,其部分特性继承自Unix的COFF(Common Object File Format)文件格 ...
- PE文件结构(三) 输入表
PE文件结构(三) 參考 书:<加密与解密> 视频:小甲鱼 解密系列 视频 输入表 输入函数,表示被程序调用可是它的代码不在程序代码中的,而在dll中的函数.对于这些函数.磁盘上的可执行文 ...
- 原创 C++应用程序在Windows下的编译、链接:第二部分COFF/PE文件结构
2.1概述 在windows操作系统下,可执行文件的存储格式是PE格式:在Linux操作系统下,可执行文件的存储格式的WLF格式.它们都是COFF格式文件的变种,都是从COFF格式的文件演化而来的. ...
- PE文件结构学习
PE:Portable Executable File Format(可移植的执行体).Windows平台主流可执行文件格式..exe与.dll文件都是PE格式.32位的叫做PE32,64位的叫做PE ...
- PE文件结构详解(六)重定位
前面两篇 PE文件结构详解(四)PE导入表 和 PE文件结构详解(五)延迟导入表 介绍了PE文件中比较常用的两种导入方式,不知道大家有没有注意到,在调用导入函数时系统生成的代码是像下面这样的: 在这里 ...
随机推荐
- 2023-01-06:给定一个只由小写字母组成的字符串str,长度为N, 给定一个只由0、1组成的数组arr,长度为N, arr[i] == 0表示str中i位置的字符不许修改, arr[i] ==
2023-01-06:给定一个只由小写字母组成的字符串str,长度为N, 给定一个只由0.1组成的数组arr,长度为N, arr[i]等于 0 表示str中i位置的字符不许修改, arr[i] 等于 ...
- 2022-07-30:以下go语言代码输出什么?A:[]byte{} []byte;B:[]byte{} []uint8;C:[]uint8{} []byte;D:[]uin8{} []uint8。
2022-07-30:以下go语言代码输出什么?A:[]byte{} []byte:B:[]byte{} []uint8:C:[]uint8{} []byte:D:[]uin8{} []uint8. ...
- 2021-08-28:给定一个正数数组arr,长度一定大于6(>=7),一定要选3个数字做分割点,从而分出4个部分,并且每部分都有数,分割点的数字直接删除,不属于任何4个部分中的任何一个。 返回有没有
2021-08-28:给定一个正数数组arr,长度一定大于6(>=7),一定要选3个数字做分割点,从而分出4个部分,并且每部分都有数,分割点的数字直接删除,不属于任何4个部分中的任何一个. 返回 ...
- Module not found: Error: Can't resolve 'axios' in 'D:\BaiduSyncdisk\vue-cli-project\dc_vue3\src\utils'
Module not found: Error: Can't resolve 'axios' in 'D:\BaiduSyncdisk\vue-cli-project\dc_vue3\src\util ...
- 《数据结构(C语言版)》严蔚敏代码实现———链表
一.前言 哈喽,大家好~我是熊子q,我又来了! 他来了他来了,他带着代码过来了! 今天要分享的代码是链表!快快搬着小板凳! 二.代码 严奶奶的书中预定义了一些预定义常量和类型,大家可以 新建一个y.h ...
- ubuntu18 安装单机k8s v1.18.2
背景 当我们需要对k8s进行二次开发时,k8s环境是必须的,那么在ubuntu上部署单机k8s是最方便的,便于开发调试 系统准备 本人用的是Ubuntu18,以下以此为例 部署之前,最好切换至root ...
- django购物车的实现
1 购物车的实现问题思路 购物车需求分析: 1 未登陆和已登陆都保存到用户的购物车数据. 2 用户可以对购物车进行增删改查: 3 购物车有选择状态,只有选中的状态才能生成订单: 4 用户登陆时,合并c ...
- C++面试八股文:指针占用多少个字节?
某日小二参加XXX科技公司的C++工程师开发岗位4面: 面试官:memset.memcpy和strcpy的区别是什么? 小二:memset用于将一块内存设置为特定的值, memcpy用于将一块内存从一 ...
- 曲线艺术编程 coding curves 第六章 平托图 (Pintographs)
第六章 平托图 (Pintographs) 原作:Keith Peters https://www.bit-101.com/blog/2022/11/coding-curves/ 译者:池中物王二狗( ...
- 【后端面经】MySQL主键、唯一索引、联合索引的区别和作用
目录 0. 简介 1. 主键 2. 唯一索引 3. 联合索引 4. 索引对数据库操作的影响 5. 其他索引 5.1 普通索引 5.2 全文索引 5.3 前缀索引 6. 总结 7. 参考资料 0. 简介 ...