首页
社区
课程
招聘
[原创]使用DELPHI编写PE区段查看器。
发表于: 2007-1-9 12:38 7567

[原创]使用DELPHI编写PE区段查看器。

2007-1-9 12:38
7567
标 题: 使用DELPHI编写PE区段查看器
作 者: pathletboy
时 间: 2007-01-09,12:30
链 接: http://bbs.pediy.com/showthread.php?s=&threadid=37667

所需工具:Ollydbg、Delphi7
要点:纪录结构、FileStream操作
提前说明,本人是新手,对PE结构很不了解,下文可能漏洞百出,希望观者能指出错误。
STEP1
建立PE文件头的结构和PE区段头的数据结构。
打开OD随便加载一个EXE文件,然后alt+m后找到加载程序的内存空间后(见下图)

双击PE文件头一行。
在偏移$3C处发现
0040003C    00010000    DD 00000100          ; Offset to PE signature
根据提示到偏移$100处
00400100    50 45 00 00>ASCII "PE"           ; PE signature (PE)
00400104    4C01        DW 014C              ; Machine = IMAGE_FILE_MACHINE_I386
00400106    0800        DW 0008              ;  NumberOfSections = 8
00400108    195E422A    DD 2A425E19          ;  TimeDateStamp = 2A425E19
0040010C    00000000    DD 00000000          ;  PointerToSymbolTable = 0
00400110    00000000    DD 00000000          ;  NumberOfSymbols = 0
00400114    E000        DW 00E0              ;  SizeOfOptionalHeader = E0 (224.)
00400116    8E81        DW 818E              ;  Characteristics =

EXECUTABLE_IMAGE|32BIT_MACHINE|LINE_NUMS_STRIPPED|LOCAL_SYMS_STRIPPED|BYTES_REVERSED_LO|BYTES_REVERSED_HI
00400118    0B01        DW 010B              ; MagicNumber = PE32
0040011A    02          DB 02                ;  MajorLinkerVersion = 2
0040011B    19          DB 19                ;  MinorLinkerVersion = 19 (25.)
0040011C    00CC0600    DD 0006CC00          ;  SizeOfCode = 6CC00 (445440.)
00400120    00180100    DD 00011800          ;  SizeOfInitializedData = 11800 (71680.)
00400124    00000000    DD 00000000          ;  SizeOfUninitializedData = 0
00400128    0CDB0600    DD 0006DB0C          ;  AddressOfEntryPoint = 6DB0C
0040012C    00100000    DD 00001000          ;  BaseOfCode = 1000
00400130    00E00600    DD 0006E000          ;  BaseOfData = 6E000
00400134    00004000    DD 00400000          ; ImageBase = 400000
00400138    00100000    DD 00001000          ;  SectionAlignment = 1000
0040013C    00020000    DD 00000200          ;  FileAlignment = 200
00400140    0400        DW 0004              ;  MajorOSVersion = 4
00400142    0000        DW 0000              ;  MinorOSVersion = 0
00400144    0000        DW 0000              ;  MajorImageVersion = 0
00400146    0000        DW 0000              ;  MinorImageVersion = 0
00400148    0400        DW 0004              ;  MajorSubsystemVersion = 4
0040014A    0000        DW 0000              ;  MinorSubsystemVersion = 0
0040014C    00000000    DD 00000000          ;  Reserved
00400150    00400800    DD 00084000          ;  SizeOfImage = 84000 (540672.)
00400154    00040000    DD 00000400          ;  SizeOfHeaders = 400 (1024.)
00400158    00000000    DD 00000000          ;  CheckSum = 0
0040015C    0200        DW 0002              ;  Subsystem = IMAGE_SUBSYSTEM_WINDOWS_GUI
0040015E    0000        DW 0000              ;  DLLCharacteristics = 0
00400160    00001000    DD 00100000          ;  SizeOfStackReserve = 100000 (1048576.)
00400164    00400000    DD 00004000          ;  SizeOfStackCommit = 4000 (16384.)
00400168    00001000    DD 00100000          ;  SizeOfHeapReserve = 100000 (1048576.)
0040016C    00100000    DD 00001000          ;  SizeOfHeapCommit = 1000 (4096.)
00400170    00000000    DD 00000000          ;  LoaderFlags = 0
00400174    10000000    DD 00000010          ;  NumberOfRvaAndSizes = 10 (16.)
00400178    00000000    DD 00000000          ;  Export Table address = 0
0040017C    00000000    DD 00000000          ;  Export Table size = 0
00400180    00100700    DD 00071000          ;  Import Table address = 71000
00400184    96200000    DD 00002096          ;  Import Table size = 2096 (8342.)
00400188    00E00700    DD 0007E000          ;  Resource Table address = 7E000
0040018C    005E0000    DD 00005E00          ;  Resource Table size = 5E00 (24064.)
00400190    00000000    DD 00000000          ;  Exception Table address = 0
00400194    00000000    DD 00000000          ;  Exception Table size = 0
00400198    00000000    DD 00000000          ;  Certificate File pointer = 0
0040019C    00000000    DD 00000000          ;  Certificate Table size = 0
004001A0    00600700    DD 00076000          ;  Relocation Table address = 76000
004001A4    547E0000    DD 00007E54          ;  Relocation Table size = 7E54 (32340.)
004001A8    00000000    DD 00000000          ;  Debug Data address = 0
004001AC    00000000    DD 00000000          ;  Debug Data size = 0
004001B0    00000000    DD 00000000          ;  Architecture Data address = 0
004001B4    00000000    DD 00000000          ;  Architecture Data size = 0
004001B8    00000000    DD 00000000          ;  Global Ptr address = 0
004001BC    00000000    DD 00000000          ;  Must be 0
004001C0    00500700    DD 00075000          ;  TLS Table address = 75000
004001C4    18000000    DD 00000018          ;  TLS Table size = 18 (24.)
004001C8    00000000    DD 00000000          ;  Load Config Table address = 0
004001CC    00000000    DD 00000000          ;  Load Config Table size = 0
004001D0    00000000    DD 00000000          ;  Bound Import Table address = 0
004001D4    00000000    DD 00000000          ;  Bound Import Table size = 0
004001D8    00000000    DD 00000000          ;  Import Address Table address = 0
004001DC    00000000    DD 00000000          ;  Import Address Table size = 0
004001E0    00000000    DD 00000000          ;  Delay Import Descriptor address = 0
004001E4    00000000    DD 00000000          ;  Delay Import Descriptor size = 0
004001E8    00000000    DD 00000000          ;  COM+ Runtime Header address = 0
004001EC    00000000    DD 00000000          ;  Import Address Table size = 0
004001F0    00000000    DD 00000000          ;  Reserved
004001F4    00000000    DD 00000000          ;  Reserved
根据以上内容建立一个PE文件头纪录结构
type PeHead = record
    Pesingature: array[0..3] of Char;
    Machine: word;
    NumberOfSections: word;
    TimeDataStamp: dword;
    PointerToSymbolTable: dword;
    NumberOfSymbols: dword;
    SizeOfOptionalHeader: word;
    Characteristics: word;
    MagicNumber: word;
    MajorLinkerVersion: byte;
    MinorLinkerVersion: byte;
    SizeOfCode: dword;
    SizeOfInitializedData: dword;
    SizeOfUninitializedData: dword;
    AddressOfEntryPointer: dword;
    BaseOfCode: dword;
    BaseOfData: dword;
    ImageBase: dword;
    SectionAlignment: dword;
    FileAlignment: dword;
    MajorOSVersion: word;
    MinorOSVersion: word;
    MajorImageVersion: word;
    MinorImageVersion: word;
    MajorSubsystemVersion: word;
    MinorSubsystemVersion: word;
    Reserved_a: dword;
    SizeOfImage: dword;
    SizeOfheaders: dword;
    CheackSum: dword;
    Subsystem: word;
    DLLCharacteristics: word;
    SizeOfStackReserve: dword;
    SizeOfstackCommit: dword;
    SizeOfHeapReserve: dword;
    SizeOfHeapCommit: dword;
    LoaderFlags: dword;
    NumberOfRvaAndSizes: dword;
    ExportTableAddress: dword;
    ExportTableSize: dword;
    ImportTableAddress: dword;
    ImportTableSize_a: dword;
    ResourceTableAddress: dword;
    ResourceTableSize: dword;
    ExceptionTableAddress: dword;
    ExceptionTableSize: dword;
    CertificateFilePointer: dword;
    CertificateTableSize: dword;
    RelocationTableAddress: dword;
    RelocationTableSize: dword;
    DebugDataAddress: dword;
    DebugDataSize: dword;
    ArchitectureDataAddress: dword;
    ArchitectureDataSize: dword;
    GlobalPtrAddress: dword;
    MustBe0: dword;
    TLSTableAddress: dword;
    TLSTableSize: dword;
    LoadConfigTableAddress: dword;
    LoadConfigTableSize: dword;
    BoundImportTableAddress: dword;
    BoundImportTableSize: dword;
    ImportAddressTableAddress: dword;
    ImportAddressTableSize: dword;
    DelayImportDescriptorAddress: dword;
    DelayImportDescriptorSize: dword;
    COMRuntimeHeaderAddress: dword;
    ImportAddressTableSize_b: dword;
    Reserver_b: dword;
    Reserver_c: dword;
  end;

在OD中往下拉看到
004001F8    43 4F 44 45>ASCII "CODE"         ; SECTION
00400200    7CCB0600    DD 0006CB7C          ;  VirtualSize = 6CB7C (445308.)
00400204    00100000    DD 00001000          ;  VirtualAddress = 1000
00400208    00CC0600    DD 0006CC00          ;  SizeOfRawData = 6CC00 (445440.)
0040020C    00040000    DD 00000400          ;  PointerToRawData = 400
00400210    00000000    DD 00000000          ;  PointerToRelocations = 0
00400214    00000000    DD 00000000          ;  PointerToLineNumbers = 0
00400218    0000        DW 0000              ;  NumberOfRelocations = 0
0040021A    0000        DW 0000              ;  NumberOfLineNumbers = 0
0040021C    20000060    DD 60000020          ;  Characteristics = CODE|EXECUTE|READ

根据以上内容建立一个PE区段头纪录结构
type SectionHead = record
    SectionName: array[0..7] of Char;
    VirtualSize: dword;
    VirtualAddress: dword;
    SizeOfRawData: dword;
    PointerToRawData: dword;
    PointerToRelocations: dword;
    PointerToLineNumbers: dword;
    NumberOfRelocations: word;
    NumberOfLineNumbers: word;
    Characteristics: dword;
  end;

STEP2
程序编写
申明变量
FileDir: string; //目标文件路径
upeheadoffset: dword;  //目标文件PE头的偏移位置
loopsection: integer;        //用于循环获取PE区段头的变量
tempstrings: Tstrings;        //用于显示PE区段头内容的变量
targetfile: TStream; //文件流对象,用来操作对象文件
upehead: PeHead; //PE文件头变量       
usectionhead: SectionHead; //PE区段头变量

通过文件流操作,首先从文件偏移$3C处获取文件头偏移放入upeheadoffset中
然后在偏移upeheadoffset处获取文件头放入upehead中
upehead.NumberOfSections即为区段数量
循环获取区段头放入usectionhead并显示出来。
具体实现见代码。
代码下载http://bbs.itsong.com/PBsPEEDITOR.rar
错误已修正。

[注意]传递专业知识、拓宽行业人脉——看雪讲师团队等你加入!

收藏
免费 0
支持
分享
最新回复 (1)
雪    币: 342
活跃值: (323)
能力值: ( LV9,RANK:450 )
在线值:
发帖
回帖
粉丝
2
Pe文件头大部分定义,在delphi的windows.pas里面已经有定义了。
2007-1-10 12:32
0
游客
登录 | 注册 方可回帖
返回
//