第一课 PE的介绍与手写DOS头

这个头文件包含了所有PE相关的结构

首先创建一个小的可执行程序

选择一个小的应用程序

编译好之后,我们看一下他的区段(text是放代码的,rdata段是放导入表的,data用来放全局函数的)

把头文件放到编译的目录下可以精简我们的程序

只要在源码中包含一下这个头文件即可

右键查看头文件

合并区段的部分被注释掉了

加上合并区段的代码

编译出来会发现应用程序更小了,查看一下区段,会发现区段被合并了

进入正题

 

 

这是PE的整体架构

我们一个一个分开看

为什么要将MZ当做DOS签名呢?

这个是我手写PE程序的DOS头,有64字节(PE只是个参考,有些结构体成员可有可无)

计算一下大小,验证一下

DOS存根的概念

40到4D是16位的汇编指令,在DOS环境下才会执行这些代码,32为的Windows中不会运行。

这是手写PE的DOS存根,总共112字节 我将它的位置留出来方便讲解,也可以不留(DOS存根大小一般为112字节,大小不固定)

 

 

NT头(包含了文件头和可选头)

NT头有4个字节的标识,前面空出的8字节是为了内存对其需要,必须得填充NULL

文件头

文件头是表现文件大致属性的结构体

注意一个特殊的例子:.obj和resource DLL的characteristics值不是0002h,他们都不可执行

 

手写PE的NT头

 

可选头(PE头中最大的结构体)

必须有的成员:否则可执行文件会出错

手写PE的可选头

 

节区头的概念

 

 

 

 

 

节区头结构体

重要成员

Characterisitics是由下面这些值组合起来的(相加)

手写PE的节区头(区段头)

RVA和RAW之间的转换

文件偏移-文件中节区的起始位置=内存偏移-内存中节区的起始位置

文件偏移=内存偏移-内存中节区的起始位置+文件中节区的起始位置

 

创建一个文件,用C32打开

认识数据的存储方式

写好PE签名,然后剩下成员用58个00填充

写好了

 

 

 

 

 

参考编译器生成的程序

把存根的位置留出来

把NT头的PE标识写在后面

 

猜你喜欢

转载自blog.csdn.net/qq_41917908/article/details/81099220