第二讲,NT头文件格式,以及文件头格式
今天详解NT 头格式,以及文件头格式,以及作用, 关于DOS头文件格式,以及DOSStub昨天的博客已经写过了.主要是分散讲解.便于理解.
一丶最小PE的生成,以及标准PE的生成
ps: (如果直接学习NT头,文件头,请不用看这个生成PE,直接看下面讲解即可)
1.标准PE的生成
为了便于学习PE文件格式,所以这里写出一个最小PE,还有一个最小的标准PE,让大家理解.
32位汇编编写.(汇编是能编写最小PE的)
首先我们先写一段基本的汇编代码,然后一层一层的优化
32位汇编代码:
.model flat,stdcall
option casemap:none include windows.inc
include user32.inc
include kernel32.inc ;包含各种lib库以及头文件
includelib user32.lib
includelib kernel32.lib .data
g_szHello db "Hello",0dh,0ah, ;定义Hello字符串
.code
start:
invoke MessageBoxA,NULL,offset g_szHello ,NULL,MB_OK ;弹出信息框
invoke ExitProcess, ;退出程序
end start
很简单的汇编代码
看下EXE的大小,以及内容

2.50KB有点大了.
可以继续优化,但是比如手动敲命令行了.注意,这里使用的masm32的link连接器
首先我们要去掉分区,因为这里的EXE主要是分区太多.所以去掉.
怎么去掉? 只需要把上面的汇编代码修改一下即可.
修改为:
.model flat,stdcall
option casemap:none include windows.inc
include user32.inc
include kernel32.inc
includelib user32.lib
includelib kernel32.lib .code
g_szHello db "Hello",0dh,0ah, ;将数据段的数据,放到代码区中
start:
invoke MessageBoxA,NULL,offset g_szHello ,NULL,MB_OK
invoke ExitProcess,
end start
很简单,就是把.data去掉即可.
这个就是标准PE了,看下文件大小.

注意一下,这里我使用的是RadAsm集成开发环境,
编译器是Masm32的link连接器. 如果使用VC6.0以及以上的,文件会变的很大,可能会有16.KB,28.KB,不利于大家学习.如果不会配置RadAsm集成开发环境,请参考以前的帖子.自己配置一下即可.
2.最小PE的生成
区合并和内存对齐优化,生成最小PE(不通用)
首先我们要知道PE中的区在哪里,以及怎么使内存对齐缩小,不至于让PE很大.
首先看下我们的标准PE格式的二进制.(使用Winhex,或者010 Editor都可以)

可以看出,生成的时候默认会为我们生成.const常量区,那么我们可以让它和代码区合并吗?
注意,如果是别的程序,是不可以合并的,因为常量区很有用,但是如果生成最小PE那么你需要合并,
最后一个Hello的位置,则是代码区
手工连接,使其合并分区,变为最小PE
命令行参数

/ALIGN:内存对齐(2的倍数即可,默认是4096)
/MERGE: 区 = 区 (合并分区)
例如link加上 写成下面这样
/ALIGN:4 /MERGE:.rdata=.text
手工编译连接看下.

不过这样写还要另外加选项,不能保证她是否是能运行,不通用,所以使用标准pe讲解
二丶NT头
首先看下NT头和文件头的结构体.
NT头:
typedef struct _IMAGE_NT_HEADERS {
DWORD Signature; //4个字节的PE标志
IMAGE_FILE_HEADER FileHeader; //文件头
IMAGE_OPTIONAL_HEADER32 OptionalHeader;//可选头
} IMAGE_NT_HEADERS32, *PIMAGE_NT_HEADERS32;
NT 头第一个成员,对应的是PE位置,4个字节.
内存分布图:

在这里,建议大家使用010编辑器,可以使用自定义PE模版,解析PE各个位置内容.

下面模版自动点击则可以解析
三丶文件头
文件头结构体:
typedef struct _IMAGE_FILE_HEADER {
WORD Machine; //机器型号,作用是区别这个exe是哪个CPU可以跑的.重要.
WORD NumberOfSections; //节的数量 (可以理解为汇编中区的个数)现在我们有两个,一个.rdata 一个.text
DWORD TimeDateStamp; //程序的编译时间,参考用,没有实际作用
DWORD PointerToSymbolTable; //符号表地址 我们使用的PDB文件(里面有函数吗什么的)都存放在这个表中,不过微软是单独生成的PDB文件,所以这个字段没用,主要是给别人用
DWORD NumberOfSymbols; //符号表大小
WORD SizeOfOptionalHeader; //可选头大小,这个字段很重要.因为要通过这个字段,才知道可选头是多大,而不懂PE的人求选项头都是用sizeof()求出来的.所以真正的选项头大小要靠这个字段
WORD Characteristics; //文件属性,描述文件信息的.
} IMAGE_FILE_HEADER, *PIMAGE_FILE_HEADER;
上面只是简单的写了下各个成员的作用.
在这里需要注意的是 可选头大小,文件属性,以及机器型号. 其余的自己看看.
1.机器型号:
机器型号,在PE中的定义,在VC++6.0中已经给出了.
代码:
#define IMAGE_FILE_MACHINE_UNKNOWN 0
#define IMAGE_FILE_MACHINE_I386 0x014c // Intel 386.
#define IMAGE_FILE_MACHINE_R3000 0x0162 // MIPS little-endian, 0x160 big-endian
#define IMAGE_FILE_MACHINE_R4000 0x0166 // MIPS little-endian
#define IMAGE_FILE_MACHINE_R10000 0x0168 // MIPS little-endian
#define IMAGE_FILE_MACHINE_WCEMIPSV2 0x0169 // MIPS little-endian WCE v2
#define IMAGE_FILE_MACHINE_ALPHA 0x0184 // Alpha_AXP
#define IMAGE_FILE_MACHINE_POWERPC 0x01F0 // IBM PowerPC Little-Endian
#define IMAGE_FILE_MACHINE_SH3 0x01a2 // SH3 little-endian
#define IMAGE_FILE_MACHINE_SH3E 0x01a4 // SH3E little-endian
#define IMAGE_FILE_MACHINE_SH4 0x01a6 // SH4 little-endian
#define IMAGE_FILE_MACHINE_ARM 0x01c0 // ARM Little-Endian
#define IMAGE_FILE_MACHINE_THUMB 0x01c2
#define IMAGE_FILE_MACHINE_IA64 0x0200 // Intel 64
#define IMAGE_FILE_MACHINE_MIPS16 0x0266 // MIPS
#define IMAGE_FILE_MACHINE_MIPSFPU 0x0366 // MIPS
#define IMAGE_FILE_MACHINE_MIPSFPU16 0x0466 // MIPS
#define IMAGE_FILE_MACHINE_ALPHA64 0x0284 // ALPHA64
看下PE中怎么存储的.

按照小尾方式,则是 0x014C ,那么对应上面的宏则是386的程序(看注释),而我们的汇编编译出来的标准PE也正是标准PE,如果学习PE,自己可以去看下PE存储。
2.可选头大小

这个地方是我计算偏移得出,根据结构体的类型大小,可以自己计算偏移得出.
可以看出,可选头的大小是0x00E0 大小,换算成10进制就可以知道,E0是224字节大小,所以根据这个,可以计算出可选头大小
3.文件属性
文件属性紧跟在E0 00 后面,它是0F 01
文件属性是按照位来的.
什么意思?
先看下宏定义:
#define IMAGE_FILE_RELOCS_STRIPPED 0x0001 // Relocation info stripped from file.
#define IMAGE_FILE_EXECUTABLE_IMAGE 0x0002 // File is executable (i.e. no unresolved externel references).
#define IMAGE_FILE_LINE_NUMS_STRIPPED 0x0004 // Line nunbers stripped from file.
#define IMAGE_FILE_LOCAL_SYMS_STRIPPED 0x0008 // Local symbols stripped from file.
#define IMAGE_FILE_AGGRESIVE_WS_TRIM 0x0010 // Agressively trim working set
#define IMAGE_FILE_LARGE_ADDRESS_AWARE 0x0020 // App can handle >2gb addresses
#define IMAGE_FILE_BYTES_REVERSED_LO 0x0080 // Bytes of machine word are reversed.
#define IMAGE_FILE_32BIT_MACHINE 0x0100 // 32 bit word machine.
#define IMAGE_FILE_DEBUG_STRIPPED 0x0200 // Debugging info stripped from file in .DBG file
#define IMAGE_FILE_REMOVABLE_RUN_FROM_SWAP 0x0400 // If Image is on removable media, copy and run from the swap file.
#define IMAGE_FILE_NET_RUN_FROM_SWAP 0x0800 // If Image is on Net, copy and run from the swap file.
#define IMAGE_FILE_SYSTEM 0x1000 // System File.
#define IMAGE_FILE_DLL 0x2000 // File is a DLL.
#define IMAGE_FILE_UP_SYSTEM_ONLY 0x4000 // File should only be run on a UP machine
#define IMAGE_FILE_BYTES_REVERSED_HI 0x8000 // Bytes of machine word are reversed.
首先按照小尾方式查看.
0x010f
那么先看第一个1,不看后面的,找百位为1的那么就是 0x100 在上面则可以找到对应的宏,它的注释是:
32 bit word machine. 代表了他是一个32位程序
那么看个位是F,那么就找F,但是需要注意,他因为是位运算,所以是 | 连接起来了,那么F 代表了
0x0001 | 0x0002 | 0x0004 |
0x0008 那么分别就对应前4个宏
那么最终想要表示的结果是
32 bit word machine.
Relocation info stripped from file.
File is executable (i.e. no
unresolved externel references)
Line nunbers stripped from file
Local symbols stripped from file.
翻译过来就是 这是一个32位程序,是一个可执行程序....
那么训练一下,我随便写一个
0x2102
那么 按照 个 十 百 千 位去寻找
先找千位 0x2000 //
File is a DLL. 说明这是一个DLL文件
再找百位 0x100 // 32 bit word
machine. 说明是一个32位可执行程序
再找十位 十位为零,则没有.
再找个位 0x0002 //
File is executable (i.e. no unresolved
externel references). 说明是一个可执行程序
那么总结一下,说明了这个文件是一个 DLL文件,是一个32位程序,是一个可执行程序
总的来说很简单,主要是熟练运用,在不使用工具的前提下,明白各个位置代表的作用。
参考于:
http://www.cnblogs.com/iBinary/
第二讲,NT头文件格式,以及文件头格式的更多相关文章
- PE文件格式详解,第二讲,NT头文件格式,以及文件头格式
PE文件格式详解,第二讲,NT头文件格式,以及文件头格式 作者:IBinary出处:http://www.cnblogs.com/iBinary/版权所有,欢迎保留原文链接进行转载:) PS:本篇博客 ...
- PE文件格式详解,第一讲,DOS头文件格式
PE文件格式详解,第一讲,DOS头文件格式 今天讲解PE文件格式的DOS头文件格式 首先我们要理解,什么是文件格式,我们常说的EXE可执行程序,就是一个文件格式,那么我们要了解它里面到底存了什么内容 ...
- 第一讲,DOS头文件格式
今天讲解PE文件格式的DOS头文件格式 首先我们要理解,什么是文件格式,我们常说的EXE可执行程序,就是一个文件格式,那么我们要了解它里面到底存了什么内容 简短的说明. 我们要知道,PE文件格式,是微 ...
- Visual Studio+VAssistX自动添加注释,函数头注释,文件头注释
转载:http://blog.csdn.net/xzytl60937234/article/details/70455777 在VAssistX中为C++提供了比较规范注释模板,用这个注释模板为编写的 ...
- PE文件头格式解析
前言: 昨天写了一题de1ctf的题,发现要脱壳,手脱之后发现要iat修复,我就发现自己在这块知识缺失了,win逆向,好像一直都是打ctf,然后用逆向方法论去肝的 其他方面倒是没有很深入学习,但实际上 ...
- MP3文件头格式
MP3文件结构及编解码流程 http://blog.sina.com.cn/s/blog_67b7cb7b01018i2l.html http://blog.csdn.net/liuyan4794/a ...
- 【转】python通过文件头判断文件类型
刚刚看到一个好玩的程序,拉过来.原文地址:https://www.ttlsa.com/python/determine-file-type-by-the-file-header/ 侵权删. ===== ...
- VA中用文件头注释和函数头注释Suggestions
写C++代码,不能不用VA,这里贴两个我最常用的注释Suggestions. [1.File Header 文件头注释] /*** @file $FILE_BASE$.$FILE_EXT$* ...
- PHP文件头BOM头问题
前几天我们公司服务器出现了一个离奇的问题,服务器与本地文件代码完全一致,本地运行正常,到了测试环境服务器之后,各种问题一个又一个浮现,先是后台验证码不显示,以为是session写入失败,又是怀疑gd库 ...
随机推荐
- make 和 make install 的区别
简单来说,make 是编译,make install 是安装. 总结:linux编译安装中configure.make和make install各自的作用 ./configure是用来检测你的安装平台 ...
- Java锁优化
Java锁优化 应用程序在并发环境下会产生很多问题,通常情况下,我们可以通过加锁来解决多线程对临界资源的访问问题.但是加锁往往会成为系统的瓶颈,因为加锁和释放锁会涉及到与操作系统的交互,会有很大的性能 ...
- arcgis python 删除一个数据库所有数据
# -*- coding: cp936 -*- import xlrd # must init xlrd import arcpy import os def main(): arcpy.env.wo ...
- idea 拉取git新分支
前面的话: 一不小心,删除了dev的分支,没办法.头头重新克隆了下,但是发现idea的右下角并没有啊,我记得之前遇到过一次 但还是忘记如何操作了,在这记录下,省的下次还得去百度 选中项目-git-fe ...
- Kotlin入门-文件读写操作
转 https://blog.csdn.net/aqi00/article/details/83241762 Java的文件处理用到了io库java.io,该库虽然功能强大,但是与文件内容的交互还得通 ...
- WPF清爽酷炫的界面Mahapps.metro
最近WPF项目中要求软件的风格要传统化一点,查阅了下资料发现了Mahapps.metro. 官网 http://mahapps.com/ 下面是官方的DOME,https://github.com/M ...
- c++ string构造函数学习
#include <iostream>#include <string> using namespace std; int main(){ string a1; cout &l ...
- 详解用python实现简单的遗传算法
详解用python实现简单的遗传算法 今天整理之前写的代码,发现在做数模期间写的用python实现的遗传算法,感觉还是挺有意思的,就拿出来分享一下. 首先遗传算法是一种优化算法,通过模拟基因的优胜劣汰 ...
- Python中bytes与字符串的相互转化
代码: # bytes转字符串方式一 b=b'\xe9\x80\x86\xe7\x81\xab' string=str(b,'utf-8') print(string) # bytes转字符串方式二 ...
- Reset Password 重置密码 (CentOS 5,6,7 ; Juniper Networks: SRX100 )
一些重置root 密码的文档分享(来自官网): CentOS 5,6,7 Juniper Networks : SRX100 链接:https://share.weiyun.com/5BM4kwK ...