千家信息网

win32下PE文件分析之DOS头

发表于:2024-10-02 作者:千家信息网编辑
千家信息网最后更新 2024年10月02日,(一).win32下的PE文件:PE是Portable Execute的缩写,是可移植可执行的意思,只要文件的数据结构遵循PE结构,就属于PE文件,windows中常见的PE文件有*.sys驱动类文件
千家信息网最后更新 2024年10月02日win32下PE文件分析之DOS头

(一).win32下的PE文件:

PE是Portable Execute的缩写,是可移植可执行的意思,只要文件的数据结构遵循PE结构,就属于PE文件,windows中常见的PE文件有

*.sys驱动类文件

*.dll动态链接库文件

*.exe可执行文件

*.ocx对象类别扩充组建

*.obj目标文件等.

同样,linux中使用的是ELF格式,和windows的PE格式有一定的差别,如:

可重定位文件*.o

可执行文件如/bin/ls等

共享目标文件*.so

核心转储文件core

都遵循ELF数据结构. unix从system v4开始也使用ELF了,而他们的始祖都是unix system v3的中COFF.如下图:

(二).win32中的PE文件二进制数据结构:

二进制数据结构如下图,看起来就比较复杂,但是当你亲自动手解析一波,那可能会改变你的世界观,前提是初学者.为了全部显示出来,看不太清,放附件里了.

(三).win32中PE的逻辑图:

一个标准的PE文件由DOS头,stub,NT头(包含PE标识,标准PE头和可选PE头三个成员),节表,节的内容以及一些为了内存对齐而填充的0.

以上就是一个PE文件的大体逻辑图,它里面的内容虽然是二进制,但绝不是随意填充的数据,而是严格遵循一定格式生成的,比如C语言写的一段代码,通过预处理, 汇编, 编译, 链接后生成的一个exe文件(PE文件中的一种),生成过程是由编译器来完成的.

(四).DOS头中的数据结构:

Visual C++ 6.0中winnt头文件中的定义:

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;

(五).C语言实现对win32中notepad.exe的DOS头的简单解析:

该代码中只是输出了DOS头中两个较为有用的数据,第一个和最后一个(e_magic和e_lfanew),代码如下:

Dos_Header_Analyze.cpp:


// Dos_Header_Analyze.cpp : Defines the entry point for the console application.//#include "stdafx.h"#include "dos.h"           //包含进自己写的dos.h文件#define filepath "notepad.exe"        //指定好notepad.exe的位置,写绝对路径,或放于源代码目录中int main(int argc, char* argv[]){        void* pbuff = NULL;                              //方便后面当参数使用        pbuff = ReadFileToBuff(filepath);        Output_Dos(pbuff);                              //解析DOS头        free(pbuff);                                    //释放空间        return 0;}

dos.h:

void* ReadFileToBuff(char* file)       //将文件读取到内存{        FILE* fp = fopen(file, "rb");       //以二进制只读形式打开文件        void* buff = NULL;               //用来指向申请的内存缓冲区        unsigned long sz = 0;               //用来存放文件的大小        if(!fp)        {                printf("Failed to open file \"%s\"\n", file);                exit(-1);        }        fseek(fp, 0, SEEK_END);             //让文件指针fp指向文件的末位位置,用于计算文件的大小        sz = ftell(fp);                     //获取当前文件指针相对于起始位置的偏移        fseek(fp, 0, SEEK_SET);             //让文件指针fp指向文件的起始位置        printf("File \"%s\" size: %ld KB\n", file, sz / 1024);  //输出文件大小(单位KB)        buff = malloc(sz);          //申请一块与文件大小相等的内存,用作文件缓冲区        if(!buff)        {                printf("Alloc memery failed!\n");                exit(-2)        }        memset(buff, 0, sz);           //置零缓冲区                //将文件中的数据写入文件缓冲区,每次读取128字节,读取sz/128次,正好读取sz字节        if(!fread(buff, 128, sz/128, fp))         {                printf("Read file \"%s\" error!\n", file);                exit(-3);        }        fclose(fp);                     //关闭刚刚打开的文件        return buff;                       //返回文件缓冲的内存地址                                           }//输出DOS头的重要信息void Output_Dos(void* buffer){        void* buf = buffer;        //定义一个指向文件缓冲的DOS头的指针        IMAGE_DOS_HEADER* pdos = (IMAGE_DOS_HEADER*)buf;        printf("DOS Header:\n");                //MZ标记,用于判断该文件是否为可执行文件(其值与MZ的ascii相对应)        printf("Magic Number:      %#X\n", pdos->e_magic);                //PE标识相对于文件其实位置的偏移 (单位字节)          printf("PE   Offset:     %#X\n", pdos->e_lfanew);                }

stdafx.h:

#if !defined(AFX_STDAFX_H__BBCA9272_49A3_4E1E_9262_9F0211C5BA05__INCLUDED_)#define AFX_STDAFX_H__BBCA9272_49A3_4E1E_9262_9F0211C5BA05__INCLUDED_#if _MSC_VER > 1000#pragma once#endif // _MSC_VER > 1000#define WIN32_LEAN_AND_MEAN                // Exclude rarely-used stuff from Windows headers//主要是把相应的头文件包含进去#include #include #include #include 

执行结果如下图:


如果有空会继续更新.


附件:http://down.51cto.com/data/2366651
文件 数据 结构 缓冲 位置 内存 数据结构 二进制 大小 指向 指针 缓冲区 代码 字节 格式 输出 内容 单位 标准 标识 数据库的安全要保护哪些东西 数据库安全各自的含义是什么 生产安全数据库录入 数据库的安全性及管理 数据库安全策略包含哪些 海淀数据库安全审计系统 建立农村房屋安全信息数据库 易用的数据库客户端支持安全管理 连接数据库失败ssl安全错误 数据库的锁怎样保障安全 福建企业软件开发零售价格 数据库联合主键怎么查询 学校关于网络安全的手抄报 java的内存式数据库 关注网络安全事项 杭州络町网络技术有限公司 存储矢量的数据库 琼山手机软件开发 新余企业服务器要多少钱 计算机网络技术初学者一道题 标签bartender数据库 津京互联网科科技生态城 列值数据库 软件开发代名词 沈阳安卓软件开发公司哪家好 dzay连接至服务器失败怎么办 博易大师模拟交易代理服务器设置 米花同城6.6.20数据库 大数据软件开发和测试 广东广电网络优点家庭服务器红灯 数据库及其查询的实验总结 数据库技术的发展有什么影响 神州数码网络安全部 网络技术和数据库技术的区别 计算机网络技术学校要分数吗 奥丁神判台服服务器忙 手机app如何开发服务器 怎么查看服务器是不是物理机器 国产磁力数据库cilidb 互联网金融软件开发方向
0