windows内核基础5——手写PE文件

PE头的顺序为:

dos头,pe标识符,文件头,可选头,节表

1.首先来构造IMAGE_DOS_HEADER结构

该结构的大小为40h字节

在IMAGE_DOS_HEADER结构中最关键的字段只有两个,就是第一个表示MZ标识头和最后一个指向PE标识符的偏移。

第一个字段占两个字节,最后一个字段占4个字节,采用小端方式存储字节.

2.构造PE标识符

PE标识符占4个字节,所以再增加4个字节的大小,并修改前两个字节为5045

3.构造IMAGE_FILE_HEADER结构体

该结构体大小为14h字节,

Machine取值为4c01,标识i386的cpu

NumberofSections取值为0300,表示该PE文件为3字节

SizeofOptionalHeader字段取值为e000,表示再win32环境下可选头的大小,

Characteristics取值为0301,表示没有重定位信息的3位平台的可执行文件

其他的字段默认为00就可以.

4.构造IMAGE_OPTIONAL_HEADER结构体

这个结构体比较大,它是PE文件格式中最重要的结构体之一

5.构造IMAGE_SECTION_HEADER结构

这样子的节表项一共有3个,一个的大小为40字节,三个就是120字节,

6.数据0的填充

PE文件格式的头部到此填充完毕,再IMAGE_OPTIONLA_HEADER结构体中,SizeofHeader字段的值是0x00001000,因此为了对齐需要将头部的大小用0补齐,所以还需要插入0x0e50个字节.

再填充完PE文件头部后,需要继续填充0x00001000字节的0字符,该0x00001000字节用来存放text节的内容,

7.填充data节的数据

data节用来保存程序运行时弹出的提示对话框中显示的字符串,用MessageBox函数来实现.MessageBox函数的第二个和第三个参数分别是两个字符串,第二个是对话框中显示的字符串,第三个是对话框标题显示的字符串,所以这里先插入4096个0字符。

并在2000地址处填写如上字符串。

8.填充.idata节的数据

idata节用来保存PE文件中最重要的两个部分,即导入表和导入地址表。在填充之前,先进行分析。

导入表和导入地址表的地址分别由数据目录给出,在数据目录中,导入表的RAV为0x00003010,导入地址表的RVA 为0x00003000.

由于本例中PE文件的RAV和FOA地址相同,不需要进行转换,接下来插入4096字节的0,并构造导入表和导入地址表。

在本例中需要导入两个DLL文件,因此需要构造3个_IMAGE_IMPORT_DESCRIPTOR,因为导入表需要有一个全0的IMAGE_IMPORT_DESCRIPTOR 来结束。

在本例中导入了两个dll文件,分别是user32.dll和kernel32.dll。在user32.dll中调用了MessageBoxA函数,在kernel32.dll中调用了Exitprocess函数。

先来构造user32.dll的导入信息,按照IMAGE_IMPORT_DESCRIPTOR结构体进行构造。

  • 在0x00003050地址处构造导入表的Name字段的值“user32.dll”
  • 在0x00003060地址处构造导入表的OriginalFirstThunk字段的值“0x00003070”
    • OriginalFirstThunk指向一个IMAGE_THUNK_DATA,在高位不为1的情况下,指向一个IMAGE_IMPORT_BY_NAME结构体。
  • 在0x00003070地址处根据IMAGE_IMPORT_BY_NAME结构体构造导入函数的名称。
  • 0x00003000地址处是导入地址表,该值由FirstThunk来指向,当在磁盘中时,该值与OriginalFirstThunk相同。

用lordpe打开该exe文件可以看到已经能够识别出为pe文件。

9.填充text节的数据

 

 

posted @ 2024-05-22 12:29  robot__i  阅读(113)  评论(0)    收藏  举报