吾爱破解 - 52pojie.cn

 找回密码
 注册[Register]

QQ登录

只需一步,快速开始

查看: 6493|回复: 33
收起左侧

[调试逆向] PE文件笔记三 DOS部分

  [复制链接]
lyl610abc 发表于 2021-3-26 23:58
本帖最后由 lyl610abc 于 2021-4-3 11:51 编辑

继续PE系列笔记的更新

PE其它笔记索引可前往:
PE文件笔记一 PE介绍


前面学习了PE结构的总体结构,接下来将具体学习PE的各个结构细节

这次学习的结构为DOS 部首

DOS部首

DOS部首结构

image-20210326211401967


image-20210326235719068


DOS部首结构 对应C中的结构体 说明
DOS 'MZ' HEADER _IMAGE_DOS_HEADER DOS MZ头 结构体
DOS stub DOS 存根

DOS MZ头

结构体截图

在winnt.h中找到_IMAGE_DOS_HEADER,得到以下截图(具体查找对应C结构体方法在PE文件笔记一 PE介绍中已经说明了,这里不再赘述)

image-20210326212749211


结构体代码

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;

结构体成员分析

_IMAGE_DOS_HEADER结构体的成员并不少,但在现在需要学习的只有两个

因为:

回顾

DOS部首,可以说是Windows的历史遗留问题了,因为Windows程序最早是在DOS系统(16位系统)上运行的

所以该部分主要是给DOS用的(向下兼容)


更新

目前在32位或64位 WINDOWS系统上还有效的只有两个成员了:

  • 第一个成员:e_magic
  • 最后一个成员:e_lfanew

成员详情
成员 数据宽度 注释 说明
e_magic WORD(2字节) Magic number PE文件判断标识 固定为4d 5a (ASCII='MZ')
e_lfanew LONG(4字节) File address of new exe header 存储PE头首地址 不定

验证其余成员无效性

前面说到在目前的系统中,只有两个成员是有效的,为验证这一点,将其余成员全部置为0试试

1.用WinHex或UltraEdit等十六进制编辑器打开一个程序

这里采用WinHex进行操作,并选中其余成员部分

image-20210326223305500


2.将选中的部分,也就是其余成员部分全部修改为0

右键→编辑→填充选块 (快捷键Ctrl+L)

image-20210326224239328


image-20210326224313607


image-20210326224403422


确定修改后:

image-20210326224440179


3.保存修改的文件

文件→保存(快捷键Ctrl+S)

image-20210326224522965


image-20210326224557452


4.执行修改后的文件

image-20210326220814513


可以看到程序仍然可以正常运行,验证了:其余成员在32位及以上的Windows系统中无效

Dos Stub

Dos Stub在32位及以上的Windows系统中其实也无效,但不妨研究一下他的作用

1.截取出Dos Stub部分的数据

image-20210326224705523

选中部分为Dos Stub,其数据范围由_IMAGE_DOS_HEADER结构体中的最后一个成员e_lfanew决定


2.复制选中部分也就是Dos Stub部分的数据

image-20210326224751035


3.将数据粘贴到记事本中

image-20210326225328310


对应数据

0E1FBA0E00B409CD21B8014CCD21546869732070726F6772616D2063616E6E6F742062652072756E20696E20444F53206D6F64652E0D0D0A2400000000000000FD661975B9077726B9077726B90777260448E126BB077726B07FE226A2077726A755F326BE077726B07FE426A6077726B9077626E8057726B07FF4267D077726B07FF32651077726A755E326B8077726B907E026BB077726B07FE626B807772652696368B90777260000000000000000

对应数据反汇编

PUSH CS
POP DS
MOV DX,000E
MOV AH,09
INT 21
MOV AX,4C01
INT 21
DB 54
DB 68
DB 69
DB 00
DB 33
DB 70
……

通过16位的反汇编引擎即可得到对应的反汇编代码

这里我们主要关注DB段,也就是汇编中数据段部分有DB 54;DB 68;DB 69 ……

在WINHEX中找到其对应的数据部分,查看其对应的ASCII

image-20210326231526001


数据部分为This program cannot be run in DOS

结合前面的两个INT 21 中断 不难猜测出该段数据对应的16位反汇编为输出数据部分的内容:This program cannot be run in DOS

自写代码解析DOS MZ头

了解了DOS部首的结构以后就可以自己写代码来读取DOS MZ头了

代码

// PE.cpp : Defines the entry point for the console application.
//

#include "stdafx.h"

#include <malloc.h>
#include <windows.h>

int main(int argc, char* argv[])
{
    //创建DOS对应的结构体指针
        _IMAGE_DOS_HEADER* dos;
    //读取文件,返回文件句柄
        HANDLE hFile = CreateFileA("C:\\Documents and Settings\\Administrator\\桌面\\dbghelp.dll",GENERIC_READ,FILE_SHARE_READ,NULL,OPEN_EXISTING,0,0);
    //根据文件句柄创建映射
        HANDLE hMap = CreateFileMappingA(hFile,NULL,PAGE_READONLY,0,0,0);
    //映射内容
        LPVOID pFile = MapViewOfFile(hMap,FILE_MAP_READ,0,0,0);
    //类型转换,用结构体的方式来读取
        dos=(_IMAGE_DOS_HEADER*)pFile;
    //输出结构体的第一个成员,以十六进制输出
        printf("%X\n",dos->e_magic);
        return 0;
}

运行结果

image-20210326234752508

可以看到能够正确地得到DOS MZ头对应的第一个成员的值:5A4D(对应ASCII为MZ)


总结

  • DOS部首分为两部分:DOS 'MZ' HEADER 和 DOS stub
  • DOS 'MZ' HEADER对应的结构体_IMAGE_DOS_HEADER中仅第一个成员和最后一个成员在32位及以上的WINDOWS系统上有效
  • DOS Stub对应为一串反汇编代码,其功能和输出This program cannot be run in DOS相关
  • DOS 'MZ' HEADER中无效的成员部分可用来填充shellcode来达到其它目的

附件

附上本笔记中分析的EverEdit文件:点我下载

免费评分

参与人数 15吾爱币 +20 热心值 +14 收起 理由
wangzhenuen + 1 + 1 热心回复!
Hmily + 7 + 1 欢迎分析讨论交流,吾爱破解论坛有你更精彩!
Alutemurat + 1 + 1 谢谢@Thanks!
gzshlp + 1 我很赞同!
aabbgl + 1 热心回复!
国际豆哥 + 1 + 1 感谢发布原创作品,吾爱破解论坛因你更精彩!
skyward + 1 + 1 我很赞同!
debug_cat + 1 + 1 来个大佬打call,我是001号粉丝
努力加载中 + 1 + 1 热心回复!
bailemenmlbj + 1 + 1 谢谢@Thanks!
波澜VAN + 1 + 1 我很赞同!
hxw0204 + 1 + 1 热心回复!
woyucheng + 1 + 1 谢谢@Thanks!
kdrew + 1 + 1 我很赞同!
为之奈何? + 1 + 1 我很赞同!

查看全部评分

发帖前要善用论坛搜索功能,那里可能会有你要找的答案或者已经有人发布过相同内容了,请勿重复发帖。

 楼主| lyl610abc 发表于 2021-3-28 14:25
本帖最后由 lyl610abc 于 2021-3-30 16:40 编辑
布衣木人 发表于 2021-3-28 14:15
最好在64位机器上写,同时最好用下vs

代码是通用的,编译环境不同而已
同样的代码,在VS 2019  win10 x64下也是可以运行的
a.png
 楼主| lyl610abc 发表于 2021-4-6 12:44
aswcy815174418 发表于 2021-4-6 12:39
输出完5a4d后不得CloseHandle嘛

只是读取,读取完程序都停止运行了,这个也只是个demo,我也就懒得加了
出于程序结构的完整性应该是要CloseHandle的
除了CloseHandle还要UnmapViewOfFile
布衣木人 发表于 2021-3-28 15:16
lyl610abc 发表于 2021-3-28 14:25
代码是通用的,编译环境不同而已
同样的代码,在VS 2019  win10 x64下也是可以运行的

pStrNtHeaders->OptionalHeader.Magic;这个值0x10b、0x20b等,就要区分了,IMAGE_NT_HEADERS、IMAGE_NT_HEADERS64里面的结构就不一样了。所以不如直接用你现在的vs2019

免费评分

参与人数 1吾爱币 +1 热心值 +1 收起 理由
lyl610abc + 1 + 1 感谢您的宝贵建议,我们会努力争取做得更好!

查看全部评分

dukeimp 发表于 2021-3-27 00:20
模板大佬
a970826 发表于 2021-3-27 00:30
膜拜大佬。感谢分享
qianshang666 发表于 2021-3-27 06:33
点名表扬,更新的非常nice
fly19930620 发表于 2021-3-27 08:09
学习下看看
Redfiremaple 发表于 2021-3-27 08:44
先收藏,感谢分享。
helanzhu1 发表于 2021-3-27 09:26
感谢分享
平头哥头不平 发表于 2021-3-27 09:43
膜拜大佬。感谢分享
宜城小站 发表于 2021-3-27 10:18
感谢分享
学习
xjh123456 发表于 2021-3-27 16:09

感谢分享
学习
您需要登录后才可以回帖 登录 | 注册[Register]

本版积分规则

返回列表

RSS订阅|小黑屋|处罚记录|联系我们|吾爱破解 - LCG - LSG ( 京ICP备16042023号 | 京公网安备 11010502030087号 )

GMT+8, 2024-11-21 16:47

Powered by Discuz!

Copyright © 2001-2020, Tencent Cloud.

快速回复 返回顶部 返回列表