PE

1.pe文件结构

windows        pe文件结构
linux        elf文件结构

例如我用clion生成的文件batman.exe,用010ediotr打开

#include "stdlib.h"

int main(){
    system("pause");
    system("ipconfig /all");
    system("pause");
}

前两个字节必是MZ

在3C的位置,我们去找这个对应的80

80位置的字节对应的就是PE,代表这是一个可执行文件

PE指纹。

1)dos部分:给dos用的
2)pe文件头:给windows用的
3)节表:决定节数据的内容(说明书)
4)节数据:真正的内容

2.pe文件的两种状态

1)DOS部分

在windows上的winnt.h文件上,有_IMAGE_DOS_HEADER

一个exe文件运行前和运行后的pe格式有差别

DOS MZ文件头是64个字节,如图

DOS Stub(DOS块)大小不确定,是给连接器用的,连接器会插入自己的数据,删掉也不会影响程序的运行

DOS MZ文件头的最后四个字节指向了PE文件头的开始位置

那么Dos块就是两者之间的部分

2)PE文件头

    typedef struct _IMAGE_NT_HEADERS {
      DWORD Signature;                #    四个字节的文件头
      IMAGE_FILE_HEADER FileHeader;        #    子结构体(标准PE头)
      IMAGE_OPTIONAL_HEADER32 OptionalHeader;        #    子结构体(扩展PE头)
    } IMAGE_NT_HEADERS32,*PIMAGE_NT_HEADERS32;

标准PE头有20个字节

扩展PE头如果是32位,那么长度是224字节

因为这个有个数组,所以大,数组的每个成员是结构体。

在标准PE头中有一个规定扩展PE头大小的(2个字节)

32位的是E0(224),64位的是F0(240)

那么向后找240个字节就是64位的扩展PE头

3)节表

节表里的每个成员是40个字节

第一个成员.text

image07ee4881057e9eea.png

第二个成员.data

第三个成员.rdata

imagef6dea161c43830c7.png

第四个成员.pdata

image41fbe809db0b9846.png

第五成员.xdata

image194382ec62fada4c.png

再之后就是编译器插入的垃圾其他数据,四个节表成员代表四组数据

扩展PE头有一个成员

image86a3e9892fa1dce9.png

这个头指的是DOS 头 + PE 头 + 节表,按照文件对其以后的大小

假设1 + 2 + 3的大小是302个字节

image8e78fbf3307ecbd3.png

那么SizeOfheaders的大小是在满足这个之后又必须被“文件对其”之后的大小的整数倍,如下

image6a781e178912b1a6.png

假设这个filealignment是200字节那么我的实际大小就是400字节,是它的整数倍大于302,为了执行的时候效率更高

image857f95e03dedcd64.png

这里我们在标准PE头之后查2 + 1 2 + 8 4 = 36 个字节之后就是filealignment

image7307be444e7c45e0.png

这里就是filealignment是10进制的200

那么我们再去找sizeofheader,从文件对其之后再找20个字节

image2e1321be8674656a.png

image3fa4dbc23293fbbe.png

也就是十进制的400,必须是200的整数倍

imagec2f35fcd27b4934f.png

这个之上都是头的大小,之下再开始就是真正的节数据了

image492e23cc24d59d1c.png

也就是说假如.text块的大小是180字节,那么我们使得它为200字节,剩下的20字节用0填充

在硬盘中的头和在内存中的头是一样的

imagea53f0814bc8959a9.pngimage3f39991365b477b7.png

在硬盘中的第一个节是400开始,但是在内存中的第一个节却不是400,是1000

imageb569c3fe62190415.pngimage73aded9fbe6f1be8.png

是因为内存对齐成员属性,在fileaglinment之上的sectionalignment规定了内存对齐

imagef6e73fe80441af68.png

image69485f324359ed4a.png

是100

PE的两种状态就是内存中和硬盘中的两种状态

3.DOS头属性说明

imagef246f0c560b9e8cc.png

image7cb29d147caa5040.png

总共是64位

除了标红的这两个,其他的都是为16位服务的,现在都是32位或者64位所以已经用不到,可以删掉了

image51c9c499e0dbab67.png

我们把除了第一个和最后一个以外其他都变成0

另存为在桌面,运行,发现正常执行

image.png

正常执行

image-20221110134057942

操作系统如何判断是否是可执行文件?
前两个字节是MZ,倒数第四个字节指向的地方是PE头,所以这两处不能改动,否则不能运行

image37b8f7d315d954fb.png

image4667321ae1c495bd.png

dos块的内容可以更改

imagedb695a05e15eb739.pngimage5507403326bb9e79.png

不影响程序的运行,所以我们可以添加恶意代码shellcode进去

image2cb5490cdc06a387.png

4.标准PE头属性说明

    typedef struct _IMAGE_NT_HEADERS {
      DWORD Signature;        #    PE标识
      IMAGE_FILE_HEADER FileHeader;            #    标准PE头
      IMAGE_OPTIONAL_HEADER32 OptionalHeader;            #    扩展PE头
    } IMAGE_NT_HEADERS32,*PIMAGE_NT_HEADERS32;

如果更改PE标识也无法运行

标准PE头

imagedb7c687176b68049.png

两个字节的machine:如果是00 00 那么就是可以运行在任何CPU上

image806c5834d26ee43a.png

system64存储32位的,system32存储64位的

imageb5592c01e2dd9bd4.png

image1cd4d3d45743b2d9.png

image22ba6d93f6f70418.pngimage1d81f40e3e9dc248.png

numberofsections 代表有多少个节,也就是后面的0F 00 ,根据小端存储,就是000F,也就是15个节

再往后的4个字节是timedatestamp,是编译器填写的时间戳,和创建时间修改时间无关

imagefb232efe7cfb3896.png

636B9534

image7d61f39e4f6f5942.pngimageec0c04ffe8bcd328.png

全部修改也不影响使用,然后跳过8个字节的两个字节是扩展PE头的大小

我们默认不该32位的是224字节(0xE0),64位的是240字节(0xF0)

imagea26dcaa8d1972f75.png

再之后两个字节就是文件属性

image4454341ea7b4ef6d.png

刚好2个字节,16位,代表每个属性

image6df6d34172b69d53.png

这里的27 00 就是 00 27,转2进制是0000 0000 0010 0111

根据上面那个图

0000 0000 0010 0111

image5bd685fed3916afb.png

这里数据位是1的,代表上图文件可执行

数据位是5的地方是1,代表可处理大于2GB的的地址,意思就是在32位中内核高2G,应用程序低2G,如果大于2G就说明不是32位的,是64位的

5.扩展PE头属性

32位的PE头和64位的PE头有差异

    typedef struct _IMAGE_NT_HEADERS {
      DWORD Signature;
      IMAGE_FILE_HEADER FileHeader;
      IMAGE_OPTIONAL_HEADER32 OptionalHeader;
    } IMAGE_NT_HEADERS32,*PIMAGE_NT_HEADERS32;
    typedef struct _IMAGE_NT_HEADERS64 {
      DWORD Signature;
      IMAGE_FILE_HEADER FileHeader;
      IMAGE_OPTIONAL_HEADER64 OptionalHeader;
    } IMAGE_NT_HEADERS64,*PIMAGE_NT_HEADERS64;

差别在 IMAGE_OPTIONAL_HEADER32 和 IMAGE_OPTIONAL_HEADER64

image83505fc8291b43ff.pngimagecfa3e409f020134d.png

这里最后的NumberOfRvaAndSizes 代表目录项数量,16个,乘以下面的数组长度,16张表(重点)

    typedef struct _IMAGE_OPTIONAL_HEADER {

      WORD Magic;
      BYTE MajorLinkerVersion;
      BYTE MinorLinkerVersion;
      DWORD SizeOfCode;
      DWORD SizeOfInitializedData;
      DWORD SizeOfUninitializedData;
      DWORD AddressOfEntryPoint;
      DWORD BaseOfCode;
      DWORD BaseOfData;
      DWORD ImageBase;
      DWORD SectionAlignment;
      DWORD FileAlignment;
      WORD MajorOperatingSystemVersion;
      WORD MinorOperatingSystemVersion;
      WORD MajorImageVersion;
      WORD MinorImageVersion;
      WORD MajorSubsystemVersion;
      WORD MinorSubsystemVersion;
      DWORD Win32VersionValue;
      DWORD SizeOfImage;
      DWORD SizeOfHeaders;
      DWORD CheckSum;
      WORD Subsystem;
      WORD DllCharacteristics;
      DWORD SizeOfStackReserve;
      DWORD SizeOfStackCommit;
      DWORD SizeOfHeapReserve;
      DWORD SizeOfHeapCommit;
      DWORD LoaderFlags;
      DWORD NumberOfRvaAndSizes;
      IMAGE_DATA_DIRECTORY DataDirectory[IMAGE_NUMBEROF_DIRECTORY_ENTRIES];
    } IMAGE_OPTIONAL_HEADER32,*PIMAGE_OPTIONAL_HEADER32;

Magic 可以判断是32位还是64位,如果转换之后是10B就是32位,是20B就是64位的

AddressOfEntryPoint 是程序的入口,一定要配合ImageBase 一起看(内存镜像基址)

这里我们ImageBase 就是我们的PE在4GB的内存中展开的初始地址,而AddressOfEntryPoint 则是我们程序开始的指向地址

image123e66605f78b6d3.png

查过16个字节就是183D7(相对地址,相对ImageBase)

imagea0e5b5e11aaa6d15.png

再跳过8个字节找ImageBase,就是400000

00 00 40 00

image3a72401c8b26364c.png

那么在内存中的绝对地址就是 400000 + 183D7 = 4183D7

imageb20a75b6b2e7f532.png

所以程序之所以能找到入口,就是因为这个

所以加密就是不能让逆向分析人员轻易找到程序的入口,想办法藏起来

SizeOfImage 决定整个PE占整个内存的多大,一定是内存对齐的整数倍

SizeOfHeaders 是按照对齐后的大小

checksum 是校验和,判断文件是否被修改

DllCharacteristics 是判断是否可以被DLL加载

image2cc05ae815dffac0.png

imageb58f49ffde8a0f78.png

这里之前的3就是代表控制台或者dll文件
40 01 就是 0140        0000   0001   0100   0000
这里就是6和8的位置有对应,就是可以被重定位和兼容DEP(硬件层面堵漏洞)

6.节表

results matching ""

    No results matching ""