首页 > 其他分享 >PeView 命令行PE文件解析工具

PeView 命令行PE文件解析工具

时间:2024-10-29 19:46:52浏览次数:9  
标签:00 PeView PE 00000000 地址 命令行 Pe -- View

PeView 是一款基于C/C++开发的命令行版PE文件解析工具,专门用于解析Windows可执行文件并提供详尽的文件结构和交互式查询功能,帮助用户理解和分析目标程序的内部构成,是逆向分析和软件调试中的重要工具,本次分享工具源代码及使用方法,读者可根据自己的需要参考学习,并以此来更好的理解PE文件格式的构成。

在这里插入图片描述

该命令行工具提供了广泛的功能,可以查看文件结构(如DOS头、NT头、数据目录、节表)、导入导出表信息、重定位表内容,以及检测资源和执行地址转换。此外,工具还包括内置计算器功能(加法、减法)、检查文件自身的保护方式或签名验证,并提供特征识别和获取DLL函数地址的能力,满足各种PE文件分析和调试需求。

查询DOS/NT结构

DOS头和NT头是PE文件格式的关键组成部分。DOS头位于文件开头,以“MZ”标识,包含指向PE头的偏移量。NT头紧随其后,包含文件签名、文件头(如目标架构和节数量)以及可选头(如入口点地址和映像基地址)。这两部分共同提供了Windows操作系统加载和执行可执行文件及动态链接库所需的结构信息。

1. DOS头(DOS Header)
  • 位置:PE文件的开头。
  • 标识符:以“MZ”开头,表示可执行文件。
  • 主要字段
    • e_lfanew:指向NT头的偏移量,帮助定位后续的PE结构。
2. NT头(NT Header)
  • 位置:紧跟在DOS头后。
  • 组成部分
    • Signature:通常为“PE\0\0”,确认文件格式为PE。
    • File Header
      • Machine:目标架构(如x86、x64)。
      • NumberOfSections:节的数量。
      • TimeDateStamp:文件的时间戳,标识文件创建或修改的时间。
      • PointerToSymbolTable:符号表的指针(通常为0)。
      • NumberOfSymbols:符号数量(通常为0)。
      • SizeOfOptionalHeader:可选头的大小。
      • Characteristics:文件特性,如是否可执行、是否为DLL等。
    • Optional Header
      • Magic:指示头的类型(32位或64位)。
      • AddressOfEntryPoint:程序的入口点地址,加载时会从这里开始执行。
      • ImageBase:映像基地址,指明程序在内存中加载的起始地址。
      • SectionAlignmentFileAlignment:节的对齐方式,确保在内存中和文件中结构的一致性。
      • SizeOfImageSizeOfHeaders:映像和头部的总大小,用于内存分配。
3. 查询DOS/NT结构

DOS/NT头的查询非常简单,首先可以使用Open命令打开对应的可执行文件,当文件被打开后,使用Dos命令可查询DOS头部数据,使用Nt命令则可查询NT头部数据,如下输出所示;

C:\>peview
[Pe View] # Open --path d://lyshark.exe
[+] 已读入文件
[Pe View] # Dos
----------------------------------------------------------------------
                         十六进制        十进制
----------------------------------------------------------------------
DOS标志:               00005A4D       00023117
文件最后一页的字节数:     00000090       00000144
文件中的页面:           00000003       00000003
重定位:                 00000000       00000000
段落中标题的大小:         00000004       00000004
至少需要额外段落:         00000000       00000000
所需的最大额外段落数:      0000FFFF       00065535
初始(相对)SS值:         00000000       00000000
初始SP值:               000000B8       00000184
校验和:                   00000000       00000000
初始IP值:                 00000000       00000000
初始(相对)CS值:         00000000       00000000
重新定位表的文件地址:     00000040       00000064
叠加编号:                 00000000       00000000
保留字:                   0010001C       01048604
OEM标识符                 00000000       00000000
OEM信息                   00100028       01048616
PE指针:                   00000100       00000256
----------------------------------------------------------------------
[Pe View] # Nt
----------------------------------------------------------------------
                         十六进制        十进制
----------------------------------------------------------------------
NT标志:               0x00004550         00017744
运行平台:             0x0000014C         00000332
区段数目:            0x00000005         00000005
时间日期标志:        0x669481D8         1721008600
特征值:              0x00000102         00000258
可选头部大小:        0x000000E0         00000224
文件符号标志:        0x00000000         00000000
文件符号指针:        0x00000000         00000000
入口点:              0x0000158B         00005515
镜像基址:            0x00400000         04194304
镜像大小:            0x00007000         00028672
代码基址:            0x00001000         00004096
内存对齐:            0x00001000         00004096
文件对齐:            0x00000200         00000512
子系统:              0x00000002         00000002
首部大小:            0x00000400         00001024
校验和:              0x00000000         00000000
RVA 数及大小:        0x00000010         00000016
主操作系统版本:      0x00000006         00000006
从操作系统版本:      0x00000000         00000000
主映像版本:          0x00000000         00000000
从映像版本:          0x00000000         00000000
主子系统版本:        0x00000006         00000006
从子系统版本:        0x00000000         00000000
Win32版本:           0x00000000         00000000
DLL标识:             0x00008140         00033088
SizeOfStackReserve:  0x00100000         01048576
SizeOfStackCommit:   0x00001000         00004096
SizeOfHeapReserve:   0x00100000         01048576
SizeOfHeapCommit:    0x00001000         00004096
LoaderFlags:         0x00000000         00000000
----------------------------------------------------------------------

查询数据目录表结构

数据目录表位于可选头中。它包含一系列指向各种重要数据结构的指针,如导入表、导出表、资源表、异常表和证书表等。每个条目都定义了对应数据的虚拟地址和大小,帮助操作系统在加载时找到和管理这些数据,确保程序的正常运行和功能调用。

1. 位置
  • 可选头:数据目录表通常位于PE文件的可选头部分,具体在NT头之后。
2. 结构

数据目录表由一组结构体组成,每个结构体表示一个特定的数据目录项。每个条目包含两个字段:

  • Virtual Address:指向数据在内存中的虚拟地址。
  • Size:数据的大小(以字节为单位)。
3. 常见数据目录项

以下是一些常见的数据目录项:

目录索引数据目录项描述
0Export Table导出表,用于列出可用的外部函数
1Import Table导入表,记录外部依赖
2Resource Table资源表,包含图标、字符串等资源
3Exception Table异常表,存储异常处理信息
4Certificate Table证书表,用于存储签名信息
5Base Relocation重定位表,处理地址重定位
6Debug Directory调试目录,用于调试信息
7Architecture架构表,针对特定架构的信息
8Global Pointer全局指针表
9TLS Directory线程局部存储目录
10Load Configuration加载配置表
4. 查询数据目录表结构

查询数据目录表,可在文件被打开状态下,通过执行DataDirectory命令获取,其输出信息中包括了,目录RVA目录FOASize长度功能描述等基本信息,如下输出所示;

[Pe View] # DataDirectory
--------------------------------------------------------------------------------------------------------------
编号     目录RVA         目录FOA         Size长度(十进制)        Size长度(十六进制)      功能描述
--------------------------------------------------------------------------------------------------------------
001      0x00000000      0xFFFFFFFF      00000000                0x00000000             Export symbols
002      0x000022A4      0x000012A4      00000080                0x00000050             Import symbols
003      0x00004000      0x00001A00      00007600                0x00001DB0             Resources
004      0x00000000      0xFFFFFFFF      00000000                0x00000000             Exception
005      0x00000000      0xFFFFFFFF      00000000                0x00000000             Security
006      0x00006000      0x00003800      00000388                0x00000184             Base relocation
007      0x00002110      0x00001110      00000056                0x00000038             Debug
008      0x00000000      0xFFFFFFFF      00000000                0x00000000             Copyright string
009      0x00000000      0xFFFFFFFF      00000000                0x00000000             Globalptr
010      0x00000000      0xFFFFFFFF      00000000                0x00000000             Thread local storage (TLS)
011      0x00002150      0x00001150      00000064                0x00000040             Load configuration
012      0x00000000      0xFFFFFFFF      00000000                0x00000000             Bound Import
013      0x00002000      0x00001000      00000232                0x000000E8             Import Address Table
014      0x00000000      0xFFFFFFFF      00000000                0x00000000             Delay Import
015      0x00000000      0xFFFFFFFF      00000000                0x00000000             COM descriptor
016      0x00000000      0xFFFFFFFF      00000000                0x00000000             NoUse
--------------------------------------------------------------------------------------------------------------

查询节表结构

节表位于NT头之后,包含多个节的描述信息。每个节由一个节头定义,提供有关节的名称、虚拟地址、大小、类型和属性等信息。节表帮助操作系统识别和加载不同类型的数据和代码,例如代码节、数据节和资源节,以确保程序在内存中的正确组织和访问。

节表同样是PE文件的重要组成部分,其定义了文件中的各个节(section),每个节包含特定类型的数据和代码。以下是对节表结构的详细分析:

1. 位置
  • 节表位于NT头之后,紧接在可选头后面。
2. 结构

每个节由一个节头(Section Header)描述,节头通常包含以下字段:

字段名称描述
Name节的名称,通常为8字节,使用ASCII表示。
Virtual Size节在内存中的大小(以字节为单位)。
Virtual Address节在内存中的虚拟地址。
Size of Raw Data节在文件中的大小(以字节为单位)。
Pointer to Raw Data节在文件中的偏移量,指向实际数据。
Pointer to Relocations指向重定位信息的偏移量(通常为0)。
Pointer to Line Numbers指向行号信息的偏移量(通常为0)。
Number of Relocations重定位条目的数量(通常为0)。
Number of Line Numbers行号条目的数量(通常为0)。
Characteristics节的特性标志,如可执行、可读、可写等。
3. 常见节类型
  • .text:存放可执行代码,通常为只读。
  • .data:存放全局变量和静态数据,通常为可读可写。
  • .rsrc:存放程序资源,如图标和字符串。
  • .bss:未初始化的数据,系统会自动分配空间。
  • .reloc:存放重定位信息,用于地址修正。
4. 查询节表结构

程序中的节表查询可通过使用Section获取,其输出结果中包含了程序中所有的节的名称及该节在内存和文件中的偏移地址,如下输出所示;

[Pe View] # Section
----------------------------------------------------------------------------------------------------
编号     节区名称       虚拟偏移        虚拟大小        实际偏移        实际大小        节区属性
----------------------------------------------------------------------------------------------------
1        .text           0x00001000      0x00000B44      0x00000400      0x00000C00      0x60000020
2        .rdata          0x00002000      0x000007BA      0x00001000      0x00000800      0x40000040
3        .data           0x00003000      0x00000518      0x00001800      0x00000200      0xC0000040
4        .rsrc           0x00004000      0x00001DB0      0x00001A00      0x00001E00      0x40000040
5        .reloc          0x00006000      0x00000184      0x00003800      0x00000200      0x42000040
----------------------------------------------------------------------------------------------------

查询导入表结构

导入表位于数据目录表中,其记录了可执行文件所依赖的外部DLL及其函数信息。每个导入表项包含DLL名称和对应的导入函数列表,帮助操作系统在加载时解析并链接这些外部依赖,以确保程序能够正确调用所需的功能和资源。

以下是导入表的基本结构和分析:

1.导入表结构
  1. 导入描述符(Import Descriptor)
    • 每个导入表项由一个或多个导入描述符组成。
    • 包含以下字段:
      • Characteristics:描述符的特征(通常为0)。
      • TimeDateStamp:时间戳,标识DLL的版本。
      • ForwarderChain:指向转发导入的链表,通常为0。
      • Name:DLL的名称,以字符串形式表示。
      • ImportAddressTable(IAT):存储函数地址的表。
      • ImportNameTable(INT):存储函数名称的表。
  2. DLL名称
    • 存储所依赖的DLL的名称,通常以空字符结尾的字符串形式表示。
  3. 导入函数列表
    • 包含DLL中所需的函数,通常包括函数的序号或名称(通过名称或按序号查找)。
2.查询导入表结构

导入表的查询有多个命令,首先我们需要查询当前程序中导入了哪些动态链接库,可通过调用ImportDll命令来获取到,如下输出所示;

[Pe View] # ImportDll
----------------------------------------------------------------------
序号     文件偏移FOA     相对偏移RVA     DLL名称
----------------------------------------------------------------------
1        0x00001516      0x00000000      USER32.dll
2        0x0000167A      0x00000000      MSVCR120.dll
3        0x000017AC      0x00000000      KERNEL32.dll
----------------------------------------------------------------------

接着我们需要查询USER32.dll模块内导入了哪些函数,此时可以使用ImportByName命令,该命令接收一个动态链接库名称字符串,并返回该动态链接库中所导入的函数信息,如下输出所示;

[Pe View] # ImportByName --dll USER32.dll
------------------------------------------------------------------------------------------
序号     文件偏移FOA     相对偏移RVA     导入函数        [ 当前模块: USER32.dll ]
------------------------------------------------------------------------------------------
231      0x0000150A      0x0000250A      EndDialog
625      0x000014F8      0x000024F8      PostQuitMessage
233      0x000014EC      0x000024EC      EndPaint
14       0x000014DE      0x000024DE      BeginPaint
161      0x000014CC      0x000024CC      DefWindowProcW
173      0x000014BC      0x000024BC      DestroyWindow
178      0x000014AA      0x000024AA      DialogBoxParamW
855      0x0000149A      0x0000249A      UpdateWindow
800      0x0000148C      0x0000248C      ShowWindow
113      0x0000147A      0x0000247A      CreateWindowExW
649      0x00001466      0x00002466      RegisterClassExW
545      0x00001458      0x00002458      LoadCursorW
547      0x0000144C      0x0000244C      LoadIconW
181      0x00001438      0x00002438      DispatchMessageW
831      0x00001424      0x00002424      TranslateMessage
829      0x0000140C      0x0000240C      TranslateAcceleratorW
371      0x000013FE      0x000023FE      GetMessageW
539      0x000013EA      0x000023EA      LoadAcceleratorsW
560      0x000013DC      0x000023DC      LoadStringW
------------------------------------------------------------------------------------------

当需要查询所有导入的动态链接库及函数信息时可以使用ImportAll命令来实现,如下输出所示;

[Pe View] # ImportAll
--------------------------------------------------------------------------------------------------------------
Hint值           API序号         文件RVA         VA地址          函数名称        模块: [ USER32.dll ]
--------------------------------------------------------------------------------------------------------------
[  231]          000009482       0000150A        0040250A        EndDialog
[  625]          000009464       000014F8        004024F8        PostQuitMessage
[  233]          000009452       000014EC        004024EC        EndPaint
[   14]          000009438       000014DE        004024DE        BeginPaint
[  161]          000009420       000014CC        004024CC        DefWindowProcW
[  173]          000009404       000014BC        004024BC        DestroyWindow
[  178]          000009386       000014AA        004024AA        DialogBoxParamW
[  855]          000009370       0000149A        0040249A        UpdateWindow
[  800]          000009356       0000148C        0040248C        ShowWindow
--------------------------------------------------------------------------------------------------------------
Hint值           API序号         文件RVA         VA地址          函数名称        模块: [ MSVCR120.dll ]
--------------------------------------------------------------------------------------------------------------
[  634]          000009954       000016E2        004026E2        _except_handler4_common
[  579]          000009938       000016D2        004026D2        _controlfp_s
[  788]          000009920       000016C0        004026C0        _invoke_watson
[ 1082]          000009910       000016B6        004026B6        _onexit
[  430]          000009896       000016A8        004026A8        __dllonexit
[  558]          000009882       0000169A        0040269A        _calloc_crt
[ 1284]          000009872       00001690        00402690        _unlock
--------------------------------------------------------------------------------------------------------------
Hint值           API序号         文件RVA         VA地址          函数名称        模块: [ KERNEL32.dll ]
--------------------------------------------------------------------------------------------------------------
[  254]          000010140       0000179C        0040279C        DecodePointer
[  726]          000010114       00001782        00402782        GetSystemTimeAsFileTime
[  526]          000010092       0000176C        0040276C        GetCurrentThreadId
[  522]          000010070       00001756        00402756        GetCurrentProcessId
[ 1069]          000010044       0000173C        0040273C        QueryPerformanceCounter
[  877]          000010016       00001720        00402720        IsProcessorFeaturePresent
[  871]          000009996       0000170C        0040270C        IsDebuggerPresent
[  289]          000009980       000016FC        004026FC        EncodePointer

有时我们需要验证特定的函数是否被导入,此时可以使用ImportByFunction来获取,若函数被导入则输出导入的详细信息,如下输出所示;

[Pe View] # ImportByFunction --function DialogBoxParamW
----------------------------------------------------------------------------------------------------
序号             FOA地址         VA地址          所在DLL
----------------------------------------------------------------------------------------------------
[  178]          000014AA        004024AA        USER32.dll
----------------------------------------------------------------------------------------------------
[Pe View] #
[Pe View] # ImportByFunction --function PostQuitMessage
----------------------------------------------------------------------------------------------------
序号             FOA地址         VA地址          所在DLL
----------------------------------------------------------------------------------------------------
[  625]          000014F8        004024F8        USER32.dll
----------------------------------------------------------------------------------------------------
[Pe View] #
[Pe View] # ImportByFunction --function QueryPerformanceCounter
----------------------------------------------------------------------------------------------------
序号             FOA地址         VA地址          所在DLL
----------------------------------------------------------------------------------------------------
[ 1069]          0000173C        0040273C        KERNEL32.dll
----------------------------------------------------------------------------------------------------

查询导出表结构

导出表同样位于数据目录表中,其用于列出可执行文件或DLL所提供的外部函数和变量。每个导出表项包含函数的名称、地址和序号,使其他程序能够调用这些导出的功能。导出表提供了模块间的接口和动态链接,使得共享代码和资源变得可行。

以下是导出表的基本结构和分析。

1.导出表的基本组成
  1. 导出描述符(Export Directory)
    • 包含指向导出表的主要信息。
    • 主要字段包括:
      • Characteristics:通常为0。
      • TimeDateStamp:时间戳,标识导出的版本。
      • MajorVersion:导出表的主版本号。
      • MinorVersion:导出表的次版本号。
      • Name:指向DLL名称的指针。
      • Base:导出函数的基地址。
      • NumberOfFunctions:导出函数的数量。
      • NumberOfNames:导出名称的数量。
      • AddressOfFunctions:指向函数地址的表。
      • AddressOfNames:指向函数名称的表。
      • AddressOfNameOrdinals:指向名称序号表的指针。
  2. DLL名称
    • 存储DLL的名称,以空字符结尾的字符串形式表示。
  3. 导出函数列表
    • 函数的地址和名称,可以通过名称或序号进行引用。
2.关键字段分析
  • Characteristics:通常为0,用于标识导出表的有效性。
  • TimeDateStamp:指示最后修改的时间,可以用于检查DLL的版本。
  • Name:DLL的名称,有助于识别模块。
  • Base:定义函数地址的起始点,为地址计算提供基础。
  • NumberOfFunctions:表示可导出函数的总数,重要的统计信息。
  • NumberOfNames:表示可导出名称的数量,通常与函数数量相同,但可以不同。
  • AddressOfFunctions:实际导出函数的地址数组,程序调用时需要用到。
  • AddressOfNames:函数名称的指针数组,提供名称与地址之间的映射。
  • AddressOfNameOrdinals:指向名称序号的数组,帮助在导出时找到具体函数。
3.查询导出表结构

查询导出表可使用Export命令,一般的EXE可执行程序中并不会包含导出表,所以在查询时可自行切换到DLL模块中查询,如下输出所示;

[Pe View] # Open --path d://asmjit.dll
[+] 已读入文件
[Pe View] # Export
------------------------------------------------------------------------------------------
序号     导出RVA地址     导出VA地址      导出FOA地址     导出函数
------------------------------------------------------------------------------------------
    1      00013670      0x10013670      0x00012A70      AsmParser@asmtk
    2      00016520      0x10016520      0x00015920      0AsmTokenizer
    3      000136D0      0x100136D0      0x00012AD0      1AsmParser@asmtk@@QAE@XZ
    4      00016550      0x10016550      0x00015950      1AsmTokenizer@asmtk@@QAE@XZ
------------------------------------------------------------------------------------------

查询重定位表结构

重定位表用于在程序加载时调整地址以适应不同的内存布局。它包含重定位条目,指定了哪些地址需要被修改,通常在执行时针对非基地址加载的情况。重定位表保证了可执行文件在内存中的正确定位和地址修正,尤其对于共享库和动态链接来说非常重要。

以下是重定位表的基本结构和分析。

1.重定位表的基本组成
  1. 重定位目录(Relocation Directory)
    • 包含重定位信息的主要字段。
    • 主要字段包括:
      • VirtualAddress:重定位块的虚拟地址。
      • Size:重定位块的大小(以字节为单位)。
  2. 重定位条目(Relocation Entry)
    • 每个重定位块包含多个重定位条目。
    • 重定位条目的格式通常包括:
      • Offset:相对于重定位块的偏移量,指示需要修改的位置。
      • Type:重定位类型,指示如何处理该地址。
2.关键字段分析
  • VirtualAddress:指示重定位信息所对应的内存地址,加载时根据此地址进行修正。

  • Size:重定位块的大小,用于确定处理的范围。

  • Offset:重定位条目的偏移量,具体指定需要修正的指令或数据位置。

  • Type:重定位类型,常见类型包括:

    • IMAGE_REL_BASED_ABSOLUTE:不需要重定位。
    • IMAGE_REL_BASED_HIGH:高16位重定位。
    • IMAGE_REL_BASED_LOW:低16位重定位。
    • IMAGE_REL_BASED_HIGHLOW:完整32位重定位。
    • IMAGE_REL_BASED_DIR64:64位重定位(在64位PE文件中)。
3.查询重定位表结构

首先我们来查询重定位表的分页情况,可使用FixRelocPage命令得到所有的分页,如下输出所示;

[Pe View] # Open --path d://lyshark.exe
[+] 已读入文件
[Pe View] #
[Pe View] # FixRelocPage
----------------------------------------------------------------------
映像基址: 00400000 虚拟偏移: 00006000 重定位表基址: 00113800
----------------------------------------------------------------------
起始RVA: 00001000        块长度: 0352    重定位个数: 0172
起始RVA: 00002000        块长度: 0036    重定位个数: 0014
----------------------------------------------------------------------

如上所示在程序中有两块重定位分页。接着我们可以使用FixRelocRVA命令,该命令可通过传入一个重定位起始页RVA地址,自动输出该重定位页内的重定位项,如下输出所示;

[Pe View] # FixRelocPage
----------------------------------------------------------------------
映像基址: 00400000 虚拟偏移: 00006000 重定位表基址: 00113800
----------------------------------------------------------------------
起始RVA: 00001000        块长度: 0352    重定位个数: 0172
起始RVA: 00002000        块长度: 0036    重定位个数: 0014
----------------------------------------------------------------------
[Pe View] #
[Pe View] # FixRelocRVA --rva 00002000
----------------------------------------------------------------------------------------------------
起始RVA          类型    重定位RVA       重定位地址      修正RVA
----------------------------------------------------------------------------------------------------
00002000         3       000020EC        00401393       00001393
00002000         3       000020F8        004012DA       000012DA
00002000         3       000020FC        0040190D       0000190D
00002000         3       00002100        0040170E       0000170E
00002000         3       00002148        00403038       00003038
00002000         3       0000214C        00403088       00003088
00002000         3       0000218C        00403000       00003000
00002000         3       00002190        00402230       00002230
00002000         3       0000225C        0040153B       0000153B
00002000         3       00002260        0040154F       0000154F
00002000         3       0000227C        00401809       00001809
00002000         3       00002280        0040181C       0000181C
00002000         3       000022A0        004019E6       000019E6
00002000         0       00002000        0000279C       FFC0279C
----------------------------------------------------------------------------------------------------

若要查询程序中所有的重定位项,可使用FixReloc命令,如下输出所示;

[Pe View] # FixReloc
----------------------------------------------------------------------------------------------------
起始RVA          类型    重定位RVA       重定位地址      修正RVA
----------------------------------------------------------------------------------------------------
00001000         3       00001009        004020E0       000020E0
00001000         3       00001014        00403438       00003438
00001000         3       00001020        00403370       00003370
00001000         3       0000104B        00403438       00003438
00002000         3       000020EC        00401393       00001393
00002000         3       000020F8        004012DA       000012DA
00002000         3       000020FC        0040190D       0000190D
00002000         3       00002100        0040170E       0000170E

查询资源表结构

资源表用于存储程序所需的各种资源,如图标、位图、对话框和字符串等。资源表以层次结构组织,包含资源类型、名称和实际数据的指针,允许程序在运行时访问和管理这些外部资源。通过资源表,开发者可以轻松地在应用程序中使用多种用户界面元素和本地化内容。

以下是资源表的基本结构和分析。

1.资源表的基本组成
  1. 资源目录(Resource Directory)
    • 包含资源的层级结构和指向具体资源的指针。
    • 主要字段包括:
      • Characteristics:通常为0,用于指示资源的特征。
      • TimeDateStamp:时间戳,标识资源的最后修改时间。
      • MajorVersion:资源表的主版本号。
      • MinorVersion:资源表的次版本号。
      • NumberOfIdEntries:ID项的数量。
      • NumberOfNamedEntries:命名项的数量。
  2. 资源项(Resource Entry)
    • 每个资源目录可以包含多个资源项。
    • 每个资源项包括:
      • NameId:资源的名称或ID。
      • Type:资源的类型(如图标、位图、字符串等)。
      • OffsetToData:指向资源数据的偏移量。
      • Size:资源数据的大小。
  3. 资源数据(Resource Data)
    • 实际的资源内容,如位图的像素数据或字符串的文本。
2.关键字段分析
  • Characteristics:指示资源的特征,通常为0,可能用于标识某些特性。
  • TimeDateStamp:指示资源的最后修改时间,有助于版本控制。
  • MajorVersion / MinorVersion:用于表示资源版本,便于管理不同版本的资源。
  • NumberOfIdEntries / NumberOfNamedEntries:帮助管理资源目录中的条目数量,便于遍历。
  • Name / Id:唯一标识资源的名称或ID,是资源查找的关键。
  • Type:指示资源的类型,如RT_ICON(图标)、RT_BITMAP(位图)、RT_STRING(字符串)等。
  • OffsetToData:指向实际资源数据的位置,程序加载资源时需要使用。
  • Size:资源数据的大小,便于分配和管理内存。
3.查询资源表结构

查询资源表可以使用Resource命令获取,该命令仅用于获取进程中所加载的资源信息概述,如下输出所示;

[Pe View] # Resource
------------------------------------------------------------
资源类型ID       类型
------------------------------------------------------------
00000003         图标
00000004         菜单
00000005         对话框
00000006         字符串列表
00000009         快捷键
0000000E         图标组
00000018         24
------------------------------------------------------------

若要查询完整的资源表结构,可通过调用ResourceAll命令获取,如下输出所示;

[Pe View] # ResourceAll
--------------------------------------------------------------------------------
资源类型ID       类型                    资源语言ID      语言            资源数据偏移地址
--------------------------------------------------------------------------------
00000003         图标                    00000003                Unknown                         

资源二层目录偏移地址: FFFFFFFF
                 -> 资源ID: 0000B800     类型: 47104     数据偏移地址: 00000000
                 -> 资源ID: 00004000     类型: 16384     数据偏移地址: 00000000
                 -> 资源ID: 00000000     类型: (null)    数据偏移地址: 00000000
                 -> 资源ID: 00000000     类型: (null)    数据偏移地址: 00000000
                 -> 资源ID: 000021CD     类型: 8653      数据偏移地址: 5421CD4C
                 -> 资源ID: 00006968     类型: 26984     数据偏移地址: 676F7270
                 -> 资源ID: 00006172     类型: 24946     数据偏移地址: 6E6E6163
                 -> 资源ID: 0000746F     类型: 29807     数据偏移地址: 75722065
                 -> 资源ID: 0000206E     类型: 8302      数据偏移地址: 534F4420
                 -> 资源ID: 00006D20     类型: 27936     数据偏移地址: 0D0D2E65

文件查询与反汇编

1.查询十六进制文本

通过调用GetHexAscii命令,该命令接收两个参数,分别是文件地址及需要向下遍历的长度,当参数被传入后则可输出特定程序中特定位置的十六进制机器码,如下输出所示;

[Pe View] # Open --path d://lyshark.exe
[+] 已读入文件
[Pe View] # GetHexAscii --offset 0 --len 100
-------------------------------------------------------------------------------
Offset   | 0  1  2  3  4  5  6  7  8  9  10 11 12 13 14 15 | ASCII
-------------------------------------------------------------------------------
00000000 | 4D 5A 90 00 03 00 00 00 04 00 00 00 FF FF 00 00 | MZ?       
00000016 | B8 00 00 00 00 00 00 00 40 00 00 00 00 00 00 00 | ?       @
00000032 | 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |
00000048 | 00 00 00 00 00 00 00 00 00 00 00 00 00 01 00 00 |              
00000064 | 0E 1F BA 0E 00 B4 09 CD 21 B8 01 4C CD 21 54 68 | ? ?     ?!?L?!Th
00000080 | 69 73 20 70 72 6F 67 72 61 6D 20 63 61 6E 6E 6F | is program canno
[Pe View] #
[Pe View] # GetHexAscii --offset 1024 --len 100
-------------------------------------------------------------------------------
Offset   | 0  1  2  3  4  5  6  7  8  9  10 11 12 13 14 15 | ASCII
-------------------------------------------------------------------------------
00001024 | 55 8B EC 83 EC 1C 56 8B 35 E0 20 40 00 57 8B 7D | U????V?5? @ W?}
00001040 | 08 6A 64 68 38 34 40 00 6A 67 57 FF D6 6A 64 68 |jdh84@ jgW?jdh
00001056 | 70 33 40 00 6A 6D 57 FF D6 8B CF E8 C0 00 00 00 | p3@ jmW?????
00001072 | 6A 00 57 6A 00 6A 00 6A 00 68 00 00 00 80 6A 00 | j Wj j j h   €j
00001088 | 68 00 00 00 80 68 00 00 CF 00 68 38 34 40 00 68 | h   €h  ? h84@ h
00001104 | 70 33 40 00 6A 00 89 3D 00 35 40 00 FF 15 BC 20 | p3@ j ?= 5@ ?
2.查询文件反汇编区域

通过调用DasmFoa命令,该命令接收两个参数,分别是文件地址及需要向下遍历的长度,用于对特定文本区域进行反汇编,如下输出所示;

[Pe View] # DasmFoa --offset 1024 --len 30
--------------------------------------------------------------------------------
文件偏移                 反汇编指令集
--------------------------------------------------------------------------------
0x00000400 | push ebp
0x00000401 | mov ebp, esp
0x00000403 | sub esp, 0x1c
0x00000406 | push esi
0x00000407 | mov esi, dword ptr [0x4020e0]
0x0000040D | push edi
0x0000040E | mov edi, dword ptr [ebp + 8]
0x00000411 | push 0x64
0x00000413 | push 0x403438
0x00000418 | push 0x67
0x0000041A | push edi
0x0000041B | call esi
[Pe View] #
[Pe View] # DasmFoa --offset 2000 --len 20
--------------------------------------------------------------------------------
文件偏移                 反汇编指令集
--------------------------------------------------------------------------------
0x000007D0 | add byte ptr [ebp + 0x6a0879c0], al
0x000007D6 | or al, ch
0x000007D8 | inc esi
0x000007D9 | add eax, dword ptr [eax]
0x000007DB | add byte ptr [ecx - 0x3d], bl
0x000007DE | push 0x14
3.扫描内存挂钩状态

检查内存汇编代码是否被挂钩可以通过调用ScanPE命令实现,该命令需要读入一个可执行文件并运行一个与之相对应的进程,当执行命令后会将内存中的反汇编代码与磁盘中的反汇编代码进行比对若两者不同则说明被挂钩了,若相同则说明正常,如下输出所示;

[Pe View] # Open --path D:\\lyshark.exe
[+] 已读入文件
[Pe View] #
[Pe View] # ScanPE
[+] 读入文件长度: 14848 bytes 基址: 0172DAF8
[+] 进程模块句柄: 15532032
[+] 进程句柄: 000000E4
[+] PE读入状态: 1
[+] 拉伸后长度: 28672 bytes 基址: 01731500
[+] 修正重定位基址: 15532032
[+] 代码段数量: 1
[+] 虚拟地址: 4096 长度: 3072 实际地址: 1024

0x00ED0000 | 文件汇编: push ebp                                 | 内存汇编: push ebp                                 |
0x00ED0001 | 文件汇编: mov ebp, esp                             | 内存汇编: mov ebp, esp                             |
0x00ED0003 | 文件汇编: sub esp, 0x1c                            | 内存汇编: sub esp, 0x1c                            |
0x00ED0006 | 文件汇编: push esi                                 | 内存汇编: push esi                                 |
0x00ED0007 | 文件汇编: mov esi, dword ptr [0xed20e0]            | 内存汇编: mov esi, dword ptr [0xed20e0]            |
0x00ED000D | 文件汇编: push edi                                 | 内存汇编: push edi                                 |
0x00ED000E | 文件汇编: mov edi, dword ptr [ebp + 8]             | 内存汇编: mov edi, dword ptr [ebp + 8]             |

其他扩展

检查函数内存地址: 用于验证特定模块中的内存地址,使用GetProcAddr命令验证。

[Pe View] # GetProcAddr --dll user32.dll --function MessageBoxA
0x75361F70
[Pe View] # GetProcAddr --dll user32.dll --function MessageBoxW
0x753623A0
[Pe View] # GetProcAddr --dll user32.dll --function MessageBox
0x0

检查保护模式: 用于检查当前打开进程所开启的保护模式,使用CheckSelf命令验证。

[Pe View] # Open --path d:\\lyshark.exe
[+] 已读入文件
[Pe View] #
[Pe View] # CheckSelf
--------------------------------------------------
基址随机化:   是
DEP保护兼容:  是
强制完整性:   否
SEH异常保护:  否
证书签名:     否
--------------------------------------------------

目标指纹识别: 使用Fingerprint命令检测目标程序硬盘特征指纹,从而判断是那个编译器生成的程序,目前特征库不全仅用于演示。

[Pe View] # Fingerprint --path d://lyshark.exe
--------------------------------------------------------------------------------------------------------------

原始数据: 55 8B EC 81 EC C4 00 00 00 53 56 57 8D BD 3C FF FF FF B9 31 00 00 00 B8 CC CC CC CC F3 AB 8B 45
磁盘映像: 35 40 00 87 01 83 3D 14 35 40 00 00 74 1B 68 14 35 40 00 E8 C8 02 00 00 59 85 C0 74 0C 6A 00 6A
检测结果: 无指纹特征

--------------------------------------------------------------------------------------------------------------

原始数据: CC CC CC CC CC E9 86 02 00 00 E9 31 05 00 00 E9 6C 01 00 00 E9 57 03 00 00 E9 22 00 00 00 CC CC
磁盘映像: 55 8B EC 83 EC 1C 56 8B 35 E0 20 40 00 57 8B 7D 08 6A 64 68 38 34 40 00 6A 67 57 FF D6 6A 64 68
检测结果: 无指纹特征

--------------------------------------------------------------------------------------------------------------

十六进制计算器: 用于计算两个十六进制数的加减法。

[Pe View] # Add --x 1c --y 2d
1c + 2d =>
         HEX= 00000049
         DEC= 73
         OCT= 111
         BIN= 1001001
[Pe View] #
[Pe View] # Sub --x 1c --y 2d
1c - 2d =>
         HEX= FFFFFFEF
         DEC= -17
         OCT= 37777777757
         BIN= 11111111111111111111111111101111

文件地址转虚拟地址: 将当前打开程序机器码所在地址转换成载入内存中的虚拟地址。

[Pe View] # Open --path d:\\lyshark.exe
[+] 已读入文件
[Pe View] #
[Pe View] # FoaToVa --foa 1024
--------------------------------------------------------------------------------
基址: 0x00400000 文件偏移开始: 0x00001000 文件偏移结束: 0x00001800
--------------------------------------------------------------------------------
FOA地址: 0x00001024
         ---> RVA地址: 0x00002024
                 ---> VA地址: 0x00402024
--------------------------------------------------------------------------------

虚拟地址转文件地址: 将当前打开程序的内存虚拟地址转换为所在文件地址。

[Pe View] # VaToFoa --va 0x00402024
--------------------------------------------------------------------------------
基址: 0x00400000 所在节区: .rdata 节开始地址: 0x00402000 节结束地址: 0x004027BA
--------------------------------------------------------------------------------
VA地址: 0x00402024
         ---> RVA地址: 0x00002024
                 ---> FOA地址: 0x00001024
--------------------------------------------------------------------------------

相对地址转文件地址: 将当前打开程序的 RVA 相对内存地址,转换成一个文件偏移地址。

[Pe View] # RvaToFoa --rva 0x00002024
--------------------------------------------------------------------------------
基址: 0x00400000 所在节区: .rdata 节开始地址: 0x00002000 节结束地址: 0x000027BA
--------------------------------------------------------------------------------
RVA地址: 0x00002024
         ---> VA地址: 0x00402024
                 ---> FOA地址: 0x00001024
--------------------------------------------------------------------------------

标签:00,PeView,PE,00000000,地址,命令行,Pe,--,View
From: https://blog.csdn.net/lyshark_csdn/article/details/143346651

相关文章

  • Iperius Backup Full 中文授权版
    IperiusBackupFull是一款优秀的电脑数据同步备份软件。该版本已授权,可以使用全部功能。功能亮点:全面的备份方案:提供全备份、增量备份、差异备份和按需备份,满足不同备份需求。灵活的备份目标:支持本地硬盘、外部硬盘、网络驱动器和NAS存储设备等多种存储选项。数据压缩与加......
  • 【Linux操作系统】Linux配置OpenSSH服务器步骤记录
    1.安装OpenSSH服务器软件包用指令查询,已经全部安装。编辑/etc/ssh/sshd_config文件:#      $OpenBSD:sshd_config,v1.1032018/04/0920:41:22tjExp$#Thisisthesshdserversystem-wideconfigurationfile. See#sshd_config(5)formoreinformat......
  • Paper Reading: Random Balance ensembles for multiclass imbalance learning
    目录研究动机文章贡献多分类的随机平衡集成二分类RandomBalanceMultiRandBalOVO-RandBal和OVA-RandBal实验结果数据集和实验设置对比实验MAUC的分解多样性运行时间优点和创新点PaperReading是从个人角度进行的一些总结分享,受到个人关注点的侧重和实力所限,可能有理解不到位......
  • 一文讲明白大模型分布式逻辑(从GPU通信原语到Megatron、Deepspeed)
    1.背景介绍如果你拿到了两台8卡A100的机器(做梦),你的导师让你学习部署并且训练不同尺寸的大模型,并且写一个说明文档。你意识到,你最需要学习的就是关于分布式训练的知识,因为你可是第一次接触这么多卡,但你并不想深入地死磕那些看起来就头大的底层原理,你只想要不求甚解地理解分......
  • ImportError: DLL load failed while importing _errors: The specified procedure co
    importh5pyImportError:DLLloadfailedwhileimporting_errors:Thespecifiedprocedurecouldnotbefound. ImportError                              Traceback(mostrecentcalllast)CellIn[2],line1---->1importh5pyFile......
  • 3.1.4 Hyperspace 的临时映射1
    系列文章目录文章目录系列文章目录3.1.4Hyperspace的临时映射MmCreateHyperspaceMappingMmGetPageTableForProcess3.1.4Hyperspace的临时映射Windows内核有时候需要将某些物理页面临时映射到内核的虚存区间,用做“草稿”或其他临时的用途。为此,Windows内核在系......
  • yolov5 train报错:TypeError: expected np.ndarray (got numpy.ndarray)
    前言macintel机器上,使用yolov5物体检测训练时报错:TypeError:expectednp.ndarray(gotnumpy.ndarray)这个错误信息TypeError:expectednp.ndarray(gotnumpy.ndarray)看起来有些奇怪,因为numpy.ndarray实际上就是np.ndarray。通常情况下,这种错误可能是由于库版本不......
  • vins-fusion gpu, docker, opencv4.5.4(cuda) 复现
    代码:https://gitee.com/zheng-yongjie/vins-fusion-gpu-cv4?skip_mobile=true硬件:jetsonxaviernx,系统20.04nvcc-V可查看cuda版本本文在docker里面复现1.opencvcuda安装root@ubuntu:~#pwd/rootwget-Oopencv-4.5.4.ziphttps://github.com/opencv/opencv/archi......
  • Performance API 实现前端资源监控
    1.PerformanceAPI的用处PerformanceAPI 是浏览器中内置的一组工具,用于测量和记录页面加载和执行过程中的各类性能指标。它的主要用处包括:监控页面资源加载:跟踪页面中的资源(如CSS、JavaScript、图片)的加载时间。分析页面加载时间:从导航到页面完全渲染的所有时间点。衡量......
  • C++之OpenCV入门到提高002:加载、修改、保存图像
    一、介绍今天是这个系列《C++之Opencv入门到提高》得第二篇文章。今天这个篇文章很简单,只是简单介绍如何使用Opencv加载图像、显示图像、修改图像和保存图像,先给大家一个最直观的感受。但是,不能认为很简单,只是让学习的过程没那么平滑一点,以后的路就好走了。OpenCV具......