from:http://www.2cto.com/Article/201203/123125.html

PE的意思就是这个the Protable Executable (PE) file format 微软搞得那么一套东西,字面意思是可移植的,但是现实使用中没见他多么的可移植,PE格式借鉴了UNIX系统中的COFF (Common Object File Format) 格式。而且PE对MS-Dos的兼容,保留了MS-Dos头,在dos下打开会提示 “这是win32程序在dos下不能跑” 向下兼容,非常的友好。
MS-DOS MZ header 的结构是这样的

typedef struct _IMAGE_DOS_HEADER {      // DOS .EXE header WORD   e_magic;                     // Magic number WORD   e_cblp;                      // Bytes on last page of file WORD   e_cp;                        // Pages in file WORD   e_crlc;                      // Relocations WORD   e_cparhdr;                   // Size of header in paragraphs WORD   e_minalloc;                  // Minimum extra paragraphs needed WORD   e_maxalloc;                  // Maximum extra paragraphs needed WORD   e_ss;                        // Initial (relative) SS value WORD   e_sp;                        // Initial SP value WORD   e_csum;                      // Checksum WORD   e_ip;                        // Initial IP value WORD   e_cs;                        // Initial (relative) CS value WORD   e_lfarlc;                    // File address of relocation table WORD   e_ovno;                      // Overlay number WORD   e_res[4];                    // Reserved words WORD   e_oemid;                     // OEM identifier (for e_oeminfo) WORD   e_oeminfo;                   // OEM information; e_oemid specific WORD   e_res2[10];                  // Reserved words LONG   e_lfanew;                    // File address of new exe header } IMAGE_DOS_HEADER, *PIMAGE_DOS_HEADER; 

其中比较关键的成员是这个e_lfanew 它指向了PE文件头在PE文件中的相对虚拟地址RAV(Relative Virtual Addresses),e_magic的值应该等于0x5A4D 是MS-DOS MZ header的标志MZ好像是个程序员名字的缩写 其他成员基本没啥大用,一些加壳软件会修改它的成员为自己的节腾出空间,或者在添加节形式感染时节表尾部的空隙不够写入一个新的解表结构的时候把IMAGE_DOS_HEADE 和IMAGE_NT_HEADER 融合。
可以自己写一个小程序来输出一下IMAGE_DOS_HEADE
IMAGE_DOS_HEADE这个结构体定义在windows.h中
系统加载PE格式的文件时,会先加载IMAGE_DOS_HEADE这个结构体,再根据结构体里的e_lfanew提供的相对偏移找到PE文件头。
 
用c语言可以直接读出IMAGE_DOS_HEADE这个结构体,下面开始写。
从文件的开始位置读取IMAGE_DOS_HEADE结构体
[cpp] view plaincopy
fread(&mydosheader,sizeof(mydosheader),1,p); 
吧文件指针移动到e_lfanew所指的相对偏移,即PE文件头
[cpp] view plaincopy
fseek(p,mydosheader.e_lfanew,SEEK_SET); 
读取PE文件标志,这个PE Signature是PE\0\0 这样一个值,证明它是PE格式的身份。
[cpp] view plaincopy
fread(&sig,4,1,p); 
这个判断中大写的变量都是,windows.h中的常数
IMAGE_NT_SIGNATURE 的值是PE\0\0
IMAGE_DOS_SIGNATURE 的值是MZ
具体的定义可以自己去windows.h中看

if((mydosheader.e_magic ==IMAGE_DOS_SIGNATURE) && 
       (sig == IMAGE_NT_SIGNATURE)) 
      printf("有效的PE文件/n"); 
   else 
     printf("无效的PE文件/n"); 
   return 0;

下面是完整的程序

#include "windows.h"
#include "stdio.h" int main(int argc, char* argv[])
{ FILE *p; IMAGE_DOS_HEADER mydosheader; unsigned long sig; p = fopen("test1.exe","r+b"); if(p == NULL)return -1; fread(&mydosheader,sizeof(mydosheader),1,p); fseek(p,mydosheader.e_lfanew,SEEK_SET); fread(&sig,4,1,p); fclose(p); printf("IMAGE_DOS_HEADER dump:/n"); printf("e_magic : %04x/n",mydosheader.e_magic); printf("e_cblp  : %04x/n",mydosheader.e_cblp); printf("e_cp   : %04x/n",mydosheader.e_cp); printf("e_crlc  : %04x/n",mydosheader.e_crlc); printf("e_cparhdr : %04x/n",mydosheader.e_cparhdr); printf("e_minalloc: %04x/n",mydosheader.e_minalloc); printf("e_maxalloc: %04x/n",mydosheader.e_maxalloc); printf("e_ss   : %04x/n",mydosheader.e_ss); printf("e_sp   : %04x/n",mydosheader.e_sp); printf("e_csum  : %04x/n",mydosheader.e_csum); printf("e_ip   : %04x/n",mydosheader.e_ip); printf("e_cs   : %04x/n",mydosheader.e_cs); printf("e_lfarlc : %04x/n",mydosheader.e_lfarlc); printf("e_ovno  : %04x/n",mydosheader.e_ovno); printf("e_res[0] : %04x/n",mydosheader.e_res[0]); printf("e_oemid : %04x/n",mydosheader.e_oemid); printf("e_oeminfo : %04x/n",mydosheader.e_oeminfo); printf("res2[0] : %04x/n",mydosheader.e_res2[0]); printf("lfanew  : %08x/n",mydosheader.e_lfanew); if((mydosheader.e_magic ==IMAGE_DOS_SIGNATURE) && (sig == IMAGE_NT_SIGNATURE)) printf("有效的PE文件/n"); else printf("无效的PE文件/n"); return 0;
} 

转载于:https://www.cnblogs.com/tk091/archive/2012/04/18/2456172.html

学破解 一 PE格式之MS-DOS MZ header相关推荐

  1. PE格式详细讲解4 - 系统篇04|解密系列

    PE格式详细讲解4 - 系统篇04 让编程改变世界 Change the world by program   到此为止,小甲鱼和大家已经学了许多关于 DOS header 和 PE header 的 ...

  2. PE格式详细讲解1 - 系统篇01|解密系列

    PE格式详细讲解1 - 系统篇01 让编程改变世界 Change the world by program 由于时间关系,这里只整理出必要的课件内容,详细请下载具体课件和详细讲解视频. [codesy ...

  3. 用dos命令破解网吧限制的方法和dos命令全集[color]

    用dos命令破解网吧限制的方法和dos命令全集[color] 这是我收集的破解网吧限制的一些方法仅供大家学习参考哈~~ 一:就是网吧限制本地硬盘的访问. 一般情况下这有两种可能,一种就是简单的隐藏掉, ...

  4. 写一个PE的壳_Part 5:PE格式修复+lief源码修改

    系列汇总 写一个PE的壳_Part 1:加载PE文件到内存 写一个PE的壳_Part 2:ASLR+修复输入表(IAT)+重定位表支持(.reloc) 写一个PE的壳_Part 3:Section里实 ...

  5. PE格式的定义头文件winnt.h

      PE格式定义的主要地方位于我们的头文件winnt.h,这个头文件中几乎能找到关于PE文件的所有定义.   在很多编译器.调试器中都会带有这个头文件,如VC++6.0.codeblocks.Olly ...

  6. PE 格式详解与试验

    PE 格式详解与试验 可执行文件结构分析 DOS头 文件头 可选头 PE RVA 地址与文件地址转换 块表 Section Header 导入表 Data Directory 基址重定位 reloc ...

  7. 7 Win98 MS—DOS

    第七章 Win98 MS-DOS ★MS-DOS方式的进入和退出 ★MS-DOS窗口的操作 ★DOS基本命令的使用 A) Ms-DOS方式 · 进入DOS的方法:"开始/程序/Ms-Dos方 ...

  8. PE格式: 分析IatHook并实现

    Ring 3层的 IAT HOOK 和 EAT HOOK 其原理是通过替换IAT表中函数的原始地址从而实现Hook的,与普通的 InlineHook 不太一样 IAT Hook 需要充分理解PE文件的 ...

  9. PE格式详细讲解11 - 系统篇11|解密系列

    PE格式详细讲解11 - 系统篇11 让编程改变世界 Change the world by program   今天我们来谈谈资源部分,资源部分可以说是 PE 文件所有结构中,最复杂的一部分,也最让 ...

最新文章

  1. easyUI 添加排序到datagrid
  2. JZOJ 3804. 【NOIP2014模拟8.24】小X 的AK 计划
  3. 实现竖式步骤条_【色彩大详解】最适合考生的水粉静物画法及步骤
  4. VTK:多行文本用法实战
  5. 怎么new一个指针_19. Go语言里的 make 和 new 有什么区别?
  6. Angular formControl指令定义的位置
  7. 10.热空气扭曲效果
  8. 不需要的系统垃圾把它杀掉!
  9. 中国顶级程序员图鉴,最后一个厉害了!
  10. VMware中ip地址消失问题
  11. java并发增强工具_0318 guava并发工具
  12. mac系统我的世界服务器,我的世界Mac版联机教程
  13. HH SaaS电商系统的虚拟资金账户(钱包余额)设计
  14. 宁向东管理课:自我力
  15. SQL代码建表时引用外键,有红线提示引用了无效的表
  16. 冷月手撕408之操作系统(3)-操作系统的发展及分类
  17. CSS核心内容:标准流、盒子模型、浮动、定位
  18. 微信小程之swiper
  19. Infiniband 和 以太网Ethernet 对比
  20. Activiti7-BPMN介绍

热门文章

  1. 互斥锁、自旋锁和自适应自旋锁
  2. Java StringBuffer与StringBuider
  3. 基于容器原理(docker、lxc、cells)的Android 双系统设计概要
  4. Android热更新方案Robust
  5. Java I/O 操作及优化建议
  6. Android L Settings 简要分析
  7. flume采集最简demo
  8. JZOJ 5305. 【NOIP2017提高A组模拟8.18】C
  9. vr体验馆项目_VR安全体验馆在江苏方洋项目推广应用啦!
  10. java web文件夹_JAVA WEB项目文件夹上传下载解决方案