首页
社区
课程
招聘
[原创]自学PE详解(1)导入表
发表于: 2020-2-5 00:35 5696

[原创]自学PE详解(1)导入表

2020-2-5 00:35
5696

这段时间学了PE文件,将我学习的一点心得和理解发给大家。

typedef IMAGE_DOS_HEADER STRUCT 

+0000h WORD  e_magic   //EXE标志,“MZ”

+0002h WORD  e_cblp  // 最后(部分)页中的字节数

+0004h WORD  e_cp   //文件中全部和部分页数

+0006h WORD  e_crlc   //重定位表中的指针数

+0008h WORD  e_cparhdr   //头部尺寸,以段落为单位

+000ah WORD  e_minalloc  //所需最小附加段

+000ch WORD  e_maxalloc  //所需最大附加段

+000eh WORD  e_ss    //DOS代码的初始化堆栈SS 

+0010h WORD  e_sp    //DOS代码的初始化堆栈指针SP 

+0012h WORD  e_csum    // 补码校验值

+0014h WORD  e_ip    //DOS代码的初始化指令入口[指针IP] 

+0016h WORD  e_cs    //DOS代码的初始堆栈入口 [寄存器CS值]

+0018h WORD  e_lfarlc    // 重定位表的字节偏移量

+001ah WORD  e_ovno        //覆盖号

+001ch WORD  e_res[4]    //保留字

+0024h WORD  e_oemid    //OEM标识符

+0026h WORD  e_oeminfo   //OEM信息

+0029h WORD  e_res2[10]   //保留字

+003ch DWORD   e_lfanew   //PE头相对于文件的偏移地址 指向PE头 

} IMAGE_DOS_HEADER ENDS,IMAGE_DOS-HEADER, *PIMAGE_DOS_HEADER;  

typedefstruct_IMAGE_NT_HEADERS

{

+00h DWORD Signature                                                         //PE头文件标识,“PE\0\0”

+04h IMAGE_FILE_HEADER FileHeader                                   //PE标准头

+18h IMAGE_OPTIONAL_HEADER32 OptionalHeader           //PE扩展头

} IMAGE_NT_HEADERS,*PIMAGE_NT_HEADERS32;

typedef struct _IMAGE_OPTIONAL_HEADER 
{
    //
    // Standard fields.  
    //
+18h    WORD    Magic;         // ROM 映像(0107h),普通可执行文件(010Bh)
// x32: 10B, x64: 20B
+1Ah    BYTE      MajorLinkerVersion;     // 链接程序的主版本号
+1Bh    BYTE      MinorLinkerVersion;     // 链接程序的次版本号
+1Ch    DWORD   SizeOfCode;     // 所有含代码的节的总大小
+20h    DWORD   SizeOfInitializedData;    // 所有含已初始化数据的节的总大小
+24h    DWORD   SizeOfUninitializedData; // 所有含未初始化数据的节的大小
+28h    DWORD   AddressOfEntryPoint;    // 程序执行入口RVA
+2Ch    DWORD   BaseOfCode;      // 代码的区块的起始RVA
+30h    DWORD   BaseOfData;      // 数据的区块的起始RVA
//-------------------------------------------------------------
// NT additional fields.    以下是属于NT结构增加的领域。
//-------------------------------------------------------------
+34h    DWORD   ImageBase;      // 程序的首选装载地址(程序建议装载地址)
+38h    DWORD   SectionAlignment;      // 内存中的区块的对齐大小
+3Ch    DWORD   FileAlignment;      // 文件中的区块的对齐大小
+40h    WORD    MajorOperatingSystemVersion;  // 要求操作系统最低版本号的主版本号
+42h    WORD    MinorOperatingSystemVersion;  // 要求操作系统最低版本号的副版本号
+44h    WORD    MajorImageVersion;       // 可运行于操作系统的主版本号
+46h    WORD    MinorImageVersion;       // 可运行于操作系统的次版本号
+48h    WORD    MajorSubsystemVersion;  // 要求最低子系统版本的主版本号
+4Ah    WORD    MinorSubsystemVersion;  // 要求最低子系统版本的次版本号
+4Ch    DWORD   Win32VersionValue;       // 莫须有字段,不被病毒利用的话一般为0
+50h    DWORD   SizeOfImage;       // 映像装入内存后的总尺寸(内存中的整个PE映像尺寸)

+54h    DWORD   SizeOfHeaders;       // 所有头 + 区块表的尺寸大小
+58h    DWORD   CheckSum;       // 映像的校检和
+5Ch    WORD    Subsystem;       // 可执行文件期望的子系统
+5Eh    WORD    DllCharacteristics;       // DllMain()函数何时被调用,默认为 0(DLL文件特性)
+60h    DWORD   SizeOfStackReserve;       // 初始化时的栈大小
+64h    DWORD   SizeOfStackCommit;       // 初始化时实际提交的栈大小
+68h    DWORD   SizeOfHeapReserve;        // 初始化时保留的堆大小
+6Ch    DWORD   SizeOfHeapCommit;        // 初始化时实际提交的堆大小
+70h    DWORD   LoaderFlags;        // 与调试有关,默认为 0 

+74h    DWORD   NumberOfRvaAndSizes;  // 下边数据目录的项数,这个字段自Windows NT 发布以来        // 一直是16

+78h    IMAGE_DATA_DIRECTORY DataDirectory[IMAGE_NUMBEROF_DIRECTORY_ENTRIES];// 数据目录表

} IMAGE_OPTIONAL_HEADER32, *PIMAGE_OPTIONAL_HEADER32;


typedef struct _IMAGE_DATA_DIRECTORY

{

DWORD VirtualAddress;      //0000h - 数据得起始RVA

DWORD isize;                      //0004h - 数据块的长度 

}IMAGE_DATA_DIRECTORY,*PIMAGE_DATA_DIRECTORY;  

#define IMAGE_DIRECTORY_ENTRY_EXPORT       0 导出表地址和大小

#define IMAGE_DIRECTORY_ENTRY_IMPORT        1 导入表地址和大小 

#define IMAGE_DIRECTORY_ENTRY_RESOURCE  2 资源目录资源表地址和大小

#define IMAGE_DIRECTORY_ENTRY_EXCEPTION  3 异常目录异常表地址和大小

#define IMAGE_DIRECTORY_ENTRY_SECURITY      4 安全目录属性证书数据地址和大小

#define IMAGE_DIRECTORY_ENTRY_BASERELOC          5 基地址重定位表地址和大小

#define IMAGE_DIRECTORY_ENTRY_DEBUG                   6 调试信息地址和大小

#define IMAGE_DIRECTORY_ENTRY_COPYRIGHT              7 预留为0

#define IMAGE_DIRECTORY_ENTRY_GLOBALPTR             8 指向全局指针寄存器的值

#define IMAGE_DIRECTORY_ENTRY_TLS                          9 线程句柄存储地址和大小

#define IMAGE_DIRECTORY_ENTRY_LOAD_CONFIG         10 加载配置表地址和大小

#define IMAGE_DIRECTORY_ENTRY_BOUND_IMPORT             11 绑定导入表地址和大小

#define IMAGE_DIRECTORY_ENTRY_IAT                                  12 导入函数地址表地址和大小

#define IMAGE_DIRECTORY_ENTRY_DELAY_IMPORT             13 延迟导入表地址和大小

#define IMAGE_DIRECTORY_ENTRY_COM_DESCRIPTOR           14 COM信息

#define Reserved                                                                               15系统保留

typedefstruct_IMAGE_SECTION_HEADER {

+0h BYTE Name[IMAGE_SIZEOF_SHORT_NAME];//节表名称,如“.text” 8个字节节名 //IMAGE_SIZEOF_SHORT_NAME=8

union

+8h

{

DWORD PhysicalAddress;//物理地址 节区的尺寸

DWORD VirtualSize;//真实长度,这两个值是一个联合结构,可以使用其中的任何一个,一般是取后一个

} Misc;

+ch DWORD VirtualAddress;//节区的 RVA 地址

+10h DWORD SizeOfRawData;//在文件中对齐后的尺寸

+14h DWORD PointerToRawData;//在文件中的偏移量

+18h DWORD PointerToRelocations;//在OBJ文件中使用,重定位的偏移

+1ch DWORD PointerToLinenumbers;//行号表的偏移(供调试使用)

+1eh WORD NumberOfRelocations;//在OBJ文件中使用,重定位项数目

+20h WORD NumberOfLinenumbers;//行号表中行号的数目

+24h DWORD Characteristics;//节属性如可读,可写,可执行等
} IMAGE_SECTION_HEADER, *PIMAGE_SECTION_HEADER; 

0000204c 是INT表的RVA        FOA 64c

00002084 是库名                     FOA 684

00002000 是IAT表的RVA         FOA 600


首先我们来看导入表结构体的第一个成员包含的是什么信息

来看第一个偏移 654


我们发现INT表保存的是一个 RVA下面我们将 RVA 转换成 FOA 65c


可以看见INT表指向的 数据包含了两个结构

(注:这里INT表指向的RVA地址实际上是一个数组)

前两个字节包含的时函数编号

后面的字符串就是函数名


导入表结构的NAME成员 偏移是 66A


这里我们可以见看 NAME所指向的DLL名


接着我们来查看 IAT表

相信表哥们可以发现一个细节

IAT表指向的地址 和 INT 表所指向的值是一样的。

到这里我们打开OD


我们发现在PE文件装载进内存之后 值就发生了改变

让我们看看这个地址又是什么


在这里我们可以发现 IAT表中的信息已经被改成了 DLL链接库中函数的地址


从上图中可以发现 750b0380是函数的入口地址




可以发现JMP的位置 就是函数的入口地址


[培训]科锐逆向工程师培训第53期2025年7月8日开班!

收藏
免费 4
支持
分享
最新回复 (8)
雪    币: 155
活跃值: (3321)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
2
支持,很不错学习了。
2020-2-5 08:38
0
雪    币: 9802
活跃值: (6258)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
jgs
3
坚持,继续
2020-2-5 15:56
0
雪    币: 2510
能力值: ( LV1,RANK:0 )
在线值:
发帖
回帖
粉丝
4
感谢分享
2020-2-5 17:57
3
雪    币: 172
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
5
先收藏了,以后再仔细学习,感谢!!!
2020-2-11 22:12
0
雪    币: 70
活跃值: (272)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
6
感谢分享,最近刚好需要
2020-2-12 01:31
0
雪    币: 205
能力值: ( LV1,RANK:0 )
在线值:
发帖
回帖
粉丝
7
感谢分享
2020-2-12 21:26
0
雪    币:
能力值: ( LV1,RANK:0 )
在线值:
发帖
回帖
粉丝
8
学习学习
2020-2-16 11:57
0
雪    币: 119
能力值: ( LV1,RANK:0 )
在线值:
发帖
回帖
粉丝
9
太好了!!!
2020-4-15 21:55
0
游客
登录 | 注册 方可回帖
返回