PE结构笔记
提示:前面加*为必须背下来的
DOS头:
typedef struct _IMAGE_DOS_HEADER { // DOS .EXE header
WORD e_magic; //* Magic number
WORD e_cblp; // Bytes on last page of file
WORD e_cp; // Pages in file
WORD e_crlc; // Relocations
WORD e_cparhdr; // Size of header in paragraphs
WORD e_minalloc; // Minimum extra paragraphs needed
WORD e_maxalloc; // Maximum extra paragraphs needed
WORD e_ss; // Initial (relative) SS value
WORD e_sp; // Initial SP value
WORD e_csum; // Checksum
WORD e_ip; // Initial IP value
WORD e_cs; // Initial (relative) CS value
WORD e_lfarlc; // File address of relocation table
WORD e_ovno; // Overlay number
WORD e_res[]; // Reserved words
WORD e_oemid; // OEM identifier (for e_oeminfo)
WORD e_oeminfo; // OEM information; e_oemid specific
WORD e_res2[]; // Reserved words
LONG e_lfanew; //* NT头指针
} IMAGE_DOS_HEADER, *PIMAGE_DOS_HEADER;
NT头:
typedef struct _IMAGE_NT_HEADERS {
DWORD Signature; //*pe签名
IMAGE_FILE_HEADER FileHeader; //*PE标准
IMAGE_OPTIONAL_HEADER OptionalHeader; //*PE可选头
} IMAGE_NT_HEADERS, *PIMAGE_NT_HEADERS;
NT::标准PE头:
typedef struct _IMAGE_FILE_HEADER {
WORD Machine; //*cpu识别
WORD NumberOfSections; //*文件的节数目 (节表与节的数目一样)
DWORD TimeDateStamp; //*文件创建日期和时间
DWORD PointerToSymbolTable; //用于调试
DWORD NumberOfSymbols; //用于调试
WORD SizeOfOptionalHeader; //*PE可选头的大小,32位PE文件默认为E0h,64位PE文件默认大小为F0h 大小可以自定
WORD Characteristics; //*关于文件信息的标记,比如文件是exe还是dll
} IMAGE_FILE_HEADER, *PIMAGE_FILE_HEADER;
NT::可选PE头(32位下大小为E0 64位的为F0)
typedef struct _IMAGE_OPTIONAL_HEADER
{
WORD Magic; //*说明文件类型:10B 32位下的PE文件 20B 64位下的PE文件
BYTE MajorLinkerVersion; //链接程序的主版本号
BYTE MinorLinkerVersion; //链接程序的次版本号
DWORD SizeOfCode; //*所有含代码的节的总大小,必须是FileAlignment的整数倍 编译器填的 没用
DWORD SizeOfInitializedData; //*已初始化数据的大小 必须是FileAlignment的整数倍 编译器填的 没用
DWORD SizeOfUninitializedData; //*未初始化数据的大小 必须是FileAlignment的整数倍 编译器填的 没用
DWORD AddressOfEntryPoint; //*****程序执行入口RVA
DWORD BaseOfCode; //*代码开始的基址, 编译器填的 没用
DWORD BaseOfData; //*数据开始的基址, 编译器填的 没用
DWORD ImageBase; //*****内存镜像基址
DWORD SectionAlignment; //*内存中的区块的对齐大小
DWORD FileAlignment; //*文件中的区块的对齐大小
WORD MajorOperatingSystemVersion; //要求操作系统最低版本号的主版本号
WORD MinorOperatingSystemVersion; //要求操作系统最低版本号的副版本号
WORD MajorImageVersion; //可运行于操作系统的主版本号
WORD MinorImageVersion; //可运行于操作系统的次版本号
WORD MajorSubsystemVersion; //要求最低子系统版本的主版本号,
WORD MinorSubsystemVersion; //要求最低子系统版本的次版本号
DWORD Win32VersionValue; //莫须有字段,不被病毒利用的话一般为0
DWORD SizeOfImage; //*内存中整个PE文件的映射尺寸,可以比实际值大,但必须是SectionAlignment的整数倍
DWORD SizeOfHeaders; //*所有头+节表按照文件对齐后的大小,否则加载会出错
DWORD CheckSum; //*校验和,一些系统文件有要求,用来判断文件是否被修改
WORD Subsystem; //可执行文件期望的子系统
WORD DllCharacteristics; //DllMain()函数何时被调用,默认为 0
DWORD SizeOfStackReserve; //*初始化时的栈大小
DWORD SizeOfStackCommit; //*初始化时实际提交的栈大小
DWORD SizeOfHeapReserve; //*初始化时保留的堆大小
DWORD SizeOfHeapCommit; //*初始化时实际提交的堆大小
DWORD LoaderFlags; //与调试有关,默认为 0
DWORD NumberOfRvaAndSizes; //下边数据目录的项数,这个字段自Windows NT 发布以来 一直是16
IMAGE_DATA_DIRECTORY DataDirectory
[IMAGE_NUMBEROF_DIRECTORY_ENTRIES];// 数据目录表
} IMAGE_OPTIONAL_HEADER32, *PIMAGE_OPTIONAL_HEADER32;
节表:
IMAGE_SIZEOF_SHORT_NAME组成,每个结构体代表一个节区
#define IMAGE_SIZEOF_SHORT_NAME
typedef struct _IMAGE_SECTION_HEADER {
BYTE Name[IMAGE_SIZEOF_SHORT_NAME]; //8个字节 一般情况下是以“\0”结尾的ASCII码字符串来标识的名称 内容可以自定义 可能由于字母太多编译器不添加"\0"需要注意
union {
DWORD PhysicalAddress;
DWORD VirtualSize;
} Misc; //在文件对齐前真实的大小,该值可以不准确
DWORD VirtualAddress; //*节在内存中的偏移地址。加上ImageBase才是内存中真实地址
DWORD SizeOfRawData; //*节在文件中对齐之后的大小
DWORD PointerToRawData; //*节在文件中的偏移 文件对齐的整数倍
DWORD PointerToRelocations; //
DWORD PointerToLinenumbers; //
WORD NumberOfRelocations; //
WORD NumberOfLinenumbers; //
DWORD Characteristics; //*节的属性
} IMAGE_SECTION_HEADER, *PIMAGE_SECTION_HEADER;
注意:
VirtualAddress 和 PointerToRawData 不带有任何值,分别由_IMAGE_OPTIONAL_HEADER中的SectionAlignment和FileAlignment确定
VirtualSize和SizeOfRawData一般具有不同的值,即磁盘节区的大小与加载到内存的大小是不一样的。
导入表(IAT)/ 导出表():
typedef struct _IMAGE_IMPORT_DESCRIPTOR {
_ANONYMOUS_UNION union {
DWORD Characteristics;
DWORD OriginalFirstThunk; // INT的地址(Import Name Table)(RVA)
} DUMMYUNIONNAME; //
DWORD TimeDateStamp; //
DWORD ForwarderChain; //
DWORD Name; //库名称字符串的地址 (RVA)
DWORD FirstThunk; // IAT的地址(Import Address Table)(RVA)
} IMAGE_IMPORT_DESCRIPTOR,*PIMAGE_IMPORT_DESCRIPTOR;
typedef struct _IMAGE_EXPORT_DIRECTORY {
DWORD Characteristics;
DWORD TimeDateStamp; // 时间戳
WORD MajorVersion;
WORD MinorVersion;
DWORD Name; // *指向该导出表文件名字符串
DWORD Base; // *导出函数起始序号
DWORD NumberOfFunctions; // *所有导出函数的个数
DWORD NumberOfNames; // *以函数名字导出的函数个数
DWORD AddressOfFunctions; // *导出函数地址表RVA
DWORD AddressOfNames; // *导出函数名称表RVA
DWORD AddressOfNameOrdinals; // *导出涵数序号表RVA
} IMAGE_EXPORT_DIRECTORY, *PIMAGE_EXPORT_DIRECTORY;
注意: INT与IAT是长整型(4个字节数据类型)数组,以NULL结束 INT中各元素的值为IMAGE_IMPORT_BY_NAME结构体指针(有时IAT也拥有相同的值) INT与IAT的大小应相同 INT输入顺序: .读取IID的Name成员,获取库名称字符串("kernel32.dll") .装载相应库——————> LoadLibrary("kernel32.dll") .读取IID的OriginalFirstThunk成员,获取INT地址 .逐一读取INT中数组的值,获取相应IMAGE_IMPORT_BY_NAME地址(RVA) .使用IMAGE_IMPORT_BY_NAME的Hint(ordinal) 或Name项,获取相应函数的起始地址。 GetProcAddress("GetCurrentThreadId") .读取IID的FirstThunk(IAT)成员,获得IAT地址 .将上面获得的函数地址输入相应IAT数组值。 .重复以上补助4~,直到INT结束(遇到NULL时) RVA与RAW转换: RAW = RAV - VirtualAddress + PointerToRawData 物理地址 = 内存相对地址 - 内存节区的起始地址 + 物理节区的起始位置
PE结构笔记的更多相关文章
- PE结构学习笔记--关于AddressOfEntryPoint位置在文件中怎么确定问题
第一次学习PE结构,也不知道有没有更好的办法. 1.AddressOfEntryPoint 这个成员在OptionalHeader里面,OptionalHeader的类型是一个IMAGE_OPTION ...
- 羽夏笔记——PE结构(不包含.Net)
写在前面 本笔记是由本人独自整理出来的,图片来源于网络.本人非计算机专业,可能对本教程涉及的事物没有了解的足够深入,如有错误,欢迎批评指正. 如有好的建议,欢迎反馈.码字不易,如果本篇文章有帮助你 ...
- 【PE结构】由浅入深PE基础学习-菜鸟手动查询导出表、相对虚拟地址(RVA)与文件偏移地址转换(FOA)
0 前言 此篇文章想写如何通过工具手查导出表.PE文件代码编程过程中的原理.文笔不是很好,内容也是查阅了很多的资料后整合出来的.希望借此加深对PE文件格式的理解,也希望可以对看雪论坛有所贡献.因为了解 ...
- 手写PE结构解析工具
PE格式是 Windows下最常用的可执行文件格式,理解PE文件格式不仅可以了解操作系统的加载流程,还可以更好的理解操作系统对进程和内存相关的管理知识,而有些技术必须建立在了解PE文件格式的基础上,如 ...
- OD 实验(五) - 对 PE 结构的简单分析
载入程序,按 Alt+M 查看内存空间 双击进入程序的 PE 头 这些为 DOS 环境下才会运行的 这个执行 PE 的地址,PE 结构的偏移地址为 C0 找到这个地址 以 PE 开头 SizeOfCo ...
- 仿LordPE获取PE结构
乍一看LordPE一个小工具一般般,真的动手做起来才知道技术含量高的很. 当前只是获取到PE结构并打印,仅此而已. PE.h #pragma once #include <stdio.h> ...
- 编写自定义PE结构的程序(如何手写一个PE,高级编译器都是编译好的PE头部,例如MASM,TASM等,NASM,FASM是低级编译器.可以自定义结构)
正在学PE结构...感谢个位大哥的文章和资料...这里先说声谢谢 一般高级编译器都是编译好的PE头部,例如MASM,TASM等一直都说NASM,FASM是低级编译器.可以自定义结构但是苦于无人发布相关 ...
- 关于pe结构
每一种操作系统它最重要的格式就是它的可执行文件格式, 因为操作系统就是为了支持这些文件而生成的,内核里面有很多机制,也是配合这种文件格式设计的. 换句话说,这种文件格式也是适合操作系统设计的. 比如: ...
- 【转】pe结构详解
(一)基本概念 PE(Portable Execute)文件是Windows下可执行文件的总称,常见的有DLL,EXE,OCX,SYS等, 事实上,一个文件是否是PE文件与其扩展名无关,PE文件可以是 ...
随机推荐
- 关于事件触发的一个小tips
今天看到如下代码 window.globalEvent.bind('hotelHotTableRendered', function () { $('#hotelHotTd a').each(func ...
- Linux Centos 上一些常用的命令
1.查看端口被哪个进程占用 netstat -lnp | grep <端口号> 2.查看某个进程号详细信息 ps <进程号> 3.检查指定服务是否开启(例如 telnet) c ...
- linux设备驱动归纳总结(八):4.总线热插拔【转】
本文转载自:http://blog.chinaunix.net/uid-25014876-id-110774.html linux设备驱动归纳总结(八):4.总线热插拔 xxxxxxxxxxxxxxx ...
- 【python cookbook】【数据结构与算法】14.对不原生支持比较操作的对象排序
问题:想在同一个类的实例之间做排序,但是它们并不原生支持比较操作. 解决方案:使用内建的sorted()函数可接受一个用来传递可调用对象的参数key,sorted利用该可调用对象返回的待排序对象中的某 ...
- 161111、NioSocket的用法(new IO)
今天先介绍NioSocket的基本用法,实际使用一般会采用多线程,后面会介绍多线程的处理方法. 从jdk1.4开始,java增加了新的io模式--nio(new IO),nio在底层采用了新的处理方式 ...
- 6.1:SportStore:一个真实的应用
之前的小例子让我们演示了AngularJS的一些特性,但他们缺少上下文.要解决这个问题,作者要创建一个简单单真实的电子商务应用. 作者将创建一个在线产品分类,客户可以通过分类和页面浏览,一个购物车用户 ...
- ectouch第四讲 之缓存文件的生成
当第一次访问\mobile主页的时候,就会生成如下缓存文件:缓存文件存放在\mobile\data\cache\文件夹下 |-mobile |-data |-cache |-compiled [前台编 ...
- 修改ECSHOP后台的商品列表里显示该商品品牌
如何在在ECSHOP后台的商品列表中也显示商品的品牌”.下面就来最模板讲一下如何来修改.此方法只保证在ECSHOP2.7.2版本下有效,其他版本请参照修改. 第一步:首先我们来打开程序文件: /adm ...
- html 和 html5(一)(表格 | 列表 | 提交按钮 | 单选 |复选 | 框架 | 脚本 | html字符实体 )
一.框架 使用iframe来显示目录链接页面 iframe可以显示一个目标链接的页面 目标链接的属性必须使用iframe的属性,如下实例: 实例 <iframe src="demo_i ...
- 20145227 《Java程序设计》实验四实验报告
20145227 <Java程序设计>实验四实验报告 实验内容 安装Andriod Studio并配置软件 使用Andriod Studio软件实现Hello World的小程序 实验步骤 ...