Contents

PE结构学习

壳执行流程

壳程序入口—>解密原程序—>重定位—>EIP指向源程序OEP

PE

DOS header

PE header

SECTION table

VA: 虚拟内存地址(Virtual Address)

PE 文件被操作系统加载进内存后的地址。

RVA: PE文件的相对虚拟地址(Relative Virual Address)

是PE文件中的数据、模块等运行在内存中的实际地址相对PE文件装载到内存的基址之间的距离。举例说明,如果PE文件装入虚拟地址(VA)空间的400000h处,且进程从虚址401000h开始执行,我们可以说进程执行起始地址在RVA 1000h。

FOA

文件偏移地址(File Offset Address),和内存无关,它是指某个位置距离文件头的偏移。

RVA FOA

RVA->VA

VA=ImageBase+RVA

FOA->VA

1.RVA找到所在Section

2.Section RVA-SECTIONBASE

3.RAW+OFFSET

简化:FOA=(RVA-SECTIONRVA)+BASEFOA

导入表

IMAGE_IMPORT_DESCRIPTOR

每个IID代表一个DLL

 0
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
typedef struct _IMAGE_IMPORT_DESCRIPTOR {
    union {
        DWORD   Characteristics;            
        DWORD   OriginalFirstThunk; // 指向 导入名称表INT(ImportNameTable)的RVA
    } DUMMYUNIONNAME;
    DWORD   TimeDateStamp;                  
    DWORD   ForwarderChain;                 
    DWORD   Name;                   // 指向 DLL名称的地址 RVA
    DWORD   FirstThunk;             // 指向 导入地址表IAT(ImportAddressTable)的RVA
} IMAGE_IMPORT_DESCRIPTOR;
typedef IMAGE_IMPORT_DESCRIPTOR UNALIGNED *PIMAGE_IMPORT_DESCRIPTOR;

FirstThunk -》IAT

导入表FOA = 导入表RVA - 区段RVA + 区段FOA 导入表VA = 加载基址BaseImage + 导入表RVA

导出表

 0
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
typedef struct _IMAGE_EXPORT_DIRECTORY {
    DWORD   Characteristics;
    DWORD   TimeDateStamp;
    WORD    MajorVersion;
    WORD    MinorVersion;
    DWORD   Name;
    DWORD   Base;
    DWORD   NumberOfFunctions; //导出函数数量
    DWORD   NumberOfNames;//按名字导出函数的数量
    DWORD   AddressOfFunctions;     // DWORD数组 记录导出函数RVA
    DWORD   AddressOfNames;         // DWORD数组 记录导出函数名字
    DWORD   AddressOfNameOrdinals;  
	// WORD 数组 数组中的每一项与AddressOfNames中的每一项对应,
	//表示该名字的函数在AddressOfFunctions中的序号。
} IMAGE_EXPORT_DIRECTORY, *PIMAGE_EXPORT_DIRECTORY;

重定位

0
1
2
3
4
5
typedef struct _MyReloadtion {
    DWORD virtualAddress;
    DWORD sizeOfBlock;
    vector<WORD> typeOffset;  //高4位表类型,一般都是3000  低12位表示偏移量
//所以这里ebx实际上就是 ebx = virtualAddress + typeOffset低12位
}MyReloadtion, *pMyReloadtion;

重定位表的作用就是:当实际加载到内存中的Imagebase与本该加载时候的Imagebase地址不同的时候 就需要进行修复重定位表

重定位表修复场景

1.脱壳后

脱壳前重定位表记载的是壳程序的重定位表

脱壳后需要修复重定位表