Added Get-ObjDump
Get-ObjDump parses and return information about one or more Windows object files. It is similar to dumpbin but it returns objects!
This commit is contained in:
parent
030fc3b43b
commit
55a6dbd019
|
|
@ -0,0 +1,292 @@
|
||||||
|
<?xml version="1.0" encoding="utf-8" ?>
|
||||||
|
<Configuration>
|
||||||
|
<ViewDefinitions>
|
||||||
|
<View>
|
||||||
|
<Name>ObjectFileView</Name>
|
||||||
|
<ViewSelectedBy>
|
||||||
|
<TypeName>COFF.OBJECT_FILE</TypeName>
|
||||||
|
</ViewSelectedBy>
|
||||||
|
<ListControl>
|
||||||
|
<ListEntries>
|
||||||
|
<ListEntry>
|
||||||
|
<ListItems>
|
||||||
|
<ListItem>
|
||||||
|
<PropertyName>COFFHeader</PropertyName>
|
||||||
|
</ListItem>
|
||||||
|
<ListItem>
|
||||||
|
<PropertyName>SectionHeaders</PropertyName>
|
||||||
|
</ListItem>
|
||||||
|
<ListItem>
|
||||||
|
<PropertyName>SymbolTable</PropertyName>
|
||||||
|
</ListItem>
|
||||||
|
</ListItems>
|
||||||
|
</ListEntry>
|
||||||
|
</ListEntries>
|
||||||
|
</ListControl>
|
||||||
|
</View>
|
||||||
|
<View>
|
||||||
|
<Name>COFFHeaderView</Name>
|
||||||
|
<ViewSelectedBy>
|
||||||
|
<TypeName>COFF.HEADER</TypeName>
|
||||||
|
</ViewSelectedBy>
|
||||||
|
<ListControl>
|
||||||
|
<ListEntries>
|
||||||
|
<ListEntry>
|
||||||
|
<ListItems>
|
||||||
|
<ListItem>
|
||||||
|
<PropertyName>Machine</PropertyName>
|
||||||
|
</ListItem>
|
||||||
|
<ListItem>
|
||||||
|
<PropertyName>NumberOfSections</PropertyName>
|
||||||
|
<FormatString>0x{0:X4}</FormatString>
|
||||||
|
</ListItem>
|
||||||
|
<ListItem>
|
||||||
|
<PropertyName>TimeDateStamp</PropertyName>
|
||||||
|
</ListItem>
|
||||||
|
<ListItem>
|
||||||
|
<PropertyName>PointerToSymbolTable</PropertyName>
|
||||||
|
<FormatString>0x{0:X8}</FormatString>
|
||||||
|
</ListItem>
|
||||||
|
<ListItem>
|
||||||
|
<PropertyName>NumberOfSymbols</PropertyName>
|
||||||
|
<FormatString>0x{0:X8}</FormatString>
|
||||||
|
</ListItem>
|
||||||
|
<ListItem>
|
||||||
|
<PropertyName>SizeOfOptionalHeader</PropertyName>
|
||||||
|
<FormatString>0x{0:X4}</FormatString>
|
||||||
|
</ListItem>
|
||||||
|
<ListItem>
|
||||||
|
<PropertyName>Characteristics</PropertyName>
|
||||||
|
</ListItem>
|
||||||
|
</ListItems>
|
||||||
|
</ListEntry>
|
||||||
|
</ListEntries>
|
||||||
|
</ListControl>
|
||||||
|
</View>
|
||||||
|
<View>
|
||||||
|
<Name>SectionHeaderView</Name>
|
||||||
|
<ViewSelectedBy>
|
||||||
|
<TypeName>COFF.SECTION_HEADER</TypeName>
|
||||||
|
</ViewSelectedBy>
|
||||||
|
<ListControl>
|
||||||
|
<ListEntries>
|
||||||
|
<ListEntry>
|
||||||
|
<ListItems>
|
||||||
|
<ListItem>
|
||||||
|
<PropertyName>Name</PropertyName>
|
||||||
|
</ListItem>
|
||||||
|
<ListItem>
|
||||||
|
<PropertyName>PhysicalAddress</PropertyName>
|
||||||
|
<FormatString>0x{0:X8}</FormatString>
|
||||||
|
</ListItem>
|
||||||
|
<ListItem>
|
||||||
|
<PropertyName>VirtualSize</PropertyName>
|
||||||
|
<FormatString>0x{0:X8}</FormatString>
|
||||||
|
</ListItem>
|
||||||
|
<ListItem>
|
||||||
|
<PropertyName>VirtualAddress</PropertyName>
|
||||||
|
<FormatString>0x{0:X8}</FormatString>
|
||||||
|
</ListItem>
|
||||||
|
<ListItem>
|
||||||
|
<PropertyName>SizeOfRawData</PropertyName>
|
||||||
|
<FormatString>0x{0:X8}</FormatString>
|
||||||
|
</ListItem>
|
||||||
|
<ListItem>
|
||||||
|
<PropertyName>PointerToRawData</PropertyName>
|
||||||
|
<FormatString>0x{0:X8}</FormatString>
|
||||||
|
</ListItem>
|
||||||
|
<ListItem>
|
||||||
|
<PropertyName>PointerToRelocations</PropertyName>
|
||||||
|
<FormatString>0x{0:X8}</FormatString>
|
||||||
|
</ListItem>
|
||||||
|
<ListItem>
|
||||||
|
<PropertyName>PointerToLinenumbers</PropertyName>
|
||||||
|
<FormatString>0x{0:X8}</FormatString>
|
||||||
|
</ListItem>
|
||||||
|
<ListItem>
|
||||||
|
<PropertyName>NumberOfRelocations</PropertyName>
|
||||||
|
<FormatString>0x{0:X4}</FormatString>
|
||||||
|
</ListItem>
|
||||||
|
<ListItem>
|
||||||
|
<PropertyName>NumberOfLinenumbers</PropertyName>
|
||||||
|
<FormatString>0x{0:X4}</FormatString>
|
||||||
|
</ListItem>
|
||||||
|
<ListItem>
|
||||||
|
<PropertyName>Characteristics</PropertyName>
|
||||||
|
</ListItem>
|
||||||
|
<ListItem>
|
||||||
|
<PropertyName>RawData</PropertyName>
|
||||||
|
</ListItem>
|
||||||
|
<ListItem>
|
||||||
|
<PropertyName>Relocations</PropertyName>
|
||||||
|
</ListItem>
|
||||||
|
</ListItems>
|
||||||
|
</ListEntry>
|
||||||
|
</ListEntries>
|
||||||
|
</ListControl>
|
||||||
|
</View>
|
||||||
|
<View>
|
||||||
|
<Name>SymbolTableView</Name>
|
||||||
|
<ViewSelectedBy>
|
||||||
|
<TypeName>COFF.SYMBOL_TABLE</TypeName>
|
||||||
|
</ViewSelectedBy>
|
||||||
|
<TableControl>
|
||||||
|
<AutoSize/>
|
||||||
|
<TableHeaders>
|
||||||
|
<TableColumnHeader>
|
||||||
|
<Label>Name</Label>
|
||||||
|
</TableColumnHeader>
|
||||||
|
<TableColumnHeader>
|
||||||
|
<Label>Value</Label>
|
||||||
|
</TableColumnHeader>
|
||||||
|
<TableColumnHeader>
|
||||||
|
<Label>SectionNumber</Label>
|
||||||
|
</TableColumnHeader>
|
||||||
|
<TableColumnHeader>
|
||||||
|
<Label>Type</Label>
|
||||||
|
</TableColumnHeader>
|
||||||
|
<TableColumnHeader>
|
||||||
|
<Label>StorageClass</Label>
|
||||||
|
</TableColumnHeader>
|
||||||
|
<TableColumnHeader>
|
||||||
|
<Label>NumberOfAuxSymbols</Label>
|
||||||
|
</TableColumnHeader>
|
||||||
|
<TableColumnHeader>
|
||||||
|
<Label>AuxSymbols</Label>
|
||||||
|
</TableColumnHeader>
|
||||||
|
</TableHeaders>
|
||||||
|
<TableRowEntries>
|
||||||
|
<TableRowEntry>
|
||||||
|
<TableColumnItems>
|
||||||
|
<TableColumnItem>
|
||||||
|
<PropertyName>Name</PropertyName>
|
||||||
|
</TableColumnItem>
|
||||||
|
<TableColumnItem>
|
||||||
|
<PropertyName>Value</PropertyName>
|
||||||
|
<FormatString>0x{0:X8}</FormatString>
|
||||||
|
</TableColumnItem>
|
||||||
|
<TableColumnItem>
|
||||||
|
<PropertyName>SectionNumber</PropertyName>
|
||||||
|
</TableColumnItem>
|
||||||
|
<TableColumnItem>
|
||||||
|
<PropertyName>Type</PropertyName>
|
||||||
|
</TableColumnItem>
|
||||||
|
<TableColumnItem>
|
||||||
|
<PropertyName>StorageClass</PropertyName>
|
||||||
|
</TableColumnItem>
|
||||||
|
<TableColumnItem>
|
||||||
|
<PropertyName>NumberOfAuxSymbols</PropertyName>
|
||||||
|
<FormatString>0x{0:X2}</FormatString>
|
||||||
|
</TableColumnItem>
|
||||||
|
<TableColumnItem>
|
||||||
|
<PropertyName>AuxSymbols</PropertyName>
|
||||||
|
</TableColumnItem>
|
||||||
|
</TableColumnItems>
|
||||||
|
</TableRowEntry>
|
||||||
|
</TableRowEntries>
|
||||||
|
</TableControl>
|
||||||
|
</View>
|
||||||
|
<View>
|
||||||
|
<Name>SectionDefinitionView</Name>
|
||||||
|
<ViewSelectedBy>
|
||||||
|
<TypeName>COFF.SECTION_DEFINITION</TypeName>
|
||||||
|
</ViewSelectedBy>
|
||||||
|
<TableControl>
|
||||||
|
<AutoSize/>
|
||||||
|
<TableHeaders>
|
||||||
|
<TableColumnHeader>
|
||||||
|
<Label>Length</Label>
|
||||||
|
</TableColumnHeader>
|
||||||
|
<TableColumnHeader>
|
||||||
|
<Label>NumberOfRelocations</Label>
|
||||||
|
</TableColumnHeader>
|
||||||
|
<TableColumnHeader>
|
||||||
|
<Label>NumberOfLinenumbers</Label>
|
||||||
|
</TableColumnHeader>
|
||||||
|
<TableColumnHeader>
|
||||||
|
<Label>CheckSum</Label>
|
||||||
|
</TableColumnHeader>
|
||||||
|
<TableColumnHeader>
|
||||||
|
<Label>Number</Label>
|
||||||
|
</TableColumnHeader>
|
||||||
|
<TableColumnHeader>
|
||||||
|
<Label>Selection</Label>
|
||||||
|
</TableColumnHeader>
|
||||||
|
</TableHeaders>
|
||||||
|
<TableRowEntries>
|
||||||
|
<TableRowEntry>
|
||||||
|
<TableColumnItems>
|
||||||
|
<TableColumnItem>
|
||||||
|
<PropertyName>Length</PropertyName>
|
||||||
|
<FormatString>0x{0:X8}</FormatString>
|
||||||
|
</TableColumnItem>
|
||||||
|
<TableColumnItem>
|
||||||
|
<PropertyName>NumberOfRelocations</PropertyName>
|
||||||
|
<FormatString>0x{0:X4}</FormatString>
|
||||||
|
</TableColumnItem>
|
||||||
|
<TableColumnItem>
|
||||||
|
<PropertyName>NumberOfLinenumbers</PropertyName>
|
||||||
|
<FormatString>0x{0:X4}</FormatString>
|
||||||
|
</TableColumnItem>
|
||||||
|
<TableColumnItem>
|
||||||
|
<PropertyName>CheckSum</PropertyName>
|
||||||
|
<FormatString>0x{0:X8}</FormatString>
|
||||||
|
</TableColumnItem>
|
||||||
|
<TableColumnItem>
|
||||||
|
<PropertyName>Number</PropertyName>
|
||||||
|
<FormatString>0x{0:X4}</FormatString>
|
||||||
|
</TableColumnItem>
|
||||||
|
<TableColumnItem>
|
||||||
|
<PropertyName>Selection</PropertyName>
|
||||||
|
<FormatString>0x{0:X2}</FormatString>
|
||||||
|
</TableColumnItem>
|
||||||
|
</TableColumnItems>
|
||||||
|
</TableRowEntry>
|
||||||
|
</TableRowEntries>
|
||||||
|
</TableControl>
|
||||||
|
</View>
|
||||||
|
<View>
|
||||||
|
<Name>RelocationView</Name>
|
||||||
|
<ViewSelectedBy>
|
||||||
|
<TypeName>COFF.RelocationEntry</TypeName>
|
||||||
|
</ViewSelectedBy>
|
||||||
|
<TableControl>
|
||||||
|
<AutoSize/>
|
||||||
|
<TableHeaders>
|
||||||
|
<TableColumnHeader>
|
||||||
|
<Label>VirtualAddress</Label>
|
||||||
|
</TableColumnHeader>
|
||||||
|
<TableColumnHeader>
|
||||||
|
<Label>SymbolTableIndex</Label>
|
||||||
|
</TableColumnHeader>
|
||||||
|
<TableColumnHeader>
|
||||||
|
<Label>Type</Label>
|
||||||
|
</TableColumnHeader>
|
||||||
|
<TableColumnHeader>
|
||||||
|
<Label>Name</Label>
|
||||||
|
</TableColumnHeader>
|
||||||
|
</TableHeaders>
|
||||||
|
<TableRowEntries>
|
||||||
|
<TableRowEntry>
|
||||||
|
<TableColumnItems>
|
||||||
|
<TableColumnItem>
|
||||||
|
<PropertyName>VirtualAddress</PropertyName>
|
||||||
|
<FormatString>0x{0:X8}</FormatString>
|
||||||
|
</TableColumnItem>
|
||||||
|
<TableColumnItem>
|
||||||
|
<PropertyName>SymbolTableIndex</PropertyName>
|
||||||
|
<FormatString>0x{0:X8}</FormatString>
|
||||||
|
</TableColumnItem>
|
||||||
|
<TableColumnItem>
|
||||||
|
<PropertyName>Type</PropertyName>
|
||||||
|
</TableColumnItem>
|
||||||
|
<TableColumnItem>
|
||||||
|
<PropertyName>Name</PropertyName>
|
||||||
|
</TableColumnItem>
|
||||||
|
</TableColumnItems>
|
||||||
|
</TableRowEntry>
|
||||||
|
</TableRowEntries>
|
||||||
|
</TableControl>
|
||||||
|
</View>
|
||||||
|
</ViewDefinitions>
|
||||||
|
</Configuration>
|
||||||
|
|
@ -0,0 +1,708 @@
|
||||||
|
function Get-ObjDump
|
||||||
|
{
|
||||||
|
<#
|
||||||
|
.SYNOPSIS
|
||||||
|
|
||||||
|
Displays information about one or more Windows object files.
|
||||||
|
|
||||||
|
PowerSploit Function: Get-ObjDump
|
||||||
|
Author: Matthew Graeber (@mattifestation)
|
||||||
|
License: BSD 3-Clause
|
||||||
|
Required Dependencies: None
|
||||||
|
Optional Dependencies: None
|
||||||
|
|
||||||
|
.DESCRIPTION
|
||||||
|
|
||||||
|
Get-ObjDump parses and returns nearly identical infomation as the dumpbin
|
||||||
|
utility. By nature of Get-ObjDump returning objects though, it lends itself
|
||||||
|
much better to manipulation since every field is an object.
|
||||||
|
|
||||||
|
.PARAMETER Path
|
||||||
|
|
||||||
|
Specifies a path to one or more object file locations.
|
||||||
|
|
||||||
|
.EXAMPLE
|
||||||
|
|
||||||
|
C:\PS>Get-ObjDump -Path main.obj
|
||||||
|
|
||||||
|
.EXAMPLE
|
||||||
|
|
||||||
|
C:\PS>ls *.obj | Get-ObjDump
|
||||||
|
|
||||||
|
.EXAMPLE
|
||||||
|
|
||||||
|
C:\PS>$ObjectFile = Get-ObjDump -Path shellcode.obj
|
||||||
|
C:\PS>$CodeBytes = $ObjectFile.SectionHeaders | ? {$_.Name -eq '.text'} | % {$_.RawData}
|
||||||
|
|
||||||
|
Description
|
||||||
|
-----------
|
||||||
|
Pulls the raw bytes out of the text section. Note that in this form,
|
||||||
|
no relocations have been fixed up.
|
||||||
|
|
||||||
|
.INPUTS
|
||||||
|
|
||||||
|
System.String[]
|
||||||
|
|
||||||
|
You can pipe a file system path (in quotation marks) to Get-ObjDump.
|
||||||
|
|
||||||
|
.OUTPUTS
|
||||||
|
|
||||||
|
COFF.OBJECT_FILE
|
||||||
|
|
||||||
|
.LINK
|
||||||
|
|
||||||
|
http://www.exploit-monday.com/
|
||||||
|
#>
|
||||||
|
[CmdletBinding()] Param (
|
||||||
|
[Parameter(Position = 0, Mandatory = $True, ValueFromPipeline = $True)]
|
||||||
|
[ValidateScript({ Test-Path $_ })]
|
||||||
|
[String[]]
|
||||||
|
$Path
|
||||||
|
)
|
||||||
|
|
||||||
|
BEGIN
|
||||||
|
{
|
||||||
|
$Code = @'
|
||||||
|
using System;
|
||||||
|
using System.IO;
|
||||||
|
using System.Text;
|
||||||
|
|
||||||
|
namespace COFF
|
||||||
|
{
|
||||||
|
public enum Machine : ushort
|
||||||
|
{
|
||||||
|
UNKNOWN = 0,
|
||||||
|
I386 = 0x014C, // Intel 386.
|
||||||
|
R3000 = 0x0162, // MIPS little-endian =0x160 big-endian
|
||||||
|
R4000 = 0x0166, // MIPS little-endian
|
||||||
|
R10000 = 0x0168, // MIPS little-endian
|
||||||
|
WCEMIPSV2 = 0x0169, // MIPS little-endian WCE v2
|
||||||
|
ALPHA = 0x0184, // Alpha_AXP
|
||||||
|
SH3 = 0x01A2, // SH3 little-endian
|
||||||
|
SH3DSP = 0x01A3,
|
||||||
|
SH3E = 0x01A4, // SH3E little-endian
|
||||||
|
SH4 = 0x01A6, // SH4 little-endian
|
||||||
|
SH5 = 0x01A8, // SH5
|
||||||
|
ARM = 0x01C0, // ARM Little-Endian
|
||||||
|
THUMB = 0x01C2,
|
||||||
|
ARMV7 = 0x01C4, // ARM Thumb-2 Little-Endian
|
||||||
|
AM33 = 0x01D3,
|
||||||
|
POWERPC = 0x01F0, // IBM PowerPC Little-Endian
|
||||||
|
POWERPCFP = 0x01F1,
|
||||||
|
IA64 = 0x0200, // Intel 64
|
||||||
|
MIPS16 = 0x0266, // MIPS
|
||||||
|
ALPHA64 = 0x0284, // ALPHA64
|
||||||
|
MIPSFPU = 0x0366, // MIPS
|
||||||
|
MIPSFPU16 = 0x0466, // MIPS
|
||||||
|
AXP64 = ALPHA64,
|
||||||
|
TRICORE = 0x0520, // Infineon
|
||||||
|
CEF = 0x0CEF,
|
||||||
|
EBC = 0x0EBC, // EFI public byte Code
|
||||||
|
AMD64 = 0x8664, // AMD64 (K8)
|
||||||
|
M32R = 0x9041, // M32R little-endian
|
||||||
|
ARM64 = 0xAA64, // ARMv8 in 64-bit mode
|
||||||
|
CEE = 0xC0EE
|
||||||
|
}
|
||||||
|
|
||||||
|
[Flags]
|
||||||
|
public enum CoffHeaderCharacteristics : ushort
|
||||||
|
{
|
||||||
|
RELOCS_STRIPPED = 0x0001, // Relocation info stripped from file.
|
||||||
|
EXECUTABLE_IMAGE = 0x0002, // File is executable (i.e. no unresolved external references).
|
||||||
|
LINE_NUMS_STRIPPED = 0x0004, // Line nunbers stripped from file.
|
||||||
|
LOCAL_SYMS_STRIPPED = 0x0008, // Local symbols stripped from file.
|
||||||
|
AGGRESIVE_WS_TRIM = 0x0010, // Agressively trim working set
|
||||||
|
LARGE_ADDRESS_AWARE = 0x0020, // App can handle >2gb addresses
|
||||||
|
REVERSED_LO = 0x0080, // public bytes of machine public ushort are reversed.
|
||||||
|
BIT32_MACHINE = 0x0100, // 32 bit public ushort machine.
|
||||||
|
DEBUG_STRIPPED = 0x0200, // Debugging info stripped from file in .DBG file
|
||||||
|
REMOVABLE_RUN_FROM_SWAP = 0x0400, // If Image is on removable media =copy and run from the swap file.
|
||||||
|
NET_RUN_FROM_SWAP = 0x0800, // If Image is on Net =copy and run from the swap file.
|
||||||
|
SYSTEM = 0x1000, // System File.
|
||||||
|
DLL = 0x2000, // File is a DLL.
|
||||||
|
UP_SYSTEM_ONLY = 0x4000, // File should only be run on a UP machine
|
||||||
|
REVERSED_HI = 0x8000 // public bytes of machine public ushort are reversed.
|
||||||
|
}
|
||||||
|
|
||||||
|
public class HEADER
|
||||||
|
{
|
||||||
|
public Machine Machine;
|
||||||
|
public ushort NumberOfSections;
|
||||||
|
public DateTime TimeDateStamp;
|
||||||
|
public uint PointerToSymbolTable;
|
||||||
|
public uint NumberOfSymbols;
|
||||||
|
public ushort SizeOfOptionalHeader;
|
||||||
|
public CoffHeaderCharacteristics Characteristics;
|
||||||
|
|
||||||
|
public HEADER(BinaryReader br)
|
||||||
|
{
|
||||||
|
this.Machine = (Machine) br.ReadUInt16();
|
||||||
|
this.NumberOfSections = br.ReadUInt16();
|
||||||
|
this.TimeDateStamp = (new DateTime(1970, 1, 1, 0, 0, 0)).AddSeconds(br.ReadUInt32());
|
||||||
|
this.PointerToSymbolTable = br.ReadUInt32();
|
||||||
|
this.NumberOfSymbols = br.ReadUInt32();
|
||||||
|
this.SizeOfOptionalHeader = br.ReadUInt16();
|
||||||
|
this.Characteristics = (CoffHeaderCharacteristics) br.ReadUInt16();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
[Flags]
|
||||||
|
public enum SectionHeaderCharacteristics : uint
|
||||||
|
{
|
||||||
|
TYPE_NO_PAD = 0x00000008, // Reserved.
|
||||||
|
CNT_CODE = 0x00000020, // Section contains code.
|
||||||
|
CNT_INITIALIZED_DATA = 0x00000040, // Section contains initialized data.
|
||||||
|
CNT_UNINITIALIZED_DATA = 0x00000080, // Section contains uninitialized data.
|
||||||
|
LNK_INFO = 0x00000200, // Section contains comments or some other type of information.
|
||||||
|
LNK_REMOVE = 0x00000800, // Section contents will not become part of image.
|
||||||
|
LNK_COMDAT = 0x00001000, // Section contents comdat.
|
||||||
|
NO_DEFER_SPEC_EXC = 0x00004000, // Reset speculative exceptions handling bits in the TLB entries for this section.
|
||||||
|
GPREL = 0x00008000, // Section content can be accessed relative to GP
|
||||||
|
MEM_FARDATA = 0x00008000,
|
||||||
|
MEM_PURGEABLE = 0x00020000,
|
||||||
|
MEM_16BIT = 0x00020000,
|
||||||
|
MEM_LOCKED = 0x00040000,
|
||||||
|
MEM_PRELOAD = 0x00080000,
|
||||||
|
ALIGN_1BYTES = 0x00100000,
|
||||||
|
ALIGN_2BYTES = 0x00200000,
|
||||||
|
ALIGN_4BYTES = 0x00300000,
|
||||||
|
ALIGN_8BYTES = 0x00400000,
|
||||||
|
ALIGN_16BYTES = 0x00500000, // Default alignment if no others are specified.
|
||||||
|
ALIGN_32BYTES = 0x00600000,
|
||||||
|
ALIGN_64BYTES = 0x00700000,
|
||||||
|
ALIGN_128BYTES = 0x00800000,
|
||||||
|
ALIGN_256BYTES = 0x00900000,
|
||||||
|
ALIGN_512BYTES = 0x00A00000,
|
||||||
|
ALIGN_1024BYTES = 0x00B00000,
|
||||||
|
ALIGN_2048BYTES = 0x00C00000,
|
||||||
|
ALIGN_4096BYTES = 0x00D00000,
|
||||||
|
ALIGN_8192BYTES = 0x00E00000,
|
||||||
|
ALIGN_MASK = 0x00F00000,
|
||||||
|
LNK_NRELOC_OVFL = 0x01000000, // Section contains extended relocations.
|
||||||
|
MEM_DISCARDABLE = 0x02000000, // Section can be discarded.
|
||||||
|
MEM_NOT_CACHED = 0x04000000, // Section is not cachable.
|
||||||
|
MEM_NOT_PAGED = 0x08000000, // Section is not pageable.
|
||||||
|
MEM_SHARED = 0x10000000, // Section is shareable.
|
||||||
|
MEM_EXECUTE = 0x20000000, // Section is executable.
|
||||||
|
MEM_READ = 0x40000000, // Section is readable.
|
||||||
|
MEM_WRITE = 0x80000000 // Section is writeable.
|
||||||
|
}
|
||||||
|
|
||||||
|
public enum AMD64RelocationType : ushort
|
||||||
|
{
|
||||||
|
ABSOLUTE,
|
||||||
|
ADDR64,
|
||||||
|
ADDR32,
|
||||||
|
ADDR32NB,
|
||||||
|
REL32,
|
||||||
|
REL32_1,
|
||||||
|
REL32_2,
|
||||||
|
REL32_3,
|
||||||
|
REL32_4,
|
||||||
|
REL32_5,
|
||||||
|
SECTION,
|
||||||
|
SECREL,
|
||||||
|
SECREL7,
|
||||||
|
TOKEN,
|
||||||
|
SREL32,
|
||||||
|
PAIR,
|
||||||
|
SSPAN32
|
||||||
|
}
|
||||||
|
|
||||||
|
public enum ARMRelocationType : ushort
|
||||||
|
{
|
||||||
|
ABSOLUTE,
|
||||||
|
ADDR32,
|
||||||
|
ADDR32NB,
|
||||||
|
BRANCH24,
|
||||||
|
BRANCH11,
|
||||||
|
TOKEN,
|
||||||
|
BLX24 = 0x08,
|
||||||
|
BLX11 = 0x09,
|
||||||
|
SECTION = 0x0E,
|
||||||
|
SECREL = 0x0F,
|
||||||
|
MOV32A = 0x10,
|
||||||
|
MOV32T = 0x11,
|
||||||
|
BRANCH20T = 0x12,
|
||||||
|
BRANCH24T = 0x14,
|
||||||
|
BLX23T = 0x15
|
||||||
|
}
|
||||||
|
|
||||||
|
public enum ARMv8RelocationType : ushort
|
||||||
|
{
|
||||||
|
ABSOLUTE,
|
||||||
|
ADDR32,
|
||||||
|
ADDR32NB,
|
||||||
|
BRANCH26,
|
||||||
|
PAGEBASE_REL21,
|
||||||
|
REL21,
|
||||||
|
PAGEOFFSET_12A,
|
||||||
|
PAGEOFFSET_12L,
|
||||||
|
SECREL,
|
||||||
|
SECREL_LOW12A,
|
||||||
|
SECREL_HIGH12A,
|
||||||
|
SECREL_LOW12L,
|
||||||
|
TOKEN,
|
||||||
|
SECTION,
|
||||||
|
ADDR64
|
||||||
|
}
|
||||||
|
|
||||||
|
public enum X86RelocationType : ushort
|
||||||
|
{
|
||||||
|
ABSOLUTE,
|
||||||
|
DIR16,
|
||||||
|
DIR32 = 0x06,
|
||||||
|
DIR32NB = 0x07,
|
||||||
|
SEG12 = 0x09,
|
||||||
|
SECTION = 0x0A,
|
||||||
|
SECREL = 0x0B,
|
||||||
|
TOKEN = 0x0C,
|
||||||
|
SECREL7 = 0x0D,
|
||||||
|
REL32 = 0x14
|
||||||
|
}
|
||||||
|
|
||||||
|
public class RelocationEntry
|
||||||
|
{
|
||||||
|
public uint VirtualAddress;
|
||||||
|
public uint SymbolTableIndex;
|
||||||
|
public Enum Type;
|
||||||
|
public string Name;
|
||||||
|
|
||||||
|
public RelocationEntry(BinaryReader br)
|
||||||
|
{
|
||||||
|
this.VirtualAddress = br.ReadUInt32();
|
||||||
|
this.SymbolTableIndex = br.ReadUInt32();
|
||||||
|
// Default to X86RelocationType. This will be changed once the processor type is determined
|
||||||
|
this.Type = (X86RelocationType) br.ReadUInt16();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public class SECTION_HEADER
|
||||||
|
{
|
||||||
|
public string Name;
|
||||||
|
public uint PhysicalAddress;
|
||||||
|
public uint VirtualSize;
|
||||||
|
public uint VirtualAddress;
|
||||||
|
public uint SizeOfRawData;
|
||||||
|
public uint PointerToRawData;
|
||||||
|
public uint PointerToRelocations;
|
||||||
|
public uint PointerToLinenumbers;
|
||||||
|
public ushort NumberOfRelocations;
|
||||||
|
public ushort NumberOfLinenumbers;
|
||||||
|
public SectionHeaderCharacteristics Characteristics;
|
||||||
|
public Byte[] RawData;
|
||||||
|
public RelocationEntry[] Relocations;
|
||||||
|
|
||||||
|
public SECTION_HEADER(BinaryReader br)
|
||||||
|
{
|
||||||
|
this.Name = Encoding.UTF8.GetString(br.ReadBytes(8)).Split((Char) 0)[0];
|
||||||
|
this.PhysicalAddress = br.ReadUInt32();
|
||||||
|
this.VirtualSize = this.PhysicalAddress;
|
||||||
|
this.VirtualAddress = br.ReadUInt32();
|
||||||
|
this.SizeOfRawData = br.ReadUInt32();
|
||||||
|
this.PointerToRawData = br.ReadUInt32();
|
||||||
|
this.PointerToRelocations = br.ReadUInt32();
|
||||||
|
this.PointerToLinenumbers = br.ReadUInt32();
|
||||||
|
this.NumberOfRelocations = br.ReadUInt16();
|
||||||
|
this.NumberOfLinenumbers = br.ReadUInt16();
|
||||||
|
this.Characteristics = (SectionHeaderCharacteristics) br.ReadUInt32();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public enum SectionNumber : short
|
||||||
|
{
|
||||||
|
UNDEFINED,
|
||||||
|
ABSOLUTE = -1,
|
||||||
|
DEBUG = -2
|
||||||
|
}
|
||||||
|
|
||||||
|
[Flags]
|
||||||
|
public enum TypeClass : short
|
||||||
|
{
|
||||||
|
TYPE_NULL,
|
||||||
|
TYPE_VOID,
|
||||||
|
TYPE_CHAR,
|
||||||
|
TYPE_SHORT,
|
||||||
|
TYPE_INT,
|
||||||
|
TYPE_LONG,
|
||||||
|
TYPE_FLOAT,
|
||||||
|
TYPE_DOUBLE,
|
||||||
|
TYPE_STRUCT,
|
||||||
|
TYPE_UNION,
|
||||||
|
TYPE_ENUM,
|
||||||
|
TYPE_MOE,
|
||||||
|
TYPE_BYTE,
|
||||||
|
TYPE_WORD,
|
||||||
|
TYPE_UINT,
|
||||||
|
TYPE_DWORD,
|
||||||
|
DTYPE_POINTER = 0x100,
|
||||||
|
DTYPE_FUNCTION = 0x200,
|
||||||
|
DTYPE_ARRAY = 0x300,
|
||||||
|
DTYPE_NULL = 0x400 // Technically, this is defined as 0 in the MSB
|
||||||
|
}
|
||||||
|
|
||||||
|
public enum StorageClass : byte
|
||||||
|
{
|
||||||
|
NULL,
|
||||||
|
AUTOMATIC,
|
||||||
|
EXTERNAL,
|
||||||
|
STATIC,
|
||||||
|
REGISTER,
|
||||||
|
EXTERNAL_DEF,
|
||||||
|
LABEL,
|
||||||
|
UNDEFINED_LABEL,
|
||||||
|
MEMBER_OF_STRUCT,
|
||||||
|
ARGUMENT,
|
||||||
|
STRUCT_TAG,
|
||||||
|
MEMBER_OF_UNION,
|
||||||
|
UNION_TAG,
|
||||||
|
TYPE_DEFINITION,
|
||||||
|
ENUM_TAG,
|
||||||
|
MEMBER_OF_ENUM,
|
||||||
|
REGISTER_PARAM,
|
||||||
|
BIT_FIELD,
|
||||||
|
BLOCK = 0x64,
|
||||||
|
FUNCTION = 0x65,
|
||||||
|
END_OF_STRUCT = 0x66,
|
||||||
|
FILE = 0x67,
|
||||||
|
SECTION = 0x68,
|
||||||
|
WEAK_EXTERNAL = 0x69,
|
||||||
|
CLR_TOKEN = 0x6B,
|
||||||
|
END_OF_FUNCTION = 0xFF
|
||||||
|
}
|
||||||
|
|
||||||
|
public class SYMBOL_TABLE
|
||||||
|
{
|
||||||
|
public string Name;
|
||||||
|
public uint Value;
|
||||||
|
public SectionNumber SectionNumber;
|
||||||
|
public TypeClass Type;
|
||||||
|
public StorageClass StorageClass;
|
||||||
|
public byte NumberOfAuxSymbols;
|
||||||
|
public Object AuxSymbols;
|
||||||
|
private Byte[] NameArray;
|
||||||
|
|
||||||
|
public SYMBOL_TABLE(BinaryReader br)
|
||||||
|
{
|
||||||
|
this.NameArray = br.ReadBytes(8);
|
||||||
|
|
||||||
|
if (this.NameArray[0] == 0 && this.NameArray[1] == 0 &&this.NameArray[2] == 0 &&this.NameArray[3] == 0)
|
||||||
|
{
|
||||||
|
// Per specification, if the high DWORD is 0, then then low DWORD is an index into the string table
|
||||||
|
this.Name = "/" + BitConverter.ToInt32(NameArray, 4).ToString();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
this.Name = Encoding.UTF8.GetString(NameArray).Trim(((char) 0));
|
||||||
|
}
|
||||||
|
|
||||||
|
this.Value = br.ReadUInt32();
|
||||||
|
this.SectionNumber = (SectionNumber) br.ReadInt16();
|
||||||
|
this.Type = (TypeClass) br.ReadInt16();
|
||||||
|
if ((((int) this.Type) & 0xff00) == 0) { this.Type = (TypeClass) Enum.Parse(typeof(TypeClass), ((int) this.Type | 0x400).ToString());}
|
||||||
|
this.StorageClass = (StorageClass) br.ReadByte();
|
||||||
|
this.NumberOfAuxSymbols = br.ReadByte();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public class SECTION_DEFINITION
|
||||||
|
{
|
||||||
|
public uint Length;
|
||||||
|
public ushort NumberOfRelocations;
|
||||||
|
public ushort NumberOfLinenumbers;
|
||||||
|
public uint CheckSum;
|
||||||
|
public ushort Number;
|
||||||
|
public byte Selection;
|
||||||
|
|
||||||
|
public SECTION_DEFINITION(BinaryReader br)
|
||||||
|
{
|
||||||
|
this.Length = br.ReadUInt32();
|
||||||
|
this.NumberOfRelocations = br.ReadUInt16();
|
||||||
|
this.NumberOfLinenumbers = br.ReadUInt16();
|
||||||
|
this.CheckSum = br.ReadUInt32();
|
||||||
|
this.Number = br.ReadUInt16();
|
||||||
|
this.Selection = br.ReadByte();
|
||||||
|
br.ReadBytes(3);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
'@
|
||||||
|
|
||||||
|
Add-Type -TypeDefinition $Code
|
||||||
|
|
||||||
|
function Dispose-Objects
|
||||||
|
{
|
||||||
|
$BinaryReader.Dispose()
|
||||||
|
$FileStream.Dispose()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
PROCESS
|
||||||
|
{
|
||||||
|
foreach ($File in $Path) {
|
||||||
|
|
||||||
|
# Resolve the absolute path of the object file. [IO.File]::OpenRead requires an absolute path.
|
||||||
|
$ObjFilePath = Resolve-Path $File
|
||||||
|
|
||||||
|
# Pull out just the file name
|
||||||
|
$ObjFileName = Split-Path $ObjFilePath -Leaf
|
||||||
|
|
||||||
|
# Fixed structure sizes
|
||||||
|
$SizeofCOFFFileHeader = 20
|
||||||
|
$SizeofSectionHeader = 40
|
||||||
|
$SizeofSymbolTableEntry = 18
|
||||||
|
$SizeofRelocationEntry = 10
|
||||||
|
|
||||||
|
# Open the object file for reading
|
||||||
|
$FileStream = [IO.File]::OpenRead($ObjFilePath)
|
||||||
|
|
||||||
|
$FileLength = $FileStream.Length
|
||||||
|
|
||||||
|
if ($FileLength -lt $SizeofCOFFFileHeader)
|
||||||
|
{
|
||||||
|
# You cannot parse the COFF header if the file is not big enough to contain a COFF header.
|
||||||
|
Write-Error "$($ObjFileName) is too small to store a COFF header."
|
||||||
|
Dispose-Objects
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
# Open a BinaryReader object for the object file
|
||||||
|
$BinaryReader = New-Object IO.BinaryReader($FileStream)
|
||||||
|
|
||||||
|
# Parse the COFF header
|
||||||
|
$CoffHeader = New-Object COFF.HEADER($BinaryReader)
|
||||||
|
|
||||||
|
if ($CoffHeader.SizeOfOptionalHeader -ne 0)
|
||||||
|
{
|
||||||
|
# Per the PECOFF specification, an object file does not have an optional header
|
||||||
|
Write-Error "Coff header indicates the existence of an optional header. An object file cannot have an optional header."
|
||||||
|
Dispose-Objects
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($CoffHeader.PointerToSymbolTable -eq 0)
|
||||||
|
{
|
||||||
|
Write-Error 'An object file is supposed to have a symbol table.'
|
||||||
|
Dispose-Objects
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($FileLength -lt (($CoffHeader.NumberOfSections * $SizeofSectionHeader) + $SizeofCOFFFileHeader))
|
||||||
|
{
|
||||||
|
# The object file isn't big enough to store the number of sections present.
|
||||||
|
Write-Error "$($ObjFileName) is too small to store section header data."
|
||||||
|
Dispose-Objects
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
# A string collection used to store section header names. This collection is referenced while
|
||||||
|
# parsing the symbol table entries whose name is the same as the section header. In this case,
|
||||||
|
# the symbol entry will have a particular auxiliary symbol table entry.
|
||||||
|
$SectionHeaderNames = New-Object Collections.Specialized.StringCollection
|
||||||
|
|
||||||
|
# Correlate the processor type to the relocation type. There are more relocation type defined
|
||||||
|
# in the PECOFF specification, but I don't expect those to be present. In that case, relocation
|
||||||
|
# entries default to X86RelocationType.
|
||||||
|
$SectionHeaders = New-Object COFF.SECTION_HEADER[]($CoffHeader.NumberOfSections)
|
||||||
|
$MachineTypes = @{ [COFF.Machine]::I386 = [COFF.X86RelocationType]
|
||||||
|
[COFF.Machine]::AMD64 = [COFF.AMD64RelocationType]
|
||||||
|
[COFF.Machine]::ARMV7 = [COFF.ARMRelocationType]
|
||||||
|
[COFF.Machine]::ARM64 = [COFF.ARMv8RelocationType] }
|
||||||
|
|
||||||
|
# Parse section headers
|
||||||
|
for ($i = 0; $i -lt $CoffHeader.NumberOfSections; $i++)
|
||||||
|
{
|
||||||
|
$SectionHeaders[$i] = New-Object COFF.SECTION_HEADER($BinaryReader)
|
||||||
|
|
||||||
|
# Add the section name to the string collection. This will be referenced during symbol table parsing.
|
||||||
|
$SectionHeaderNames.Add($SectionHeaders[$i].Name) | Out-Null
|
||||||
|
|
||||||
|
# Save the current filestream position. We are about to jump out of place.
|
||||||
|
$SavedFilePosition = $FileStream.Position
|
||||||
|
|
||||||
|
# Check to see if the raw data points beyond the actual file size
|
||||||
|
if (($SectionHeaders[$i].PointerToRawData + $SectionHeaders[$i].SizeOfRawData) -gt $FileLength)
|
||||||
|
{
|
||||||
|
Write-Error "$($SectionHeaders[$i].Name) section header's raw data exceeds the size of the object file."
|
||||||
|
return
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
# Read the raw data into a byte array
|
||||||
|
$FileStream.Seek($SectionHeaders[$i].PointerToRawData, 'Begin') | Out-Null
|
||||||
|
$SectionHeaders[$i].RawData = $BinaryReader.ReadBytes($SectionHeaders[$i].SizeOfRawData)
|
||||||
|
}
|
||||||
|
|
||||||
|
# Check to see if the section has a relocation table
|
||||||
|
if ($SectionHeaders[$i].PointerToRelocations -and $SectionHeaders[$i].NumberOfRelocations)
|
||||||
|
{
|
||||||
|
# Check to see if the relocation entries point beyond the actual file size
|
||||||
|
if (($SectionHeaders[$i].PointerToRelocations + ($SizeofRelocationEntry * $SectionHeaders[$i].NumberOfRelocations)) -gt $FileLength)
|
||||||
|
{
|
||||||
|
Write-Error "$($SectionHeaders[$i].Name) section header's relocation entries exceeds the soze of the object file."
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
$FileStream.Seek($SectionHeaders[$i].PointerToRelocations, 'Begin') | Out-Null
|
||||||
|
|
||||||
|
$Relocations = New-Object COFF.RelocationEntry[]($SectionHeaders[$i].NumberOfRelocations)
|
||||||
|
|
||||||
|
for ($j = 0; $j -lt $SectionHeaders[$i].NumberOfRelocations; $j++)
|
||||||
|
{
|
||||||
|
$Relocations[$j] = New-Object COFF.RelocationEntry($BinaryReader)
|
||||||
|
# Cast the relocation as its respective type
|
||||||
|
$Relocations[$j].Type = ($Relocations[$j].Type.value__ -as $MachineTypes[$CoffHeader.Machine])
|
||||||
|
}
|
||||||
|
|
||||||
|
# Add the relocation table entry to the section header
|
||||||
|
$SectionHeaders[$i].Relocations = $Relocations
|
||||||
|
}
|
||||||
|
|
||||||
|
# Restore the original filestream pointer
|
||||||
|
$FileStream.Seek($SavedFilePosition, 'Begin') | Out-Null
|
||||||
|
}
|
||||||
|
|
||||||
|
# Retrieve the contents of the COFF string table
|
||||||
|
$SymTableSize = $CoffHeader.NumberOfSymbols * $SizeofSymbolTableEntry
|
||||||
|
$StringTableOffset = $CoffHeader.PointerToSymbolTable + $SymTableSize
|
||||||
|
|
||||||
|
if ($StringTableOffset -gt $FileLength)
|
||||||
|
{
|
||||||
|
Write-Error 'The string table points beyond the end of the file.'
|
||||||
|
Dispose-Objects
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
$FileStream.Seek($StringTableOffset, 'Begin') | Out-Null
|
||||||
|
$StringTableLength = $BinaryReader.ReadUInt32()
|
||||||
|
|
||||||
|
if ($StringTableLength -gt $FileLength)
|
||||||
|
{
|
||||||
|
Write-Error "The string table's length exceeds the length of the file."
|
||||||
|
Dispose-Objects
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
$StringTable = [Text.Encoding]::UTF8.GetString($BinaryReader.ReadBytes($StringTableLength))
|
||||||
|
|
||||||
|
$RawSymbolTable = New-Object COFF.SYMBOL_TABLE[]($CoffHeader.NumberOfSymbols)
|
||||||
|
|
||||||
|
# Retrieve the symbol table
|
||||||
|
if ($FileLength -lt $StringTableOffset)
|
||||||
|
{
|
||||||
|
"Symbol table is larger than the file size."
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
$FileStream.Seek($CoffHeader.PointerToSymbolTable, 'Begin') | Out-Null
|
||||||
|
$NumberofRegularSymbols = 0
|
||||||
|
|
||||||
|
<#
|
||||||
|
Go through each symbol table looking for auxiliary symbols to parse
|
||||||
|
|
||||||
|
Currently supported auxiliary symbol table entry formats:
|
||||||
|
1) .file
|
||||||
|
2) Entry names that match the name of a section header
|
||||||
|
#>
|
||||||
|
for ($i = 0; $i -lt $CoffHeader.NumberOfSymbols; $i++)
|
||||||
|
{
|
||||||
|
# Parse the symbol tables regardless of whether they are normal or auxiliary symbols
|
||||||
|
$RawSymbolTable[$i] = New-Object COFF.SYMBOL_TABLE($BinaryReader)
|
||||||
|
|
||||||
|
if ($RawSymbolTable[$i].NumberOfAuxSymbols -eq 0)
|
||||||
|
{
|
||||||
|
# This symbol table entry has no auxiliary symbols
|
||||||
|
$NumberofRegularSymbols++
|
||||||
|
}
|
||||||
|
elseif ($RawSymbolTable[$i].Name -eq '.file')
|
||||||
|
{
|
||||||
|
$TempPosition = $FileStream.Position # Save filestream position
|
||||||
|
# Retrieve the file name
|
||||||
|
$RawSymbolTable[$i].AuxSymbols = [Text.Encoding]::UTF8.GetString($BinaryReader.ReadBytes($RawSymbolTable[$i].NumberOfAuxSymbols * $SizeofSymbolTableEntry)).TrimEnd(([Char] 0))
|
||||||
|
$FileStream.Seek($TempPosition, 'Begin') | Out-Null # Restore filestream position
|
||||||
|
}
|
||||||
|
elseif ($SectionHeaderNames.Contains($RawSymbolTable[$i].Name))
|
||||||
|
{
|
||||||
|
$TempPosition = $FileStream.Position # Save filestream position
|
||||||
|
$RawSymbolTable[$i].AuxSymbols = New-Object COFF.SECTION_DEFINITION($BinaryReader)
|
||||||
|
$FileStream.Seek($TempPosition, 'Begin') | Out-Null # Restore filestream position
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
# Create an array of symbol table entries without auxiliary table entries
|
||||||
|
$SymbolTable = New-Object COFF.SYMBOL_TABLE[]($NumberofRegularSymbols)
|
||||||
|
$j = 0
|
||||||
|
|
||||||
|
for ($i = 0; $i -lt $CoffHeader.NumberOfSymbols; $i++)
|
||||||
|
{
|
||||||
|
$SymbolTable[$j] = $RawSymbolTable[$i] # FYI, the first symbol table entry will never be an aux symbol
|
||||||
|
$j++
|
||||||
|
|
||||||
|
# Skip over the auxiliary symbols
|
||||||
|
if ($RawSymbolTable[$i].NumberOfAuxSymbols -ne 0)
|
||||||
|
{
|
||||||
|
$i += $RawSymbolTable[$i].NumberOfAuxSymbols
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
# Dispose the binaryreader and filestream objects
|
||||||
|
Dispose-Objects
|
||||||
|
|
||||||
|
# Fix the section names if any of them point to the COFF string table
|
||||||
|
for ($i = 0; $i -lt $CoffHeader.NumberOfSections; $i++)
|
||||||
|
{
|
||||||
|
if ($SectionHeaders[$i].Name.IndexOf('/') -eq 0)
|
||||||
|
{
|
||||||
|
$StringTableIndex = $SectionHeaders[$i].Name.SubString(1)
|
||||||
|
|
||||||
|
if ($StringTableIndex -match '^[1-9][0-9]*$')
|
||||||
|
{
|
||||||
|
$StringTableIndex = ([Int] $StringTableIndex) - 4
|
||||||
|
|
||||||
|
if ($StringTableIndex -gt ($StringTableLength + 4))
|
||||||
|
{
|
||||||
|
Write-Error 'String table entry exceeds the bounds of the object file.'
|
||||||
|
}
|
||||||
|
|
||||||
|
$Length = $StringTable.IndexOf(([Char] 0), $StringTableIndex)
|
||||||
|
$SectionHeaders[$i].Name = $StringTable.Substring($StringTableIndex, $Length)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
# Fix the symbol table names
|
||||||
|
for ($i = 0; $i -lt $SymbolTable.Length; $i++)
|
||||||
|
{
|
||||||
|
if ($SymbolTable[$i].Name.IndexOf('/') -eq 0)
|
||||||
|
{
|
||||||
|
$StringTableIndex = $SymbolTable[$i].Name.SubString(1)
|
||||||
|
|
||||||
|
if ($StringTableIndex -match '^[1-9][0-9]*$')
|
||||||
|
{
|
||||||
|
$StringTableIndex = ([Int] $StringTableIndex) - 4
|
||||||
|
$Length = $StringTable.IndexOf(([Char] 0), $StringTableIndex) - $StringTableIndex
|
||||||
|
$SymbolTable[$i].Name = $StringTable.Substring($StringTableIndex, $Length)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
# Apply symbol names to the relocation entries
|
||||||
|
$SectionHeaders | Where-Object { $_.Relocations } | % {
|
||||||
|
$_.Relocations | % { $_.Name = $RawSymbolTable[$_.SymbolTableIndex].Name }
|
||||||
|
}
|
||||||
|
|
||||||
|
$Result = @{
|
||||||
|
COFFHeader = $CoffHeader
|
||||||
|
SectionHeaders = $SectionHeaders
|
||||||
|
SymbolTable = $SymbolTable
|
||||||
|
}
|
||||||
|
|
||||||
|
$ParsedObjectFile = New-Object PSObject -Property $Result
|
||||||
|
$ParsedObjectFile.PSObject.TypeNames[0] = 'COFF.OBJECT_FILE'
|
||||||
|
Write-Output $ParsedObjectFile
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
END {}
|
||||||
|
}
|
||||||
|
|
@ -52,7 +52,7 @@ PowerShellVersion = '2.0'
|
||||||
# TypesToProcess = @()
|
# TypesToProcess = @()
|
||||||
|
|
||||||
# Format files (.ps1xml) to be loaded when importing this module
|
# Format files (.ps1xml) to be loaded when importing this module
|
||||||
FormatsToProcess = 'PETools.format.ps1xml'
|
FormatsToProcess = 'PETools.format.ps1xml', 'Get-ObjDump.format.ps1xml'
|
||||||
|
|
||||||
# Modules to import as nested modules of the module specified in RootModule/ModuleToProcess
|
# Modules to import as nested modules of the module specified in RootModule/ModuleToProcess
|
||||||
# NestedModules = @()
|
# NestedModules = @()
|
||||||
|
|
@ -74,7 +74,8 @@ ModuleList = @(@{ModuleName = 'PETools'; ModuleVersion = '1.0.0.0'; GUID = 'd150
|
||||||
|
|
||||||
# List of all files packaged with this module
|
# List of all files packaged with this module
|
||||||
FileList = 'PETools.psm1', 'PETools.psd1', 'PETools.format.ps1xml', 'Get-DllLoadPath.ps1',
|
FileList = 'PETools.psm1', 'PETools.psd1', 'PETools.format.ps1xml', 'Get-DllLoadPath.ps1',
|
||||||
'Get-PEArchitecture.ps1', 'Get-PEHeader.ps1', 'Usage.md'
|
'Get-PEArchitecture.ps1', 'Get-PEHeader.ps1', 'Get-ObjDump.ps1', 'Get-ObjDump.format.ps1xml',
|
||||||
|
'Usage.md'
|
||||||
|
|
||||||
# Private data to pass to the module specified in RootModule/ModuleToProcess
|
# Private data to pass to the module specified in RootModule/ModuleToProcess
|
||||||
# PrivateData = ''
|
# PrivateData = ''
|
||||||
|
|
|
||||||
|
|
@ -68,6 +68,10 @@ Add persistence capabilities to a script.
|
||||||
|
|
||||||
An in-memory and on-disk PE parsing utility.
|
An in-memory and on-disk PE parsing utility.
|
||||||
|
|
||||||
|
#### `Get-ObjDump`
|
||||||
|
|
||||||
|
Displays information about one or more Windows object files.
|
||||||
|
|
||||||
#### `Get-PEArchitecture`
|
#### `Get-PEArchitecture`
|
||||||
|
|
||||||
Returns the architecture for which an executable was compiled.
|
Returns the architecture for which an executable was compiled.
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue