diff options
author | mattifestation <mattgraeber@gmail.com> | 2014-11-16 10:26:11 -0500 |
---|---|---|
committer | mattifestation <mattgraeber@gmail.com> | 2014-11-16 10:26:11 -0500 |
commit | 956e4c968a1795d868e35fcb72311704d616cbaf (patch) | |
tree | ca962602b87d3a7c89b6d864f6e17c541eb3cce2 /PETools | |
parent | 97034006f63f2691cde8ddb1055b1253c6f93cce (diff) | |
download | PowerSploit-956e4c968a1795d868e35fcb72311704d616cbaf.tar.gz PowerSploit-956e4c968a1795d868e35fcb72311704d616cbaf.zip |
Moving all RE functionality to PowerShellArsenal
https://github.com/mattifestation/PowerShellArsenal
PowerSploit will now stay true to its roots of being a purely offensive
PowerShell module.
Diffstat (limited to 'PETools')
-rw-r--r-- | PETools/Get-DllLoadPath.ps1 | 190 | ||||
-rw-r--r-- | PETools/Get-LibSymbols.format.ps1xml | 31 | ||||
-rw-r--r-- | PETools/Get-LibSymbols.ps1 | 282 | ||||
-rw-r--r-- | PETools/Get-ObjDump.format.ps1xml | 292 | ||||
-rw-r--r-- | PETools/Get-ObjDump.ps1 | 708 | ||||
-rw-r--r-- | PETools/Get-PEHeader.ps1 | 960 | ||||
-rw-r--r-- | PETools/PETools.format.ps1xml | 374 | ||||
-rw-r--r-- | PETools/PETools.psd1 | 89 | ||||
-rw-r--r-- | PETools/PETools.psm1 | 1 | ||||
-rw-r--r-- | PETools/Usage.md | 12 |
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 |