aboutsummaryrefslogtreecommitdiff
path: root/PETools
diff options
context:
space:
mode:
Diffstat (limited to 'PETools')
-rw-r--r--PETools/Get-DllLoadPath.ps1190
-rw-r--r--PETools/Get-LibSymbols.format.ps1xml31
-rw-r--r--PETools/Get-LibSymbols.ps1282
-rw-r--r--PETools/Get-ObjDump.format.ps1xml292
-rw-r--r--PETools/Get-ObjDump.ps1708
-rw-r--r--PETools/Get-PEHeader.ps1960
-rw-r--r--PETools/PETools.format.ps1xml374
-rw-r--r--PETools/PETools.psd189
-rw-r--r--PETools/PETools.psm11
-rw-r--r--PETools/Usage.md12
10 files changed, 0 insertions, 2939 deletions
diff --git a/PETools/Get-DllLoadPath.ps1 b/PETools/Get-DllLoadPath.ps1
deleted file mode 100644
index 97b0210..0000000
--- a/PETools/Get-DllLoadPath.ps1
+++ /dev/null
@@ -1,190 +0,0 @@
-function Get-DllLoadPath
-{
-<#
-.SYNOPSIS
-
-Outputs the order of paths in which a dll would be loaded.
-
-PowerSploit Function: Get-DllLoadPath
-Author: Matthew Graeber (@mattifestation)
-License: BSD 3-Clause
-Required Dependencies: None
-Optional Dependencies: None
-
-.DESCRIPTION
-
-Get-DllLoadPath returns the path from which Windows will load a Dll for the given executable.
-
-.PARAMETER ExecutablePath
-
-Path to the executable from which the Dll would be loaded.
-
-.PARAMETER DllName
-
-Name of the Dll in the form 'dllname.dll'.
-
-.EXAMPLE
-
-C:\PS> Get-DllLoadPath C:\Windows\System32\cmd.exe kernel32.dll
-
-Path
-----
-C:\Windows\system32\kernel32.dll
-
-.EXAMPLE
-
-C:\PS> Get-DllLoadPath C:\Windows\SysWOW64\calc.exe Comctl32.dll
-
-Path
-----
-C:\Windows\SysWOW64\Comctl32.dll
-
-.OUTPUTS
-
-System.Management.Automation.PathInfo
-
-.NOTES
-
-This script will not detect if the executable provided intentionally alters the Dll search path via LoadLibraryEx, SetDllDirectory, or AddDllDirectory.
-
-.LINK
-
-http://www.exploit-monday.com
-http://msdn.microsoft.com/en-us/library/windows/desktop/ms682586%28v=vs.85%29.aspx
-#>
-
- Param (
- [Parameter(Position = 0, Mandatory = $True)]
- [String]
- $ExecutablePath,
-
- [Parameter(Position = 1, Mandatory = $True)]
- [String]
- $DllName
- )
-
- if (!(Test-Path $ExecutablePath)) {
- Write-Warning 'Invalid path or file does not exist.'
- return
- } else {
- $ExecutablePath = Resolve-Path $ExecutablePath
- $ExecutableDirectory = Split-Path $ExecutablePath
- }
-
- if ($DllName.Contains('.dll')) {
- $DllNameShort = $DllName.Split('.')[0]
- } else {
- Write-Warning 'You must provide a proper dll name (i.e. kernel32.dll)'
- return
- }
-
- function Get-PEArchitecture {
-
- Param ( [Parameter(Position = 0, Mandatory = $True)] [String] $Path )
-
- # Parse PE header to see if binary was compiled 32 or 64-bit
- $FileStream = New-Object System.IO.FileStream($Path, [System.IO.FileMode]::Open, [System.IO.FileAccess]::Read)
-
- [Byte[]] $MZHeader = New-Object Byte[](2)
- $FileStream.Read($MZHeader,0,2) | Out-Null
-
- $Header = [System.Text.AsciiEncoding]::ASCII.GetString($MZHeader)
- if ($Header -ne 'MZ') {
- Write-Warning 'Invalid PE header.'
- $FileStream.Close()
- return
- }
-
- # Seek to 0x3c - IMAGE_DOS_HEADER.e_lfanew (i.e. Offset to PE Header)
- $FileStream.Seek(0x3c, [System.IO.SeekOrigin]::Begin) | Out-Null
-
- [Byte[]] $lfanew = New-Object Byte[](4)
-
- # Read offset to the PE Header (will be read in reverse)
- $FileStream.Read($lfanew,0,4) | Out-Null
- $PEOffset = [Int] ('0x{0}' -f (( $lfanew[-1..-4] | % { $_.ToString('X2') } ) -join ''))
-
- # Seek to IMAGE_FILE_HEADER.IMAGE_FILE_MACHINE
- $FileStream.Seek($PEOffset + 4, [System.IO.SeekOrigin]::Begin) | Out-Null
- [Byte[]] $IMAGE_FILE_MACHINE = New-Object Byte[](2)
-
- # Read compiled architecture
- $FileStream.Read($IMAGE_FILE_MACHINE,0,2) | Out-Null
- $Architecture = '{0}' -f (( $IMAGE_FILE_MACHINE[-1..-2] | % { $_.ToString('X2') } ) -join '')
- $FileStream.Close()
-
- if (($Architecture -ne '014C') -and ($Architecture -ne '8664')) {
- Write-Warning 'Invalid PE header or unsupported architecture.'
- return
- }
-
- if ($Architecture -eq '014C') {
- return 'X86'
- } elseif ($Architecture -eq '8664') {
- return 'X64'
- } else {
- return 'OTHER'
- }
-
- }
-
- # Check if SafeDllSearch is disabled. Note: The logic of this check will fail in XP SP0/1
- $UnsafeSearch = $False
- $SearchMode = (Get-ItemProperty 'HKLM:\SYSTEM\CurrentControlSet\Control\Session Manager').SafeDllSearchMode
- if ($SearchMode -eq 0) { $UnsafeSearch = $True }
-
- $OSArch = (Get-WmiObject Win32_OperatingSystem -Property OSArchitecture).OSArchitecture
- $PEArch = Get-PEArchitecture $ExecutablePath
- $KnownDlls = Get-ItemProperty 'HKLM:\SYSTEM\CurrentControlSet\Control\Session Manager\KnownDLLs'
-
- if ($OSArch -eq '32-bit') {
- $DllDirectory = Resolve-Path $KnownDlls.DllDirectory
- } else {
- if ($PEArch -eq 'X86') {
- $DllDirectory = Resolve-Path $KnownDlls.DllDirectory32
- } else {
- $DllDirectory = Resolve-Path $KnownDlls.DllDirectory
- }
- }
-
-
- if ($KnownDlls | Get-Member -MemberType NoteProperty | Where-Object { $_.Name -eq $DllNameShort }) {
- $Expression = '$KnownDlls.' + "$DllNameShort"
- $Filename = Invoke-Expression $Expression
- return Resolve-Path (Join-Path $DllDirectory $Filename)
- }
-
- $FoundInAppDirectory = Get-ChildItem (Join-Path $ExecutableDirectory $DllName) -ErrorAction SilentlyContinue
- if ($FoundInAppDirectory) { return Resolve-Path $FoundInAppDirectory.FullName }
-
- if ($UnsafeSearch) {
- $FoundInWorkingDirectory = Get-ChildItem (Join-Path (Get-Location) $DllName) -ErrorAction SilentlyContinue
- if ($FoundInWorkingDirectory) { return Resolve-Path $FoundInWorkingDirectory.FullName }
- }
-
- $FoundInSystemDirectory = Get-ChildItem (Join-Path $DllDirectory $DllName) -ErrorAction SilentlyContinue
- if ($FoundInSystemDirectory) { return Resolve-Path $FoundInSystemDirectory.FullName }
-
- $FoundIn16BitSystemDir = Get-ChildItem "$($Env:windir)\System\$DllName" -ErrorAction SilentlyContinue
- if ($FoundIn16BitSystemDir) { return Resolve-Path $FoundIn16BitSystemDir.FullName }
-
- $FoundInWindowsDirectory = Get-ChildItem "$($Env:windir)\$DllName" -ErrorAction SilentlyContinue
- if ($FoundInWindowsDirectory) { return Resolve-Path $FoundInWindowsDirectory.FullName }
-
- if (!$UnsafeSearch) {
- $FoundInWorkingDirectory = Get-ChildItem (Join-Path (Get-Location) $DllName) -ErrorAction SilentlyContinue
- if ($FoundInWorkingDirectory) { return Resolve-Path $FoundInWorkingDirectory.FullName }
- }
-
- $Env:Path.Split(';') | ForEach-Object {
- if ($_ -match '%(.{1,})%') {
- $TempPath = $_.Replace($Matches[0], [Environment]::GetEnvironmentVariable($Matches[1]))
- } else {
- $TempPath = $_
- }
-
- $FoundInPathEnvVar = Get-ChildItem (Join-Path $TempPath $DllName) -ErrorAction SilentlyContinue
- if ($FoundInPathEnvVar) { return Resolve-Path $FoundInPathEnvVar.FullName }
- }
-
-}
diff --git a/PETools/Get-LibSymbols.format.ps1xml b/PETools/Get-LibSymbols.format.ps1xml
deleted file mode 100644
index 5d4d848..0000000
--- a/PETools/Get-LibSymbols.format.ps1xml
+++ /dev/null
@@ -1,31 +0,0 @@
-<?xml version="1.0" encoding="utf-8" ?>
-<Configuration>
- <ViewDefinitions>
- <View>
- <Name>SymbolTypeView</Name>
- <ViewSelectedBy>
- <TypeName>COFF.SymbolInfo</TypeName>
- </ViewSelectedBy>
- <ListControl>
- <ListEntries>
- <ListEntry>
- <ListItems>
- <ListItem>
- <PropertyName>SymbolType</PropertyName>
- </ListItem>
- <ListItem>
- <PropertyName>Module</PropertyName>
- </ListItem>
- <ListItem>
- <PropertyName>DecoratedName</PropertyName>
- </ListItem>
- <ListItem>
- <PropertyName>UndecoratedName</PropertyName>
- </ListItem>
- </ListItems>
- </ListEntry>
- </ListEntries>
- </ListControl>
- </View>
- </ViewDefinitions>
-</Configuration>
diff --git a/PETools/Get-LibSymbols.ps1 b/PETools/Get-LibSymbols.ps1
deleted file mode 100644
index 9864676..0000000
--- a/PETools/Get-LibSymbols.ps1
+++ /dev/null
@@ -1,282 +0,0 @@
-function Get-LibSymbols
-{
-<#
-.SYNOPSIS
-
- Displays symbolic information from Windows lib files.
-
- PowerSploit Function: Get-LibSymbols
- Author: Matthew Graeber (@mattifestation)
- License: BSD 3-Clause
- Required Dependencies: None
- Optional Dependencies: None
-
-.DESCRIPTION
-
- Get-LibSymbols parses and returns symbols in Windows .lib files
- in both decorated and undecorated form (for C++ functions).
-
-.PARAMETER Path
-
- Specifies a path to one or more lib file locations.
-
-.EXAMPLE
-
- C:\PS>Get-LibSymbols -Path msvcrt.lib
-
-.EXAMPLE
-
- C:\PS>ls *.lib | Get-LibSymbols
-
-.INPUTS
-
- System.String[]
-
- You can pipe a file system path (in quotation marks) to Get-LibSymbols.
-
-.OUTPUTS
-
- COFF.SymbolInfo
-
-.LINK
-
- http://www.exploit-monday.com/
-#>
- [CmdletBinding()] Param (
- [Parameter(Position = 0, Mandatory = $True, ValueFromPipelineByPropertyName = $True)]
- [ValidateScript({ Test-Path $_ })]
- [Alias('FullName')]
- [String[]]
- $Path
- )
-
- BEGIN
- {
- $Code = @'
- using System;
- using System.IO;
- using System.Text;
- using System.Runtime.InteropServices;
-
- namespace COFF
- {
- public class HEADER
- {
- public ushort Machine;
- public ushort NumberOfSections;
- public DateTime TimeDateStamp;
- public uint PointerToSymbolTable;
- public uint NumberOfSymbols;
- public ushort SizeOfOptionalHeader;
- public ushort Characteristics;
-
- public HEADER(BinaryReader br)
- {
- this.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 = br.ReadUInt16();
- }
- }
-
- public class IMAGE_ARCHIVE_MEMBER_HEADER
- {
- public string Name;
- public DateTime Date;
- public ulong Size;
- public string EndHeader;
-
- public IMAGE_ARCHIVE_MEMBER_HEADER(BinaryReader br)
- {
- string tempName = Encoding.UTF8.GetString(br.ReadBytes(16));
- DateTime dt = new DateTime(1970, 1, 1, 0, 0, 0);
- this.Name = tempName.Substring(0, tempName.IndexOf((Char) 47));
- this.Date = dt.AddSeconds(Convert.ToDouble(Encoding.UTF8.GetString(br.ReadBytes(12)).Split((Char) 20)[0]));
- br.ReadBytes(20); // Skip over UserID, GroupID, and Mode. They are useless fields.
- this.Size = Convert.ToUInt64(Encoding.UTF8.GetString(br.ReadBytes(10)).Split((Char) 20)[0]);
- this.EndHeader = Encoding.UTF8.GetString(br.ReadBytes(2));
- }
- }
-
- public class Functions
- {
- [DllImport("dbghelp.dll", SetLastError=true, PreserveSig=true)]
- public static extern int UnDecorateSymbolName(
- [In] [MarshalAs(UnmanagedType.LPStr)] string DecoratedName,
- [Out] StringBuilder UnDecoratedName,
- [In] [MarshalAs(UnmanagedType.U4)] uint UndecoratedLength,
- [In] [MarshalAs(UnmanagedType.U4)] uint Flags);
- }
- }
-'@
-
- Add-Type -TypeDefinition $Code
-
- function Dispose-Objects
- {
- $BinaryReader.Close()
- $FileStream.Dispose()
- }
- }
-
- PROCESS
- {
- foreach ($File in $Path)
- {
- # Resolve the absolute path of the lib file. [IO.File]::OpenRead requires an absolute path.
- $LibFilePath = Resolve-Path $File
-
- # Pull out just the file name
- $LibFileName = Split-Path $LibFilePath -Leaf
-
- $IMAGE_SIZEOF_ARCHIVE_MEMBER_HDR = 60
- $IMAGE_ARCHIVE_START = "!<arch>`n" # Magic used for lib files
- $IMAGE_SIZEOF_LIB_HDR = $IMAGE_SIZEOF_ARCHIVE_MEMBER_HDR + $IMAGE_ARCHIVE_START.Length
- $IMAGE_ARCHIVE_END = "```n" # Footer of an archive header
- $SizeofCOFFFileHeader = 20
-
- # Open the object file for reading
- $FileStream = [IO.File]::OpenRead($LibFilePath)
-
- $FileLength = $FileStream.Length
-
- # Validate lib header size
- if ($FileLength -lt $IMAGE_SIZEOF_LIB_HDR)
- {
- # You cannot parse the lib header if the file is not big enough to contain a lib header.
- Write-Error "$($LibFileName) is too small to store a lib header."
- $FileStream.Dispose()
- return
- }
-
- # Open a BinaryReader object for the lib file
- $BinaryReader = New-Object IO.BinaryReader($FileStream)
-
- $ArchiveStart = [Text.Encoding]::UTF8.GetString($BinaryReader.ReadBytes(8))
-
- if ($ArchiveStart -ne $IMAGE_ARCHIVE_START)
- {
- Write-Error "$($LibFileName) does not contain a valid lib header."
- Dispose-Objects
- return
- }
-
- # Parse the first archive header
- $ArchiveHeader = New-Object COFF.IMAGE_ARCHIVE_MEMBER_HEADER($BinaryReader)
-
- if ($ArchiveHeader.EndHeader -ne $IMAGE_ARCHIVE_END)
- {
- Write-Error "$($LibFileName) does not contain a valid lib header."
- Dispose-Objects
- return
- }
-
- # Check for the existence of symbols
- if ($ArchiveHeader.Size -eq 0)
- {
- Write-Warning "$($LibFileName) contains no symbols."
- Dispose-Objects
- return
- }
-
- $NumberOfSymbols = $BinaryReader.ReadBytes(4)
-
- # The offsets in the first archive header of a Microsoft lib file are stored in big-endian format
- if ([BitConverter]::IsLittleEndian)
- {
- [Array]::Reverse($NumberOfSymbols)
- }
-
- $NumberOfSymbols = [BitConverter]::ToUInt32($NumberOfSymbols, 0)
-
- $SymbolOffsets = New-Object UInt32[]($NumberOfSymbols)
-
- foreach ($Offset in 0..($SymbolOffsets.Length - 1))
- {
- $SymbolOffset = $BinaryReader.ReadBytes(4)
-
- if ([BitConverter]::IsLittleEndian)
- {
- [Array]::Reverse($SymbolOffset)
- }
-
- $SymbolOffsets[$Offset] = [BitConverter]::ToUInt32($SymbolOffset, 0)
- }
-
- $SymbolStringLength = $ArchiveHeader.Size + $IMAGE_SIZEOF_LIB_HDR - $FileStream.Position - 1
- # $SymbolStrings = [Text.Encoding]::UTF8.GetString($BinaryReader.ReadBytes($SymbolStringLength)).Split([Char] 0)
-
- # Write-Output $SymbolStrings
-
- # There will be many duplicate offset entries. Remove them.
- $SymbolOffsetsSorted = $SymbolOffsets | Sort-Object -Unique
-
- $SymbolOffsetsSorted | ForEach-Object {
- # Seek to the each repective offset in the file
- $FileStream.Seek($_, 'Begin') | Out-Null
-
- $ArchiveHeader = New-Object COFF.IMAGE_ARCHIVE_MEMBER_HEADER($BinaryReader)
-
- # This is not a true COFF header. It's the same size and mostly resembles a standard COFF header
- # but Microsoft placed a marker (0xFFFF) in the first WORD to indicate that the 'object file'
- # consists solely of the module name and symbol.
- $CoffHeader = New-Object COFF.HEADER($BinaryReader)
-
- # Check for 0xFFFF flag value
- if ($CoffHeader.NumberOfSections -eq [UInt16]::MaxValue)
- {
- # Get the total length of the module and symbol name
- $SymbolStringLength = $CoffHeader.NumberOfSymbols
- $Symbols = [Text.Encoding]::UTF8.GetString($BinaryReader.ReadBytes($SymbolStringLength)).Split([Char] 0)
-
- $DecoratedSymbol = $Symbols[0]
- $UndecoratedSymbol = ''
-
- # Default to a 'C' type symbol unless it starts with a '?'
- $SymbolType = 'C'
-
- # Is the symbol a C++ type?
- if ($DecoratedSymbol.StartsWith('?'))
- {
- $StrBuilder = New-Object Text.Stringbuilder(512)
- # Magically undecorated the convoluted C++ symbol into a proper C++ function definition
- [COFF.Functions]::UnDecorateSymbolName($DecoratedSymbol, $StrBuilder, $StrBuilder.Capacity, 0) | Out-Null
- $UndecoratedSymbol = $StrBuilder.ToString()
- $SymbolType = 'C++'
- }
- else
- {
- if ($DecoratedSymbol[0] -eq '_' -or $DecoratedSymbol[0] -eq '@')
- {
- $UndecoratedSymbol = $DecoratedSymbol.Substring(1).Split('@')[0]
- }
- else
- {
- $UndecoratedSymbol = $DecoratedSymbol.Split('@')[0]
- }
- }
-
- $SymInfo = @{
- DecoratedName = $DecoratedSymbol
- UndecoratedName = $UndecoratedSymbol
- Module = $Symbols[1]
- SymbolType = $SymbolType
- }
-
- $ParsedSymbol = New-Object PSObject -Property $SymInfo
- $ParsedSymbol.PSObject.TypeNames[0] = 'COFF.SymbolInfo'
-
- Write-Output $ParsedSymbol
- }
- }
-
- # Close file and binaryreader objects
- Dispose-Objects
- }
- }
-
- END {}
-}
diff --git a/PETools/Get-ObjDump.format.ps1xml b/PETools/Get-ObjDump.format.ps1xml
deleted file mode 100644
index 25e13b8..0000000
--- a/PETools/Get-ObjDump.format.ps1xml
+++ /dev/null
@@ -1,292 +0,0 @@
-<?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>
diff --git a/PETools/Get-ObjDump.ps1 b/PETools/Get-ObjDump.ps1
deleted file mode 100644
index 2a8ebcb..0000000
--- a/PETools/Get-ObjDump.ps1
+++ /dev/null
@@ -1,708 +0,0 @@
-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 {}
-}
diff --git a/PETools/Get-PEHeader.ps1 b/PETools/Get-PEHeader.ps1
deleted file mode 100644
index 0021377..0000000
--- a/PETools/Get-PEHeader.ps1
+++ /dev/null
@@ -1,960 +0,0 @@
-function Get-PEHeader
-{
-<#
-.SYNOPSIS
-
-Parses and outputs the PE header of a process in memory or a PE file on disk.
-
-PowerSploit Function: Get-PEHeader
-Author: Matthew Graeber (@mattifestation)
-License: BSD 3-Clause
-Required Dependencies: None
-Optional Dependencies: PETools.format.ps1xml
-
-.DESCRIPTION
-
-Get-PEHeader retrieves PE headers including imports and exports from either a file on disk or a module in memory. Get-PEHeader will operate on single PE header but you can also feed it the output of Get-ChildItem or Get-Process! Get-PEHeader works on both 32 and 64-bit modules.
-
-.PARAMETER FilePath
-
-Specifies the path to the portable executable file on disk
-
-.PARAMETER ProcessID
-
-Specifies the process ID.
-
-.PARAMETER Module
-
-The name of the module. This parameter is typically only used in pipeline expressions
-
-.PARAMETER ModuleBaseAddress
-
-The base address of the module
-
-.PARAMETER GetSectionData
-
-Retrieves raw section data.
-
-.OUTPUTS
-
-System.Object
-
-Returns a custom object consisting of the following: compile time, section headers, module name, DOS header, imports, exports, file header, optional header, and PE signature.
-
-.EXAMPLE
-
-C:\PS> Get-Process cmd | Get-PEHeader
-
-Description
------------
-Returns the full PE headers of every loaded module in memory
-
-.EXAMPLE
-
-C:\PS> Get-ChildItem C:\Windows\*.exe | Get-PEHeader
-
-Description
------------
-Returns the full PE headers of every exe in C:\Windows\
-
-.EXAMPLE
-
-C:\PS> Get-PEHeader C:\Windows\System32\kernel32.dll
-
-Module : C:\Windows\System32\kernel32.dll
-DOSHeader : PE+_IMAGE_DOS_HEADER
-FileHeader : PE+_IMAGE_FILE_HEADER
-OptionalHeader : PE+_IMAGE_OPTIONAL_HEADER32
-SectionHeaders : {.text, .data, .rsrc, .reloc}
-Imports : {@{Ordinal=; FunctionName=RtlUnwind; ModuleName=API-MS-Win-Core-RtlSupport-L1-1-0.
- dll; VA=0x000CB630}, @{Ordinal=; FunctionName=RtlCaptureContext; ModuleName=API-MS
- -Win-Core-RtlSupport-L1-1-0.dll; VA=0x000CB63C}, @{Ordinal=; FunctionName=RtlCaptu
- reStackBackTrace; ModuleName=API-MS-Win-Core-RtlSupport-L1-1-0.dll; VA=0x000CB650}
- , @{Ordinal=; FunctionName=NtCreateEvent; ModuleName=ntdll.dll; VA=0x000CB66C}...}
-Exports : {@{ForwardedName=; FunctionName=lstrlenW; Ordinal=0x0552; VA=0x0F022708}, @{Forwar
- dedName=; FunctionName=lstrlenA; Ordinal=0x0551; VA=0x0F026A23}, @{ForwardedName=;
- FunctionName=lstrlen; Ordinal=0x0550; VA=0x0F026A23}, @{ForwardedName=; FunctionN
- ame=lstrcpynW; Ordinal=0x054F; VA=0x0F04E54E}...}
-
-.EXAMPLE
-
-C:\PS> $Proc = Get-Process cmd
-C:\PS> $Kernel32Base = ($Proc.Modules | Where-Object {$_.ModuleName -eq 'kernel32.dll'}).BaseAddress
-C:\PS> Get-PEHeader -ProcessId $Proc.Id -ModuleBaseAddress $Kernel32Base
-
-Module :
-DOSHeader : PE+_IMAGE_DOS_HEADER
-FileHeader : PE+_IMAGE_FILE_HEADER
-OptionalHeader : PE+_IMAGE_OPTIONAL_HEADER32
-SectionHeaders : {.text, .data, .rsrc, .reloc}
-Imports : {@{Ordinal=; FunctionName=RtlUnwind; ModuleName=API-MS-Win-Core-RtlSupport-L1-1-0.
- dll; VA=0x77B8B6D9}, @{Ordinal=; FunctionName=RtlCaptureContext; ModuleName=API-MS
- -Win-Core-RtlSupport-L1-1-0.dll; VA=0x77B8B4CB}, @{Ordinal=; FunctionName=RtlCaptu
- reStackBackTrace; ModuleName=API-MS-Win-Core-RtlSupport-L1-1-0.dll; VA=0x77B95277}
- , @{Ordinal=; FunctionName=NtCreateEvent; ModuleName=ntdll.dll; VA=0x77B4FF54}...}
-Exports : {@{ForwardedName=; FunctionName=lstrlenW; Ordinal=0x0552; VA=0x08221720}, @{Forwar
- dedName=; FunctionName=lstrlenA; Ordinal=0x0551; VA=0x08225A3B}, @{ForwardedName=;
- FunctionName=lstrlen; Ordinal=0x0550; VA=0x08225A3B}, @{ForwardedName=; FunctionN
- ame=lstrcpynW; Ordinal=0x054F; VA=0x0824D566}...}
-
-Description
------------
-A PE header is returned upon providing the module's base address. This technique would be useful for dumping the PE header of a rogue module that is invisible to Windows - e.g. a reflectively loaded meterpreter binary (metsrv.dll).
-
-.NOTES
-
-Be careful if you decide to specify a module base address. Get-PEHeader does not check for the existence of an MZ header. An MZ header is not a prerequisite for reflectively loading a module in memory. If you provide an address that is not an actual PE header, you could crash the process.
-
-.LINK
-
-http://www.exploit-monday.com/2012/07/get-peheader.html
-#>
-
- [CmdletBinding(DefaultParameterSetName = 'OnDisk')] Param (
- [Parameter(Position = 0, Mandatory = $True, ParameterSetName = 'OnDisk', ValueFromPipelineByPropertyName = $True)] [Alias('FullName')] [String[]] $FilePath,
- [Parameter(Position = 0, Mandatory = $True, ParameterSetName = 'InMemory', ValueFromPipelineByPropertyName = $True)] [Alias('Id')] [Int] $ProcessID,
- [Parameter(Position = 2, ParameterSetName = 'InMemory', ValueFromPipelineByPropertyName = $True)] [Alias('MainModule')] [Alias('Modules')] [System.Diagnostics.ProcessModule[]] $Module,
- [Parameter(Position = 1, ParameterSetName = 'InMemory')] [IntPtr] $ModuleBaseAddress,
- [Parameter()] [Switch] $GetSectionData
- )
-
-PROCESS {
-
- switch ($PsCmdlet.ParameterSetName) {
- 'OnDisk' {
-
- if ($FilePath.Length -gt 1) {
- foreach ($Path in $FilePath) { Get-PEHeader $Path }
- }
-
- if (!(Test-Path $FilePath)) {
- Write-Warning 'Invalid path or file does not exist.'
- return
- }
-
- $FilePath = Resolve-Path $FilePath
-
- if ($FilePath.GetType() -eq [System.Array]) {
- $ModuleName = $FilePath[0]
- } else {
- $ModuleName = $FilePath
- }
-
- }
- 'InMemory' {
-
- if ($Module.Length -gt 1) {
- foreach ($Mod in $Module) {
- $BaseAddr = $Mod.BaseAddress
- Get-PEHeader -ProcessID $ProcessID -Module $Mod -ModuleBaseAddress $BaseAddr
- }
- }
-
- if (-not $ModuleBaseAddress) { return }
-
- if ($ProcessID -eq $PID) {
- Write-Warning 'You cannot parse the PE header of the current process. Open another instance of PowerShell.'
- return
- }
-
- if ($Module) {
- $ModuleName = $Module[0].FileName
- } else {
- $ModuleName = ''
- }
-
- }
- }
-
- try { [PE] | Out-Null } catch [Management.Automation.RuntimeException]
- {
- $code = @"
- using System;
- using System.Runtime.InteropServices;
-
- public class PE
- {
- [Flags]
- public enum IMAGE_DOS_SIGNATURE : ushort
- {
- DOS_SIGNATURE = 0x5A4D, // MZ
- OS2_SIGNATURE = 0x454E, // NE
- OS2_SIGNATURE_LE = 0x454C, // LE
- VXD_SIGNATURE = 0x454C, // LE
- }
-
- [Flags]
- public enum IMAGE_NT_SIGNATURE : uint
- {
- VALID_PE_SIGNATURE = 0x00004550 // PE00
- }
-
- [Flags]
- public enum IMAGE_FILE_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,
- ARMNT = 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
- CEE = 0xC0EE
- }
-
- [Flags]
- public enum IMAGE_FILE_CHARACTERISTICS : ushort
- {
- IMAGE_RELOCS_STRIPPED = 0x0001, // Relocation info stripped from file.
- IMAGE_EXECUTABLE_IMAGE = 0x0002, // File is executable (i.e. no unresolved external references).
- IMAGE_LINE_NUMS_STRIPPED = 0x0004, // Line nunbers stripped from file.
- IMAGE_LOCAL_SYMS_STRIPPED = 0x0008, // Local symbols stripped from file.
- IMAGE_AGGRESIVE_WS_TRIM = 0x0010, // Agressively trim working set
- IMAGE_LARGE_ADDRESS_AWARE = 0x0020, // App can handle >2gb addresses
- IMAGE_REVERSED_LO = 0x0080, // public bytes of machine public ushort are reversed.
- IMAGE_32BIT_MACHINE = 0x0100, // 32 bit public ushort machine.
- IMAGE_DEBUG_STRIPPED = 0x0200, // Debugging info stripped from file in .DBG file
- IMAGE_REMOVABLE_RUN_FROM_SWAP = 0x0400, // If Image is on removable media =copy and run from the swap file.
- IMAGE_NET_RUN_FROM_SWAP = 0x0800, // If Image is on Net =copy and run from the swap file.
- IMAGE_SYSTEM = 0x1000, // System File.
- IMAGE_DLL = 0x2000, // File is a DLL.
- IMAGE_UP_SYSTEM_ONLY = 0x4000, // File should only be run on a UP machine
- IMAGE_REVERSED_HI = 0x8000 // public bytes of machine public ushort are reversed.
- }
-
- [Flags]
- public enum IMAGE_NT_OPTIONAL_HDR_MAGIC : ushort
- {
- PE32 = 0x10b,
- PE64 = 0x20b
- }
-
- [Flags]
- public enum IMAGE_SUBSYSTEM : ushort
- {
- UNKNOWN = 0, // Unknown subsystem.
- NATIVE = 1, // Image doesn't require a subsystem.
- WINDOWS_GUI = 2, // Image runs in the Windows GUI subsystem.
- WINDOWS_CUI = 3, // Image runs in the Windows character subsystem.
- OS2_CUI = 5, // image runs in the OS/2 character subsystem.
- POSIX_CUI = 7, // image runs in the Posix character subsystem.
- NATIVE_WINDOWS = 8, // image is a native Win9x driver.
- WINDOWS_CE_GUI = 9, // Image runs in the Windows CE subsystem.
- EFI_APPLICATION = 10,
- EFI_BOOT_SERVICE_DRIVER = 11,
- EFI_RUNTIME_DRIVER = 12,
- EFI_ROM = 13,
- XBOX = 14,
- WINDOWS_BOOT_APPLICATION = 16
- }
-
- [Flags]
- public enum IMAGE_DLLCHARACTERISTICS : ushort
- {
- DYNAMIC_BASE = 0x0040, // DLL can move.
- FORCE_INTEGRITY = 0x0080, // Code Integrity Image
- NX_COMPAT = 0x0100, // Image is NX compatible
- NO_ISOLATION = 0x0200, // Image understands isolation and doesn't want it
- NO_SEH = 0x0400, // Image does not use SEH. No SE handler may reside in this image
- NO_BIND = 0x0800, // Do not bind this image.
- WDM_DRIVER = 0x2000, // Driver uses WDM model
- TERMINAL_SERVER_AWARE = 0x8000
- }
-
- [Flags]
- public enum IMAGE_SCN : 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.
- }
-
- [StructLayout(LayoutKind.Sequential, Pack=1)]
- public struct _IMAGE_DOS_HEADER
- {
- public IMAGE_DOS_SIGNATURE e_magic; // Magic number
- public ushort e_cblp; // public bytes on last page of file
- public ushort e_cp; // Pages in file
- public ushort e_crlc; // Relocations
- public ushort e_cparhdr; // Size of header in paragraphs
- public ushort e_minalloc; // Minimum extra paragraphs needed
- public ushort e_maxalloc; // Maximum extra paragraphs needed
- public ushort e_ss; // Initial (relative) SS value
- public ushort e_sp; // Initial SP value
- public ushort e_csum; // Checksum
- public ushort e_ip; // Initial IP value
- public ushort e_cs; // Initial (relative) CS value
- public ushort e_lfarlc; // File address of relocation table
- public ushort e_ovno; // Overlay number
- [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 8)]
- public string e_res; // This will contain 'Detours!' if patched in memory
- public ushort e_oemid; // OEM identifier (for e_oeminfo)
- public ushort e_oeminfo; // OEM information; e_oemid specific
- [MarshalAsAttribute(UnmanagedType.ByValArray, SizeConst=10)] // , ArraySubType=UnmanagedType.U4
- public ushort[] e_res2; // Reserved public ushorts
- public int e_lfanew; // File address of new exe header
- }
-
- [StructLayout(LayoutKind.Sequential, Pack=1)]
- public struct _IMAGE_FILE_HEADER
- {
- public IMAGE_FILE_MACHINE Machine;
- public ushort NumberOfSections;
- public uint TimeDateStamp;
- public uint PointerToSymbolTable;
- public uint NumberOfSymbols;
- public ushort SizeOfOptionalHeader;
- public IMAGE_FILE_CHARACTERISTICS Characteristics;
- }
-
- [StructLayout(LayoutKind.Sequential, Pack=1)]
- public struct _IMAGE_NT_HEADERS32
- {
- public IMAGE_NT_SIGNATURE Signature;
- public _IMAGE_FILE_HEADER FileHeader;
- public _IMAGE_OPTIONAL_HEADER32 OptionalHeader;
- }
-
- [StructLayout(LayoutKind.Sequential, Pack=1)]
- public struct _IMAGE_NT_HEADERS64
- {
- public IMAGE_NT_SIGNATURE Signature;
- public _IMAGE_FILE_HEADER FileHeader;
- public _IMAGE_OPTIONAL_HEADER64 OptionalHeader;
- }
-
- [StructLayout(LayoutKind.Sequential, Pack=1)]
- public struct _IMAGE_OPTIONAL_HEADER32
- {
- public IMAGE_NT_OPTIONAL_HDR_MAGIC Magic;
- public byte MajorLinkerVersion;
- public byte MinorLinkerVersion;
- public uint SizeOfCode;
- public uint SizeOfInitializedData;
- public uint SizeOfUninitializedData;
- public uint AddressOfEntryPoint;
- public uint BaseOfCode;
- public uint BaseOfData;
- public uint ImageBase;
- public uint SectionAlignment;
- public uint FileAlignment;
- public ushort MajorOperatingSystemVersion;
- public ushort MinorOperatingSystemVersion;
- public ushort MajorImageVersion;
- public ushort MinorImageVersion;
- public ushort MajorSubsystemVersion;
- public ushort MinorSubsystemVersion;
- public uint Win32VersionValue;
- public uint SizeOfImage;
- public uint SizeOfHeaders;
- public uint CheckSum;
- public IMAGE_SUBSYSTEM Subsystem;
- public IMAGE_DLLCHARACTERISTICS DllCharacteristics;
- public uint SizeOfStackReserve;
- public uint SizeOfStackCommit;
- public uint SizeOfHeapReserve;
- public uint SizeOfHeapCommit;
- public uint LoaderFlags;
- public uint NumberOfRvaAndSizes;
- [MarshalAsAttribute(UnmanagedType.ByValArray, SizeConst=16)]
- public _IMAGE_DATA_DIRECTORY[] DataDirectory;
- }
-
- [StructLayout(LayoutKind.Sequential, Pack=1)]
- public struct _IMAGE_OPTIONAL_HEADER64
- {
- public IMAGE_NT_OPTIONAL_HDR_MAGIC Magic;
- public byte MajorLinkerVersion;
- public byte MinorLinkerVersion;
- public uint SizeOfCode;
- public uint SizeOfInitializedData;
- public uint SizeOfUninitializedData;
- public uint AddressOfEntryPoint;
- public uint BaseOfCode;
- public ulong ImageBase;
- public uint SectionAlignment;
- public uint FileAlignment;
- public ushort MajorOperatingSystemVersion;
- public ushort MinorOperatingSystemVersion;
- public ushort MajorImageVersion;
- public ushort MinorImageVersion;
- public ushort MajorSubsystemVersion;
- public ushort MinorSubsystemVersion;
- public uint Win32VersionValue;
- public uint SizeOfImage;
- public uint SizeOfHeaders;
- public uint CheckSum;
- public IMAGE_SUBSYSTEM Subsystem;
- public IMAGE_DLLCHARACTERISTICS DllCharacteristics;
- public ulong SizeOfStackReserve;
- public ulong SizeOfStackCommit;
- public ulong SizeOfHeapReserve;
- public ulong SizeOfHeapCommit;
- public uint LoaderFlags;
- public uint NumberOfRvaAndSizes;
- [MarshalAsAttribute(UnmanagedType.ByValArray, SizeConst=16)]
- public _IMAGE_DATA_DIRECTORY[] DataDirectory;
- }
-
- [StructLayout(LayoutKind.Sequential, Pack=1)]
- public struct _IMAGE_DATA_DIRECTORY
- {
- public uint VirtualAddress;
- public uint Size;
- }
-
- [StructLayout(LayoutKind.Sequential, Pack=1)]
- public struct _IMAGE_EXPORT_DIRECTORY
- {
- public uint Characteristics;
- public uint TimeDateStamp;
- public ushort MajorVersion;
- public ushort MinorVersion;
- public uint Name;
- public uint Base;
- public uint NumberOfFunctions;
- public uint NumberOfNames;
- public uint AddressOfFunctions; // RVA from base of image
- public uint AddressOfNames; // RVA from base of image
- public uint AddressOfNameOrdinals; // RVA from base of image
- }
-
- [StructLayout(LayoutKind.Sequential, Pack=1)]
- public struct _IMAGE_SECTION_HEADER
- {
- [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 8)]
- public string Name;
- 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 IMAGE_SCN Characteristics;
- }
-
- [StructLayout(LayoutKind.Sequential, Pack=1)]
- public struct _IMAGE_IMPORT_DESCRIPTOR
- {
- public uint OriginalFirstThunk; // RVA to original unbound IAT (PIMAGE_THUNK_DATA)
- public uint TimeDateStamp; // 0 if not bound,
- // -1 if bound, and real date/time stamp
- // in IMAGE_DIRECTORY_ENTRY_BOUND_IMPORT (new BIND)
- // O.W. date/time stamp of DLL bound to (Old BIND)
- public uint ForwarderChain; // -1 if no forwarders
- public uint Name;
- public uint FirstThunk; // RVA to IAT (if bound this IAT has actual addresses)
- }
-
- [StructLayout(LayoutKind.Sequential, Pack=1)]
- public struct _IMAGE_THUNK_DATA32
- {
- public Int32 AddressOfData; // PIMAGE_IMPORT_BY_NAME
- }
-
- [StructLayout(LayoutKind.Sequential, Pack=1)]
- public struct _IMAGE_THUNK_DATA64
- {
- public Int64 AddressOfData; // PIMAGE_IMPORT_BY_NAME
- }
-
- [StructLayout(LayoutKind.Sequential, Pack=1)]
- public struct _IMAGE_IMPORT_BY_NAME
- {
- public ushort Hint;
- public char Name;
- }
- }
-"@
-
- $compileParams = New-Object System.CodeDom.Compiler.CompilerParameters
- $compileParams.ReferencedAssemblies.AddRange(@('System.dll', 'mscorlib.dll'))
- $compileParams.GenerateInMemory = $True
- Add-Type -TypeDefinition $code -CompilerParameters $compileParams -PassThru -WarningAction SilentlyContinue | Out-Null
- }
-
- function Get-DelegateType
- {
- Param (
- [Parameter(Position = 0, Mandatory = $True)] [Type[]] $Parameters,
- [Parameter(Position = 1)] [Type] $ReturnType = [Void]
- )
-
- $Domain = [AppDomain]::CurrentDomain
- $DynAssembly = New-Object System.Reflection.AssemblyName('ReflectedDelegate')
- $AssemblyBuilder = $Domain.DefineDynamicAssembly($DynAssembly, [System.Reflection.Emit.AssemblyBuilderAccess]::Run)
- $ModuleBuilder = $AssemblyBuilder.DefineDynamicModule('InMemoryModule', $false)
- $TypeBuilder = $ModuleBuilder.DefineType('MyDelegateType', 'Class, Public, Sealed, AnsiClass, AutoClass', [System.MulticastDelegate])
- $ConstructorBuilder = $TypeBuilder.DefineConstructor('RTSpecialName, HideBySig, Public', [System.Reflection.CallingConventions]::Standard, $Parameters)
- $ConstructorBuilder.SetImplementationFlags('Runtime, Managed')
- $MethodBuilder = $TypeBuilder.DefineMethod('Invoke', 'Public, HideBySig, NewSlot, Virtual', $ReturnType, $Parameters)
- $MethodBuilder.SetImplementationFlags('Runtime, Managed')
-
- return $TypeBuilder.CreateType()
- }
-
- function Get-ProcAddress
- {
- Param (
- [Parameter(Position = 0, Mandatory = $True)] [String] $Module,
- [Parameter(Position = 1, Mandatory = $True)] [String] $Procedure
- )
-
- # Get a reference to System.dll in the GAC
- $SystemAssembly = [AppDomain]::CurrentDomain.GetAssemblies() |
- Where-Object { $_.GlobalAssemblyCache -And $_.Location.Split('\\')[-1].Equals('System.dll') }
- $UnsafeNativeMethods = $SystemAssembly.GetType('Microsoft.Win32.UnsafeNativeMethods')
- # Get a reference to the GetModuleHandle and GetProcAddress methods
- $GetModuleHandle = $UnsafeNativeMethods.GetMethod('GetModuleHandle')
- $GetProcAddress = $UnsafeNativeMethods.GetMethod('GetProcAddress')
- # Get a handle to the module specified
- $Kern32Handle = $GetModuleHandle.Invoke($null, @($Module))
- $tmpPtr = New-Object IntPtr
- $HandleRef = New-Object System.Runtime.InteropServices.HandleRef($tmpPtr, $Kern32Handle)
- # Return the address of the function
-
- return $GetProcAddress.Invoke($null, @([System.Runtime.InteropServices.HandleRef]$HandleRef, $Procedure))
- }
-
- $OnDisk = $True
- if ($PsCmdlet.ParameterSetName -eq 'InMemory') { $OnDisk = $False }
-
-
- $OpenProcessAddr = Get-ProcAddress kernel32.dll OpenProcess
- $OpenProcessDelegate = Get-DelegateType @([UInt32], [Bool], [UInt32]) ([IntPtr])
- $OpenProcess = [System.Runtime.InteropServices.Marshal]::GetDelegateForFunctionPointer($OpenProcessAddr, [Type] $OpenProcessDelegate)
- $ReadProcessMemoryAddr = Get-ProcAddress kernel32.dll ReadProcessMemory
- $ReadProcessMemoryDelegate = Get-DelegateType @([IntPtr], [IntPtr], [IntPtr], [Int], [Int].MakeByRefType()) ([Bool])
- $ReadProcessMemory = [System.Runtime.InteropServices.Marshal]::GetDelegateForFunctionPointer($ReadProcessMemoryAddr, [Type] $ReadProcessMemoryDelegate)
- $CloseHandleAddr = Get-ProcAddress kernel32.dll CloseHandle
- $CloseHandleDelegate = Get-DelegateType @([IntPtr]) ([Bool])
- $CloseHandle = [System.Runtime.InteropServices.Marshal]::GetDelegateForFunctionPointer($CloseHandleAddr, [Type] $CloseHandleDelegate)
-
- if ($OnDisk) {
-
- $FileStream = New-Object System.IO.FileStream($FilePath, [System.IO.FileMode]::Open, [System.IO.FileAccess]::Read)
- $FileByteArray = New-Object Byte[]($FileStream.Length)
- $FileStream.Read($FileByteArray, 0, $FileStream.Length) | Out-Null
- $FileStream.Close()
- $Handle = [System.Runtime.InteropServices.GCHandle]::Alloc($FileByteArray, 'Pinned')
- $PEBaseAddr = $Handle.AddrOfPinnedObject()
-
- } else {
-
- # Size of the memory page allocated for the PE header
- $HeaderSize = 0x1000
- # Allocate space for when the PE header is read from the remote process
- $PEBaseAddr = [System.Runtime.InteropServices.Marshal]::AllocHGlobal($HeaderSize + 1)
- # Get handle to the process
- $hProcess = $OpenProcess.Invoke(0x10, $false, $ProcessID) # PROCESS_VM_READ (0x00000010)
-
- # Read PE header from remote process
- if (!$ReadProcessMemory.Invoke($hProcess, $ModuleBaseAddress, $PEBaseAddr, $HeaderSize, [Ref] 0)) {
- if ($ModuleName) {
- Write-Warning "Failed to read PE header of $ModuleName"
- } else {
- Write-Warning "Failed to read PE header of process ID: $ProcessID"
- }
-
- Write-Warning "Error code: 0x$([System.Runtime.InteropServices.Marshal]::GetLastWin32Error().ToString('X8'))"
- $CloseHandle.Invoke($hProcess) | Out-Null
- return
- }
-
- }
-
- $DosHeader = [System.Runtime.InteropServices.Marshal]::PtrToStructure($PEBaseAddr, [Type] [PE+_IMAGE_DOS_HEADER])
- $PointerNtHeader = [IntPtr] ($PEBaseAddr.ToInt64() + $DosHeader.e_lfanew)
- $NtHeader = [System.Runtime.InteropServices.Marshal]::PtrToStructure($PointerNtHeader, [Type] [PE+_IMAGE_NT_HEADERS32])
- $Architecture = ($NtHeader.FileHeader.Machine).ToString()
-
- $BinaryPtrWidth = 4
-
- # Define relevant structure types depending upon whether the binary is 32 or 64-bit
- if ($Architecture -eq 'AMD64') {
-
- $BinaryPtrWidth = 8
-
- $PEStruct = @{
- IMAGE_OPTIONAL_HEADER = [PE+_IMAGE_OPTIONAL_HEADER64]
- NT_HEADER = [PE+_IMAGE_NT_HEADERS64]
- }
-
- $ThunkDataStruct = [PE+_IMAGE_THUNK_DATA64]
-
- Write-Verbose "Architecture: $Architecture"
- Write-Verbose 'Proceeding with parsing a 64-bit binary.'
-
- } elseif ($Architecture -eq 'I386' -or $Architecture -eq 'ARMNT' -or $Architecture -eq 'THUMB') {
-
- $PEStruct = @{
- IMAGE_OPTIONAL_HEADER = [PE+_IMAGE_OPTIONAL_HEADER32]
- NT_HEADER = [PE+_IMAGE_NT_HEADERS32]
- }
-
- $ThunkDataStruct = [PE+_IMAGE_THUNK_DATA32]
-
- Write-Verbose "Architecture: $Architecture"
- Write-Verbose 'Proceeding with parsing a 32-bit binary.'
-
- } else {
-
- Write-Warning 'Get-PEHeader only supports binaries compiled for x86, AMD64, and ARM.'
- return
-
- }
-
- # Need to get a new NT header in case the architecture changed
- $NtHeader = [System.Runtime.InteropServices.Marshal]::PtrToStructure($PointerNtHeader, [Type] $PEStruct['NT_HEADER'])
- # Display all section headers
- $NumSections = $NtHeader.FileHeader.NumberOfSections
- $NumRva = $NtHeader.OptionalHeader.NumberOfRvaAndSizes
- $PointerSectionHeader = [IntPtr] ($PointerNtHeader.ToInt64() + [System.Runtime.InteropServices.Marshal]::SizeOf([Type] $PEStruct['NT_HEADER']))
- $SectionHeaders = New-Object PSObject[]($NumSections)
- foreach ($i in 0..($NumSections - 1))
- {
- $SectionHeaders[$i] = [System.Runtime.InteropServices.Marshal]::PtrToStructure(([IntPtr] ($PointerSectionHeader.ToInt64() + ($i * [System.Runtime.InteropServices.Marshal]::SizeOf([Type] [PE+_IMAGE_SECTION_HEADER])))), [Type] [PE+_IMAGE_SECTION_HEADER])
- }
-
-
- if (!$OnDisk) {
-
- $ReadSize = $NtHeader.OptionalHeader.SizeOfImage
- # Free memory allocated for the PE header
- [System.Runtime.InteropServices.Marshal]::FreeHGlobal($PEBaseAddr)
- $PEBaseAddr = [System.Runtime.InteropServices.Marshal]::AllocHGlobal($ReadSize + 1)
-
- # Read process memory of each section header
- foreach ($SectionHeader in $SectionHeaders) {
- if (!$ReadProcessMemory.Invoke($hProcess, [IntPtr] ($ModuleBaseAddress.ToInt64() + $SectionHeader.VirtualAddress), [IntPtr] ($PEBaseAddr.ToInt64() + $SectionHeader.VirtualAddress), $SectionHeader.VirtualSize, [Ref] 0)) {
- if ($ModuleName) {
- Write-Warning "Failed to read $($SectionHeader.Name) section of $ModuleName"
- } else {
- Write-Warning "Failed to read $($SectionHeader.Name) section of process ID: $ProcessID"
- }
-
- Write-Warning "Error code: 0x$([System.Runtime.InteropServices.Marshal]::GetLastWin32Error().ToString('X8'))"
- $CloseHandle.Invoke($hProcess) | Out-Null
- return
- }
- }
-
- # Close handle to the remote process since we no longer need to access the process.
- $CloseHandle.Invoke($hProcess) | Out-Null
-
- }
-
- if ($PSBoundParameters['GetSectionData'])
- {
- foreach ($i in 0..($NumSections - 1))
- {
- $RawBytes = $null
-
- if ($OnDisk)
- {
- $RawBytes = New-Object Byte[]($SectionHeaders[$i].SizeOfRawData)
- [Runtime.InteropServices.Marshal]::Copy([IntPtr] ($PEBaseAddr.ToInt64() + $SectionHeaders[$i].PointerToRawData), $RawBytes, 0, $SectionHeaders[$i].SizeOfRawData)
- }
- else
- {
- $RawBytes = New-Object Byte[]($SectionHeaders[$i].VirtualSize)
- [Runtime.InteropServices.Marshal]::Copy([IntPtr] ($PEBaseAddr.ToInt64() + $SectionHeaders[$i].VirtualAddress), $RawBytes, 0, $SectionHeaders[$i].VirtualSize)
- }
-
- $SectionHeaders[$i] = Add-Member -InputObject ($SectionHeaders[$i]) -MemberType NoteProperty -Name RawData -Value $RawBytes -PassThru -Force
- }
- }
-
- function Get-Exports()
- {
-
- if ($NTHeader.OptionalHeader.DataDirectory[0].VirtualAddress -eq 0) {
- Write-Verbose 'Module does not contain any exports'
- return
- }
-
- # List all function Rvas in the export table
- $ExportPointer = [IntPtr] ($PEBaseAddr.ToInt64() + $NtHeader.OptionalHeader.DataDirectory[0].VirtualAddress)
- # This range will be used to test for the existence of forwarded functions
- $ExportDirLow = $NtHeader.OptionalHeader.DataDirectory[0].VirtualAddress
- if ($OnDisk) {
- $ExportPointer = Convert-RVAToFileOffset $ExportPointer
- $ExportDirLow = Convert-RVAToFileOffset $ExportDirLow
- $ExportDirHigh = $ExportDirLow.ToInt32() + $NtHeader.OptionalHeader.DataDirectory[0].Size
- } else { $ExportDirHigh = $ExportDirLow + $NtHeader.OptionalHeader.DataDirectory[0].Size }
-
- $ExportDirectory = [System.Runtime.InteropServices.Marshal]::PtrToStructure($ExportPointer, [Type] [PE+_IMAGE_EXPORT_DIRECTORY])
- $AddressOfNamePtr = [IntPtr] ($PEBaseAddr.ToInt64() + $ExportDirectory.AddressOfNames)
- $NameOrdinalAddrPtr = [IntPtr] ($PEBaseAddr.ToInt64() + $ExportDirectory.AddressOfNameOrdinals)
- $AddressOfFunctionsPtr = [IntPtr] ($PEBaseAddr.ToInt64() + $ExportDirectory.AddressOfFunctions)
- $NumNamesFuncs = $ExportDirectory.NumberOfFunctions - $ExportDirectory.NumberOfNames
- $NumNames = $ExportDirectory.NumberOfNames
- $NumFunctions = $ExportDirectory.NumberOfFunctions
- $Base = $ExportDirectory.Base
-
- # Recalculate file offsets based upon relative virtual addresses
- if ($OnDisk) {
- $AddressOfNamePtr = Convert-RVAToFileOffset $AddressOfNamePtr
- $NameOrdinalAddrPtr = Convert-RVAToFileOffset $NameOrdinalAddrPtr
- $AddressOfFunctionsPtr = Convert-RVAToFileOffset $AddressOfFunctionsPtr
- }
-
- if ($NumFunctions -gt 0) {
-
- # Create an empty hash table that will contain indices to exported functions and their RVAs
- $FunctionHashTable = @{}
-
- foreach ($i in 0..($NumFunctions - 1))
- {
-
- $RvaFunction = [System.Runtime.InteropServices.Marshal]::ReadInt32($AddressOfFunctionsPtr.ToInt64() + ($i * 4))
- # Function is exported by ordinal if $RvaFunction -ne 0. I.E. NumberOfFunction != the number of actual, exported functions.
- if ($RvaFunction) { $FunctionHashTable[[Int]$i] = $RvaFunction }
-
- }
-
- # Create an empty hash table that will contain indices into RVA array and the function's name
- $NameHashTable = @{}
-
- foreach ($i in 0..($NumNames - 1))
- {
-
- $RvaName = [System.Runtime.InteropServices.Marshal]::ReadInt32($AddressOfNamePtr.ToInt64() + ($i * 4))
- $FuncNameAddr = [IntPtr] ($PEBaseAddr.ToInt64() + $RvaName)
- if ($OnDisk) { $FuncNameAddr= Convert-RVAToFileOffset $FuncNameAddr }
- $FuncName = [System.Runtime.InteropServices.Marshal]::PtrToStringAnsi($FuncNameAddr)
- $NameOrdinal = [Int][System.Runtime.InteropServices.Marshal]::ReadInt16($NameOrdinalAddrPtr.ToInt64() + ($i * 2))
- $NameHashTable[$NameOrdinal] = $FuncName
-
- }
-
- foreach ($Key in $FunctionHashTable.Keys)
- {
- $Result = @{}
-
- if ($NameHashTable[$Key]) {
- $Result['FunctionName'] = $NameHashTable[$Key]
- } else {
- $Result['FunctionName'] = ''
- }
-
- if (($FunctionHashTable[$Key] -ge $ExportDirLow) -and ($FunctionHashTable[$Key] -lt $ExportDirHigh)) {
- $ForwardedNameAddr = [IntPtr] ($PEBaseAddr.ToInt64() + $FunctionHashTable[$Key])
- if ($OnDisk) { $ForwardedNameAddr = Convert-RVAToFileOffset $ForwardedNameAddr }
- $ForwardedName = [System.Runtime.InteropServices.Marshal]::PtrToStringAnsi($ForwardedNameAddr)
- # This script does not attempt to resolve the virtual addresses of forwarded functions
- $Result['ForwardedName'] = $ForwardedName
- } else {
- $Result['ForwardedName'] = ''
- }
-
- $Result['Ordinal'] = "0x$(($Key + $Base).ToString('X4'))"
- $Result['RVA'] = "0x$($FunctionHashTable[$Key].ToString("X$($BinaryPtrWidth*2)"))"
- #$Result['VA'] = "0x$(($FunctionHashTable[$Key] + $PEBaseAddr.ToInt64()).ToString("X$($BinaryPtrWidth*2)"))"
-
- $Export = New-Object PSObject -Property $Result
- $Export.PSObject.TypeNames.Insert(0, 'Export')
-
- $Export
-
- }
-
- } else { Write-Verbose 'Module does not export any functions.' }
-
- }
-
- function Get-Imports()
- {
- if ($NTHeader.OptionalHeader.DataDirectory[1].VirtualAddress -eq 0) {
- Write-Verbose 'Module does not contain any imports'
- return
- }
-
- $FirstImageImportDescriptorPtr = [IntPtr] ($PEBaseAddr.ToInt64() + $NtHeader.OptionalHeader.DataDirectory[1].VirtualAddress)
- if ($OnDisk) { $FirstImageImportDescriptorPtr = Convert-RVAToFileOffset $FirstImageImportDescriptorPtr }
- $ImportDescriptorPtr = $FirstImageImportDescriptorPtr
-
- $i = 0
- # Get all imported modules
- while ($true)
- {
- $ImportDescriptorPtr = [IntPtr] ($FirstImageImportDescriptorPtr.ToInt64() + ($i * [System.Runtime.InteropServices.Marshal]::SizeOf([Type] [PE+_IMAGE_IMPORT_DESCRIPTOR])))
- $ImportDescriptor = [System.Runtime.InteropServices.Marshal]::PtrToStructure($ImportDescriptorPtr, [Type] [PE+_IMAGE_IMPORT_DESCRIPTOR])
- if ($ImportDescriptor.OriginalFirstThunk -eq 0) { break }
- $DllNamePtr = [IntPtr] ($PEBaseAddr.ToInt64() + $ImportDescriptor.Name)
- if ($OnDisk) { $DllNamePtr = Convert-RVAToFileOffset $DllNamePtr }
- $DllName = [System.Runtime.InteropServices.Marshal]::PtrToStringAnsi($DllNamePtr)
- $FirstFuncAddrPtr = [IntPtr] ($PEBaseAddr.ToInt64() + $ImportDescriptor.FirstThunk)
- if ($OnDisk) { $FirstFuncAddrPtr = Convert-RVAToFileOffset $FirstFuncAddrPtr }
- $FuncAddrPtr = $FirstFuncAddrPtr
- $FirstOFTPtr = [IntPtr] ($PEBaseAddr.ToInt64() + $ImportDescriptor.OriginalFirstThunk)
- if ($OnDisk) { $FirstOFTPtr = Convert-RVAToFileOffset $FirstOFTPtr }
- $OFTPtr = $FirstOFTPtr
- $j = 0
- while ($true)
- {
- $FuncAddrPtr = [IntPtr] ($FirstFuncAddrPtr.ToInt64() + ($j * [System.Runtime.InteropServices.Marshal]::SizeOf([Type] $ThunkDataStruct)))
- $FuncAddr = [System.Runtime.InteropServices.Marshal]::PtrToStructure($FuncAddrPtr, [Type] $ThunkDataStruct)
- $OFTPtr = [IntPtr] ($FirstOFTPtr.ToInt64() + ($j * [System.Runtime.InteropServices.Marshal]::SizeOf([Type] $ThunkDataStruct)))
- $ThunkData = [System.Runtime.InteropServices.Marshal]::PtrToStructure($OFTPtr, [Type] $ThunkDataStruct)
- $Result = @{ ModuleName = $DllName }
-
- if (([System.Convert]::ToString($ThunkData.AddressOfData, 2)).PadLeft(32, '0')[0] -eq '1')
- {
- # Trim high order bit in order to get the ordinal value
- $TempOrdinal = [System.Convert]::ToInt64(([System.Convert]::ToString($ThunkData.AddressOfData, 2))[1..63] -join '', 2)
- $TempOrdinal = $TempOrdinal.ToString('X16')[-1..-4]
- [Array]::Reverse($TempOrdinal)
- $Ordinal = ''
- $TempOrdinal | ForEach-Object { $Ordinal += $_ }
- $Result['Ordinal'] = "0x$Ordinal"
- $Result['FunctionName'] = ''
- }
- else
- {
- $ImportByNamePtr = [IntPtr] ($PEBaseAddr.ToInt64() + [Int64]$ThunkData.AddressOfData + 2)
- if ($OnDisk) { $ImportByNamePtr = Convert-RVAToFileOffset $ImportByNamePtr }
- $FuncName = [System.Runtime.InteropServices.Marshal]::PtrToStringAnsi($ImportByNamePtr)
- $Result['Ordinal'] = ''
- $Result['FunctionName'] = $FuncName
- }
-
- $Result['RVA'] = "0x$($FuncAddr.AddressOfData.ToString("X$($BinaryPtrWidth*2)"))"
-
- if ($FuncAddr.AddressOfData -eq 0) { break }
- if ($OFTPtr -eq 0) { break }
-
- $Import = New-Object PSObject -Property $Result
- $Import.PSObject.TypeNames.Insert(0, 'Import')
-
- $Import
-
- $j++
-
- }
-
- $i++
-
- }
-
- }
-
- function Convert-RVAToFileOffset([IntPtr] $Rva)
- {
-
- foreach ($Section in $SectionHeaders) {
- if ((($Rva.ToInt64() - $PEBaseAddr.ToInt64()) -ge $Section.VirtualAddress) -and (($Rva.ToInt64() - $PEBaseAddr.ToInt64()) -lt ($Section.VirtualAddress + $Section.VirtualSize))) {
- return [IntPtr] ($Rva.ToInt64() - ($Section.VirtualAddress - $Section.PointerToRawData))
- }
- }
-
- # Pointer did not fall in the address ranges of the section headers
- return $Rva
-
- }
-
- $PEFields = @{
- Module = $ModuleName
- DOSHeader = $DosHeader
- PESignature = $NTHeader.Signature
- FileHeader = $NTHeader.FileHeader
- OptionalHeader = $NTHeader.OptionalHeader
- SectionHeaders = $SectionHeaders
- Imports = Get-Imports
- Exports = Get-Exports
- }
-
- if ($Ondisk) {
- $Handle.Free()
- } else {
- # Free memory allocated for the PE header
- [System.Runtime.InteropServices.Marshal]::FreeHGlobal($PEBaseAddr)
- }
-
- $PEHeader = New-Object PSObject -Property $PEFields
- $PEHeader.PSObject.TypeNames.Insert(0, 'PEHeader')
-
- $ScriptBlock = {
- $SymServerURL = 'http://msdl.microsoft.com/download/symbols'
- $FileName = $this.Module.Split('\')[-1]
- $Request = "{0}/{1}/{2:X8}{3:X}/{1}" -f $SymServerURL, $FileName, $this.FileHeader.TimeDateStamp, $this.OptionalHeader.SizeOfImage
- $Request = "$($Request.Substring(0, $Request.Length - 1))_"
- $WebClient = New-Object Net.WebClient
- $WebClient.Headers.Add('User-Agent', 'Microsoft-Symbol-Server/6.6.0007.5')
- Write-Host "Downloading $FileName from the Microsoft symbol server..."
- $CabBytes = $WebClient.DownloadData($Request)
- $CabPath = "$PWD\$($FileName.Split('.')[0]).cab"
- Write-Host "Download complete. Saving it to $("$(Split-Path $CabPath)\$FileName")."
- [IO.File]::WriteAllBytes($CabPath, $CabBytes)
- $Shell = New-Object -Comobject Shell.Application
- $CabFile = $Shell.Namespace($CabPath).Items()
- $Destination = $Shell.Namespace((Split-Path $CabPath))
- $Destination.CopyHere($CabFile)
- Remove-Item $CabPath -Force
- }
-
- $PEHeader = Add-Member -InputObject $PEHeader -MemberType ScriptMethod -Name DownloadFromMSSymbolServer -Value $ScriptBlock -PassThru -Force
-
- return $PEHeader
-
-}
-
-}
diff --git a/PETools/PETools.format.ps1xml b/PETools/PETools.format.ps1xml
deleted file mode 100644
index c510281..0000000
--- a/PETools/PETools.format.ps1xml
+++ /dev/null
@@ -1,374 +0,0 @@
-<?xml version="1.0" encoding="utf-8" ?>
-<Configuration>
- <SelectionSets>
- <SelectionSet>
- <Name>OptionHeaderTypes</Name>
- <Types>
- <TypeName>PE+_IMAGE_OPTIONAL_HEADER32</TypeName>
- <TypeName>PE+_IMAGE_OPTIONAL_HEADER64</TypeName>
- </Types>
- </SelectionSet>
- </SelectionSets>
- <ViewDefinitions>
- <View>
- <Name>PEView</Name>
- <ViewSelectedBy>
- <TypeName>PEHeader</TypeName>
- </ViewSelectedBy>
- <ListControl>
- <ListEntries>
- <ListEntry>
- <ListItems>
- <ListItem>
- <PropertyName>Module</PropertyName>
- </ListItem>
- <ListItem>
- <PropertyName>DOSHeader</PropertyName>
- </ListItem>
- <ListItem>
- <PropertyName>FileHeader</PropertyName>
- </ListItem>
- <ListItem>
- <PropertyName>OptionalHeader</PropertyName>
- </ListItem>
- <ListItem>
- <PropertyName>SectionHeaders</PropertyName>
- </ListItem>
- <ListItem>
- <PropertyName>Imports</PropertyName>
- </ListItem>
- <ListItem>
- <PropertyName>Exports</PropertyName>
- </ListItem>
- </ListItems>
- </ListEntry>
- </ListEntries>
- </ListControl>
- </View>
- <View>
- <Name>OptionalHeaderView</Name>
- <ViewSelectedBy>
- <SelectionSetName>OptionHeaderTypes</SelectionSetName>
- </ViewSelectedBy>
- <ListControl>
- <ListEntries>
- <ListEntry>
- <ListItems>
- <ListItem>
- <PropertyName>Magic</PropertyName>
- </ListItem>
- <ListItem>
- <PropertyName>MajorLinkerVersion</PropertyName>
- </ListItem>
- <ListItem>
- <PropertyName>MinorLinkerVersion</PropertyName>
- </ListItem>
- <ListItem>
- <Label>SizeOfCode</Label>
- <ScriptBlock>"0x$($_.SizeOfCode.ToString('X8'))"</ScriptBlock>
- </ListItem>
- <ListItem>
- <Label>SizeOfInitializedData</Label>
- <ScriptBlock>"0x$($_.SizeOfInitializedData.ToString('X8'))"</ScriptBlock>
- </ListItem>
- <ListItem>
- <Label>SizeOfUninitializedData</Label>
- <ScriptBlock>"0x$($_.SizeOfUninitializedData.ToString('X8'))"</ScriptBlock>
- </ListItem>
- <ListItem>
- <Label>AddressOfEntryPoint</Label>
- <ScriptBlock>"0x$($_.AddressOfEntryPoint.ToString('X8'))"</ScriptBlock>
- </ListItem>
- <ListItem>
- <Label>BaseOfCode</Label>
- <ScriptBlock>"0x$($_.BaseOfCode.ToString('X8'))"</ScriptBlock>
- </ListItem>
- <ListItem>
- <Label>BaseOfData</Label>
- <ScriptBlock>"0x$($_.BaseOfData.ToString('X8'))"</ScriptBlock>
- </ListItem>
- <ListItem>
- <Label>ImageBase</Label>
- <ScriptBlock>if ($_.Magic.ToString() -eq 'PE32') { "0x$($_.ImageBase.ToString('X8'))" } else { "0x$($_.ImageBase.ToString('X16'))" }</ScriptBlock>
- </ListItem>
- <ListItem>
- <Label>SectionAlignment</Label>
- <ScriptBlock>"0x$($_.SectionAlignment.ToString('X8'))"</ScriptBlock>
- </ListItem>
- <ListItem>
- <Label>FileAlignment</Label>
- <ScriptBlock>"0x$($_.FileAlignment.ToString('X8'))"</ScriptBlock>
- </ListItem>
- <ListItem>
- <PropertyName>MajorOperatingSystemVersion</PropertyName>
- </ListItem>
- <ListItem>
- <PropertyName>MinorOperatingSystemVersion</PropertyName>
- </ListItem>
- <ListItem>
- <PropertyName>MajorSubsystemVersion</PropertyName>
- </ListItem>
- <ListItem>
- <PropertyName>MinorSubsystemVersion</PropertyName>
- </ListItem>
- <ListItem>
- <PropertyName>Win32VersionValue</PropertyName>
- </ListItem>
- <ListItem>
- <Label>SizeOfImage</Label>
- <ScriptBlock>"0x$($_.SizeOfImage.ToString('X8'))"</ScriptBlock>
- </ListItem>
- <ListItem>
- <Label>SizeOfHeaders</Label>
- <ScriptBlock>"0x$($_.SizeOfHeaders.ToString('X8'))"</ScriptBlock>
- </ListItem>
- <ListItem>
- <Label>CheckSum</Label>
- <ScriptBlock>"0x$($_.CheckSum.ToString('X8'))"</ScriptBlock>
- </ListItem>
- <ListItem>
- <PropertyName>Subsystem</PropertyName>
- </ListItem>
- <ListItem>
- <PropertyName>DllCharacteristics</PropertyName>
- </ListItem>
- <ListItem>
- <Label>SizeOfStackReserve</Label>
- <ScriptBlock>if ($_.Magic.ToString() -eq 'PE32') { "0x$($_.SizeOfStackReserve.ToString('X8'))" } else { "0x$($_.SizeOfStackReserve.ToString('X16'))" }</ScriptBlock>
- </ListItem>
- <ListItem>
- <Label>SizeOfStackCommit</Label>
- <ScriptBlock>if ($_.Magic.ToString() -eq 'PE32') { "0x$($_.SizeOfStackCommit.ToString('X8'))" } else { "0x$($_.SizeOfStackCommit.ToString('X16'))" }</ScriptBlock>
- </ListItem>
- <ListItem>
- <Label>SizeOfHeapReserve</Label>
- <ScriptBlock>if ($_.Magic.ToString() -eq 'PE32') { "0x$($_.SizeOfHeapReserve.ToString('X8'))" } else { "0x$($_.SizeOfHeapReserve.ToString('X16'))" }</ScriptBlock>
- </ListItem>
- <ListItem>
- <Label>SizeOfHeapCommit</Label>
- <ScriptBlock>if ($_.Magic.ToString() -eq 'PE32') { "0x$($_.SizeOfHeapCommit.ToString('X8'))" } else { "0x$($_.SizeOfHeapCommit.ToString('X16'))" }</ScriptBlock>
- </ListItem>
- <ListItem>
- <PropertyName>LoaderFlags</PropertyName>
- </ListItem>
- <ListItem>
- <PropertyName>NumberOfRvaAndSizes</PropertyName>
- </ListItem>
- <ListItem>
- <PropertyName>DataDirectory</PropertyName>
- </ListItem>
- </ListItems>
- </ListEntry>
- </ListEntries>
- </ListControl>
- </View>
- <View>
- <Name>SectionHeaderView</Name>
- <ViewSelectedBy>
- <TypeName>PE+_IMAGE_SECTION_HEADER</TypeName>
- </ViewSelectedBy>
- <TableControl>
- <AutoSize/>
- <TableHeaders>
- <TableColumnHeader>
- <Label>Name</Label>
- <Alignment>Right</Alignment>
- </TableColumnHeader>
- <TableColumnHeader>
- <Label>VirtualSize</Label>
- </TableColumnHeader>
- <TableColumnHeader>
- <Label>VirtualAddress</Label>
- </TableColumnHeader>
- <TableColumnHeader>
- <Label>SizeOfRawData</Label>
- </TableColumnHeader>
- <TableColumnHeader>
- <Label>PointerToRawData</Label>
- </TableColumnHeader>
- <TableColumnHeader>
- <Label>Characteristics</Label>
- <Alignment>Left</Alignment>
- </TableColumnHeader>
- </TableHeaders>
- <TableRowEntries>
- <TableRowEntry>
- <TableColumnItems>
- <TableColumnItem>
- <Alignment>Right</Alignment>
- <PropertyName>Name</PropertyName>
- </TableColumnItem>
- <TableColumnItem>
- <ScriptBlock>"0x$($_.VirtualSize.ToString('X8'))"</ScriptBlock>
- </TableColumnItem>
- <TableColumnItem>
- <ScriptBlock>"0x$($_.VirtualAddress.ToString('X8'))"</ScriptBlock>
- </TableColumnItem>
- <TableColumnItem>
- <ScriptBlock>"0x$($_.SizeOfRawData.ToString('X8'))"</ScriptBlock>
- </TableColumnItem>
- <TableColumnItem>
- <ScriptBlock>"0x$($_.PointerToRawData.ToString('X8'))"</ScriptBlock>
- </TableColumnItem>
- <TableColumnItem>
- <PropertyName>Characteristics</PropertyName>
- </TableColumnItem>
- </TableColumnItems>
- </TableRowEntry>
- </TableRowEntries>
- </TableControl>
- </View>
- <View>
- <Name>FileHeaderView</Name>
- <ViewSelectedBy>
- <TypeName>PE+_IMAGE_FILE_HEADER</TypeName>
- </ViewSelectedBy>
- <ListControl>
- <ListEntries>
- <ListEntry>
- <ListItems>
- <ListItem>
- <PropertyName>Machine</PropertyName>
- </ListItem>
- <ListItem>
- <PropertyName>NumberOfSections</PropertyName>
- </ListItem>
- <ListItem>
- <Label>TimeDateStamp</Label>
- <!-- GMT compile time -->
- <ScriptBlock>(New-Object DateTime(1970, 1, 1, 0, 0, 0)).AddSeconds($_.TimeDateStamp)</ScriptBlock>
- <!-- Compile time assuming it was compiled in Redmond, Washington (PST - GMT-8) -->
- <!-- <ScriptBlock>(New-Object DateTime(1969, 12, 31, 16, 0, 0)).AddSeconds($_.TimeDateStamp)</ScriptBlock> -->
- </ListItem>
- <ListItem>
- <PropertyName>PointerToSymbolTable</PropertyName>
- </ListItem>
- <ListItem>
- <PropertyName>NumberOfSymbols</PropertyName>
- </ListItem>
- <ListItem>
- <PropertyName>SizeOfOptionalHeader</PropertyName>
- </ListItem>
- <ListItem>
- <PropertyName>Characteristics</PropertyName>
- </ListItem>
- </ListItems>
- </ListEntry>
- </ListEntries>
- </ListControl>
- </View>
- <View>
- <Name>DataDirectoryView</Name>
- <ViewSelectedBy>
- <TypeName>PE+_IMAGE_DATA_DIRECTORY</TypeName>
- </ViewSelectedBy>
- <TableControl>
- <AutoSize/>
- <TableHeaders>
- <TableColumnHeader>
- <Label>VirtualAddress</Label>
- </TableColumnHeader>
- <TableColumnHeader>
- <Label>Size</Label>
- </TableColumnHeader>
- </TableHeaders>
- <TableRowEntries>
- <TableRowEntry>
- <TableColumnItems>
- <TableColumnItem>
- <ScriptBlock>"0x$($_.VirtualAddress.ToString('X8'))"</ScriptBlock>
- </TableColumnItem>
- <TableColumnItem>
- <ScriptBlock>"0x$($_.Size.ToString('X8'))"</ScriptBlock>
- </TableColumnItem>
- </TableColumnItems>
- </TableRowEntry>
- </TableRowEntries>
- </TableControl>
- </View>
- <View>
- <Name>ImportView</Name>
- <ViewSelectedBy>
- <TypeName>Import</TypeName>
- </ViewSelectedBy>
- <TableControl>
- <AutoSize/>
- <TableHeaders>
- <TableColumnHeader>
- <Label>ModuleName</Label>
- <Alignment>Right</Alignment>
- </TableColumnHeader>
- <TableColumnHeader>
- <Label>VA/FT</Label>
- </TableColumnHeader>
- <TableColumnHeader>
- <Label>Ordinal</Label>
- </TableColumnHeader>
- <TableColumnHeader>
- <Label>FunctionName</Label>
- </TableColumnHeader>
- </TableHeaders>
- <TableRowEntries>
- <TableRowEntry>
- <TableColumnItems>
- <TableColumnItem>
- <Alignment>Right</Alignment>
- <PropertyName>ModuleName</PropertyName>
- </TableColumnItem>
- <TableColumnItem>
- <PropertyName>RVA</PropertyName>
- </TableColumnItem>
- <TableColumnItem>
- <PropertyName>Ordinal</PropertyName>
- </TableColumnItem>
- <TableColumnItem>
- <PropertyName>FunctionName</PropertyName>
- </TableColumnItem>
- </TableColumnItems>
- </TableRowEntry>
- </TableRowEntries>
- </TableControl>
- </View>
- <View>
- <Name>ExportView</Name>
- <ViewSelectedBy>
- <TypeName>Export</TypeName>
- </ViewSelectedBy>
- <TableControl>
- <AutoSize/>
- <TableHeaders>
- <TableColumnHeader>
- <Label>RVA</Label>
- </TableColumnHeader>
- <TableColumnHeader>
- <Label>Ordinal</Label>
- </TableColumnHeader>
- <TableColumnHeader>
- <Label>FunctionName</Label>
- </TableColumnHeader>
- <TableColumnHeader>
- <Label>ForwardedName</Label>
- </TableColumnHeader>
- </TableHeaders>
- <TableRowEntries>
- <TableRowEntry>
- <TableColumnItems>
- <TableColumnItem>
- <PropertyName>RVA</PropertyName>
- </TableColumnItem>
- <TableColumnItem>
- <PropertyName>Ordinal</PropertyName>
- </TableColumnItem>
- <TableColumnItem>
- <PropertyName>FunctionName</PropertyName>
- </TableColumnItem>
- <TableColumnItem>
- <PropertyName>ForwardedName</PropertyName>
- </TableColumnItem>
- </TableColumnItems>
- </TableRowEntry>
- </TableRowEntries>
- </TableControl>
- </View>
- </ViewDefinitions>
-</Configuration>
diff --git a/PETools/PETools.psd1 b/PETools/PETools.psd1
deleted file mode 100644
index ef470a7..0000000
--- a/PETools/PETools.psd1
+++ /dev/null
@@ -1,89 +0,0 @@
-@{
-
-# Script module or binary module file associated with this manifest.
-ModuleToProcess = 'PETools.psm1'
-
-# Version number of this module.
-ModuleVersion = '1.0.0.0'
-
-# ID used to uniquely identify this module
-GUID = 'd15059e2-8bd9-47ff-8bcd-b708ff90e402'
-
-# Author of this module
-Author = 'Matthew Graeber'
-
-# Company or vendor of this module
-CompanyName = ''
-
-# Copyright statement for this module
-Copyright = 'BSD 3-Clause'
-
-# Description of the functionality provided by this module
-Description = 'PowerSploit Portable Executable Analysis Module'
-
-# Minimum version of the Windows PowerShell engine required by this module
-PowerShellVersion = '2.0'
-
-# Name of the Windows PowerShell host required by this module
-# PowerShellHostName = ''
-
-# Minimum version of the Windows PowerShell host required by this module
-# PowerShellHostVersion = ''
-
-# Minimum version of the .NET Framework required by this module
-# DotNetFrameworkVersion = ''
-
-# Minimum version of the common language runtime (CLR) required by this module
-# CLRVersion = ''
-
-# Processor architecture (None, X86, Amd64) required by this module
-# ProcessorArchitecture = ''
-
-# Modules that must be imported into the global environment prior to importing this module
-# RequiredModules = @()
-
-# Assemblies that must be loaded prior to importing this module
-# RequiredAssemblies = @()
-
-# Script files (.ps1) that are run in the caller's environment prior to importing this module.
-# ScriptsToProcess = ''
-
-# Type files (.ps1xml) to be loaded when importing this module
-# TypesToProcess = @()
-
-# Format files (.ps1xml) to be loaded when importing this module
-FormatsToProcess = 'PETools.format.ps1xml', 'Get-ObjDump.format.ps1xml', 'Get-LibSymbols.format.ps1xml'
-
-# Modules to import as nested modules of the module specified in RootModule/ModuleToProcess
-# NestedModules = @()
-
-# Functions to export from this module
-FunctionsToExport = '*'
-
-# Cmdlets to export from this module
-CmdletsToExport = '*'
-
-# Variables to export from this module
-VariablesToExport = ''
-
-# Aliases to export from this module
-AliasesToExport = ''
-
-# List of all modules packaged with this module.
-ModuleList = @(@{ModuleName = 'PETools'; ModuleVersion = '1.0.0.0'; GUID = 'd15059e2-8bd9-47ff-8bcd-b708ff90e402'})
-
-# List of all files packaged with this module
-FileList = 'PETools.psm1', 'PETools.psd1', 'PETools.format.ps1xml', 'Get-DllLoadPath.ps1',
- 'Get-PEHeader.ps1', 'Get-ObjDump.ps1', 'Get-ObjDump.format.ps1xml', 'Get-LibSymbols.ps1',
- 'Usage.md'
-
-# Private data to pass to the module specified in RootModule/ModuleToProcess
-# PrivateData = ''
-
-# HelpInfo URI of this module
-# HelpInfoURI = ''
-
-# Default prefix for commands exported from this module. Override the default prefix using Import-Module -Prefix.
-# DefaultCommandPrefix = ''
-
-}
diff --git a/PETools/PETools.psm1 b/PETools/PETools.psm1
deleted file mode 100644
index 81d3818..0000000
--- a/PETools/PETools.psm1
+++ /dev/null
@@ -1 +0,0 @@
-Get-ChildItem (Join-Path $PSScriptRoot *.ps1) | % { . $_.FullName}
diff --git a/PETools/Usage.md b/PETools/Usage.md
deleted file mode 100644
index 6c96b10..0000000
--- a/PETools/Usage.md
+++ /dev/null
@@ -1,12 +0,0 @@
-To install this module, drop the entire PETools folder into one of your module directories. The default PowerShell module paths are listed in the $Env:PSModulePath environment variable.
-
-The default per-user module path is: "$Env:HomeDrive$Env:HOMEPATH\Documents\WindowsPowerShell\Modules"
-The default computer-level module path is: "$Env:windir\System32\WindowsPowerShell\v1.0\Modules"
-
-To use the module, type `Import-Module PETools`
-
-To see the commands imported, type `Get-Command -Module PETools`
-
-For help on each individual command, Get-Help is your friend.
-
-Note: The tools contained within this module were all designed such that they can be run individually. Including them in a module simply lends itself to increased portability. \ No newline at end of file