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.
This commit is contained in:
mattifestation 2014-11-16 10:26:11 -05:00
parent 97034006f6
commit 956e4c968a
40 changed files with 10 additions and 8686 deletions

View File

@ -1,48 +0,0 @@
@{
# Script module or binary module file associated with this manifest.
ModuleToProcess = 'Capstone.psm1'
# Version number of this module.
ModuleVersion = '2.0.0.0'
# ID used to uniquely identify this module
GUID = 'bc335667-02fd-46c4-a3d9-0a5113c9c03b'
# Author of this module
Author = 'Matthew Graeber'
# Copyright statement for this module
Copyright = 'see LICENSE.TXT'
# Description of the functionality provided by this module
Description = 'Capstone Disassembly Framework Binding Module'
# Minimum version of the Windows PowerShell engine required by this module
PowerShellVersion = '3.0'
# Minimum version of the common language runtime (CLR) required by this module
CLRVersion = '4.0'
# Assemblies that must be loaded prior to importing this module
RequiredAssemblies = 'lib/capstone.dll'
# Format files (.ps1xml) to be loaded when importing this module
FormatsToProcess = 'Get-CSDisassembly.format.ps1xml'
# Functions to export from this module
FunctionsToExport = '*'
# List of all modules packaged with this module.
ModuleList = @(@{ModuleName = 'Capstone'; ModuleVersion = '1.0.0.0'; GUID = 'bc335667-02fd-46c4-a3d9-0a5113c9c03b'})
# List of all files packaged with this module
FileList = 'Capstone.psm1',
'Capstone.psd1',
'Get-CSDisassembly.format.ps1xml',
'LICENSE.TXT',
'README',
'lib/capstone.dll',
'lib/x86/libcapstone.dll',
'lib/x64/libcapstone.dll'
}

View File

@ -1,171 +0,0 @@
function Get-CSDisassembly
{
<#
.SYNOPSIS
Disassembles a byte array using the Capstone Engine disassembly framework.
PowerSploit Function: Get-CSDisassembly
Author: Matthew Graeber (@mattifestation)
License: See LICENSE.TXT
Required Dependencies: lib\capstone.dll, lib\[x86|x64]\libcapstone.dll
Optional Dependencies: None
.DESCRIPTION
Get-CSDisassembly is compatible on 32 and 64-bit.
.PARAMETER Architecture
Specifies the architecture of the code to be disassembled.
.PARAMETER Mode
Specifies the mode in which to disassemble code. For example, to disassemble Amd64 code, architecture is set to 'X86' and Mode is set to 'MODE_64'.
.PARAMETER Code
A byte array consisting of the code to be disassembled.
.PARAMETER Offset
Specifies the starting address of the disassembly listing.
.PARAMETER Count
Specifies the maximum number of instructions to disassemble.
.PARAMETER Syntax
Specifies the syntax flavor to be used (INTEL vs. ATT).
.PARAMETER DetailOn
Specifies that detailed parsing should be performed - i.e. provide detailed information for each disassembled instruction.
.PARAMETER Verstion
Prints the running Capstone Framework version.
.EXAMPLE
$Bytes = [Byte[]] @( 0x8D, 0x4C, 0x32, 0x08, 0x01, 0xD8, 0x81, 0xC6, 0x34, 0x12, 0x00, 0x00 )
Get-CSDisassembly -Architecture X86 -Mode Mode16 -Code $Bytes -Offset 0x1000
$Bytes = [Byte[]] @( 0x8D, 0x4C, 0x32, 0x08, 0x01, 0xD8, 0x81, 0xC6, 0x34, 0x12, 0x00, 0x00 )
Get-CSDisassembly -Architecture X86 -Mode Mode32 -Code $Bytes
$Bytes = [Byte[]] @( 0x8D, 0x4C, 0x32, 0x08, 0x01, 0xD8, 0x81, 0xC6, 0x34, 0x12, 0x00, 0x00 )
Get-CSDisassembly -Architecture X86 -Mode Mode32 -Code $Bytes -Syntax ATT
$Bytes = [Byte[]] @( 0x55, 0x48, 0x8b, 0x05, 0xb8, 0x13, 0x00, 0x00 )
Get-CSDisassembly -Architecture X86 -Mode Mode64 -Code $Bytes -DetailOn
$Bytes = [Byte[]] @( 0xED, 0xFF, 0xFF, 0xEB, 0x04, 0xe0, 0x2d, 0xe5, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x83, 0x22, 0xe5, 0xf1, 0x02, 0x03, 0x0e, 0x00, 0x00, 0xa0, 0xe3, 0x02, 0x30, 0xc1, 0xe7, 0x00, 0x00, 0x53, 0xe3 )
Get-CSDisassembly -Architecture Arm -Mode Arm -Code $Bytes
$Bytes = [Byte[]] @( 0x4f, 0xf0, 0x00, 0x01, 0xbd, 0xe8, 0x00, 0x88, 0xd1, 0xe8, 0x00, 0xf0 )
Get-CSDisassembly -Architecture Arm -Mode Thumb -Code $Bytes
$Bytes = [Byte[]] @( 0x10, 0xf1, 0x10, 0xe7, 0x11, 0xf2, 0x31, 0xe7, 0xdc, 0xa1, 0x2e, 0xf3, 0xe8, 0x4e, 0x62, 0xf3 )
Get-CSDisassembly -Architecture Arm -Mode Arm -Code $Bytes
$Bytes = [Byte[]] @( 0x70, 0x47, 0xeb, 0x46, 0x83, 0xb0, 0xc9, 0x68 )
Get-CSDisassembly -Architecture Arm -Mode Thumb -Code $Bytes -DetailOn
$Bytes = [Byte[]] @( 0x21, 0x7c, 0x02, 0x9b, 0x21, 0x7c, 0x00, 0x53, 0x00, 0x40, 0x21, 0x4b, 0xe1, 0x0b, 0x40, 0xb9 )
Get-CSDisassembly -Architecture Arm64 -Mode Arm -Code $Bytes
$Bytes = [Byte[]] @( 0x0C, 0x10, 0x00, 0x97, 0x00, 0x00, 0x00, 0x00, 0x24, 0x02, 0x00, 0x0c, 0x8f, 0xa2, 0x00, 0x00, 0x34, 0x21, 0x34, 0x56 )
Get-CSDisassembly -Architecture Mips -Mode 'Mode32, BigEndian' -Code $Bytes
$Bytes = [Byte[]] @( 0x56, 0x34, 0x21, 0x34, 0xc2, 0x17, 0x01, 0x00 )
Get-CSDisassembly -Architecture Mips -Mode 'Mode64, LittleEndian' -Code $Bytes
$Bytes = [Byte[]] @( 0x80, 0x20, 0x00, 0x00, 0x80, 0x3f, 0x00, 0x00, 0x10, 0x43, 0x23, 0x0e, 0xd0, 0x44, 0x00, 0x80, 0x4c, 0x43, 0x22, 0x02, 0x2d, 0x03, 0x00, 0x80, 0x7c, 0x43, 0x20, 0x14, 0x7c, 0x43, 0x20, 0x93, 0x4f, 0x20, 0x00, 0x21, 0x4c, 0xc8, 0x00, 0x21 )
Get-CSDisassembly -Architecture PPC -Mode BigEndian -Code $Bytes
.INPUTS
None
You cannot pipe objects to Get-CSDisassembly.
.OUTPUTS
Capstone.Instruction[]
Get-CSDisassembly returns an array of Instruction objects.
#>
[OutputType([Capstone.Instruction])]
[CmdletBinding(DefaultParameterSetName = 'Disassemble')]
Param (
[Parameter(Mandatory, ParameterSetName = 'Disassemble')]
[Capstone.Architecture]
$Architecture,
[Parameter(Mandatory, ParameterSetName = 'Disassemble')]
[Capstone.Mode]
$Mode,
[Parameter(Mandatory, ParameterSetName = 'Disassemble')]
[ValidateNotNullOrEmpty()]
[Byte[]]
$Code,
[Parameter( ParameterSetName = 'Disassemble' )]
[UInt64]
$Offset = 0,
[Parameter( ParameterSetName = 'Disassemble' )]
[UInt32]
$Count = 0,
[Parameter( ParameterSetName = 'Disassemble' )]
[ValidateSet('Intel', 'ATT')]
[String]
$Syntax,
[Parameter( ParameterSetName = 'Disassemble' )]
[Switch]
$DetailOn,
[Parameter( ParameterSetName = 'Version' )]
[Switch]
$Version
)
if ($PsCmdlet.ParameterSetName -eq 'Version')
{
$Disassembly = New-Object Capstone.Capstone([Capstone.Architecture]::X86, [Capstone.Mode]::Mode16)
$Disassembly.Version
return
}
$Disassembly = New-Object Capstone.Capstone($Architecture, $Mode)
if ($Disassembly.Version -ne [Capstone.Capstone]::BindingVersion)
{
Write-Error "capstone.dll version ($([Capstone.Capstone]::BindingVersion.ToString())) should be the same as libcapstone.dll version. Otherwise, undefined behavior is likely."
}
if ($Syntax)
{
switch ($Syntax)
{
'Intel' { $SyntaxMode = [Capstone.OptionValue]::SyntaxIntel }
'ATT' { $SyntaxMode = [Capstone.OptionValue]::SyntaxATT }
}
$Disassembly.SetSyntax($SyntaxMode)
}
if ($DetailOn)
{
$Disassembly.SetDetail($True)
}
$Disassembly.Disassemble($Code, $Offset, $Count)
}

View File

@ -1,41 +0,0 @@
<?xml version="1.0" encoding="utf-8" ?>
<Configuration>
<ViewDefinitions>
<View>
<Name>InstructionView</Name>
<ViewSelectedBy>
<TypeName>Capstone.Instruction</TypeName>
</ViewSelectedBy>
<TableControl>
<AutoSize/>
<TableHeaders>
<TableColumnHeader>
<Label>Address</Label>
</TableColumnHeader>
<TableColumnHeader>
<Label>Mnemonic</Label>
</TableColumnHeader>
<TableColumnHeader>
<Label>Operands</Label>
</TableColumnHeader>
</TableHeaders>
<TableRowEntries>
<TableRowEntry>
<TableColumnItems>
<TableColumnItem>
<PropertyName>Address</PropertyName>
<FormatString>0x{0:X8}</FormatString>
</TableColumnItem>
<TableColumnItem>
<PropertyName>Mnemonic</PropertyName>
</TableColumnItem>
<TableColumnItem>
<PropertyName>Operands</PropertyName>
</TableColumnItem>
</TableColumnItems>
</TableRowEntry>
</TableRowEntries>
</TableControl>
</View>
</ViewDefinitions>
</Configuration>

View File

@ -1,30 +0,0 @@
This is the software license for Capstone disassembly framework.
Capstone has been designed & implemented by Nguyen Anh Quynh <aquynh@gmail.com>
See http://www.capstone-engine.org for further information.
Copyright (c) 2013, COSEINC.
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
* Redistributions of source code must retain the above copyright notice,
this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright notice,
this list of conditions and the following disclaimer in the documentation
and/or other materials provided with the distribution.
* Neither the name of the developer(s) nor the names of its
contributors may be used to endorse or promote products derived from this
software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
POSSIBILITY OF SUCH DAMAGE.

View File

@ -1,17 +0,0 @@
This module has three dependencies:
* lib\x86\libcapstone.dll (the 32-bit unmanaged Capstone library)
* lib\x64\libcapstone.dll (the 64-bit unmanaged Capstone library)
* lib\capstone.dll (the managed C# bindings to the Capstone Framework)
To install this module, drop the entire ScriptModification 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 Capstone`
To see the commands imported, type `Get-Command -Module Capstone`
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.

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@ -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 }
}
}

View File

@ -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>

View File

@ -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 {}
}

View File

@ -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>

View File

@ -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 {}
}

View File

@ -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
}
}

View File

@ -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>

View File

@ -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 = ''
}

View File

@ -1 +0,0 @@
Get-ChildItem (Join-Path $PSScriptRoot *.ps1) | % { . $_.FullName}

View File

@ -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.

View File

@ -1,5 +1,4 @@
@{ @{
# Script module or binary module file associated with this manifest. # Script module or binary module file associated with this manifest.
ModuleToProcess = 'PowerSploit.psm1' ModuleToProcess = 'PowerSploit.psm1'
@ -24,39 +23,6 @@ Description = 'PowerSploit Root Module'
# Minimum version of the Windows PowerShell engine required by this module # Minimum version of the Windows PowerShell engine required by this module
PowerShellVersion = '2.0' 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 = @()
# Modules to import as nested modules of the module specified in RootModule/ModuleToProcess
# NestedModules = @()
# Functions to export from this module # Functions to export from this module
FunctionsToExport = '*' FunctionsToExport = '*'
@ -70,28 +36,10 @@ VariablesToExport = ''
AliasesToExport = '' AliasesToExport = ''
# List of all modules packaged with this module. # List of all modules packaged with this module.
ModuleList = @( @{ModuleName = 'PowerSploit'; ModuleVersion = '1.0.0.0'; GUID = '6753b496-d842-40a3-924a-0f09e248640c'}, ModuleList = @( @{ModuleName = 'AntivirusBypass'; ModuleVersion = '1.0.0.0'; GUID = '7cf9de61-2bfc-41b4-a397-9d7cf3a8e66b'},
@{ModuleName = 'AntivirusBypass'; ModuleVersion = '1.0.0.0'; GUID = '7cf9de61-2bfc-41b4-a397-9d7cf3a8e66b'},
@{ModuleName = 'CodeExecution'; ModuleVersion = '1.0.0.0'; GUID = 'a8a6780b-e694-4aa4-b28d-646afa66733c'}, @{ModuleName = 'CodeExecution'; ModuleVersion = '1.0.0.0'; GUID = 'a8a6780b-e694-4aa4-b28d-646afa66733c'},
@{ModuleName = 'Exfiltration'; ModuleVersion = '1.0.0.0'; GUID = '75dafa99-1402-4e29-b5d4-6c87da2b323a'}, @{ModuleName = 'Exfiltration'; ModuleVersion = '1.0.0.0'; GUID = '75dafa99-1402-4e29-b5d4-6c87da2b323a'},
@{ModuleName = 'PETools'; ModuleVersion = '1.0.0.0'; GUID = 'd15059e2-8bd9-47ff-8bcd-b708ff90e402'},
@{ModuleName = 'Recon'; ModuleVersion = '1.0.0.0'; GUID = '7e775ad6-cd3d-4a93-b788-da067274c877'}, @{ModuleName = 'Recon'; ModuleVersion = '1.0.0.0'; GUID = '7e775ad6-cd3d-4a93-b788-da067274c877'},
@{ModuleName = 'ReverseEngineering'; ModuleVersion = '1.0.0.0'; GUID = 'cbffaf47-c55a-4901-92e7-8d794fbe1fff'},
@{ModuleName = 'ScriptModification'; ModuleVersion = '1.0.0.0'; GUID = 'a4d86266-b39b-437a-b5bb-d6f99aa6e610'}, @{ModuleName = 'ScriptModification'; ModuleVersion = '1.0.0.0'; GUID = 'a4d86266-b39b-437a-b5bb-d6f99aa6e610'},
@{ModuleName = 'Persistence'; ModuleVersion = '1.0.0.0'; GUID = '633d0f10-a056-41da-869d-6d2f75430195'} @{ModuleName = 'Persistence'; ModuleVersion = '1.0.0.0'; GUID = '633d0f10-a056-41da-869d-6d2f75430195'} )
@{ModuleName = 'Capstone'; ModuleVersion = '1.0.0.0'; GUID = 'bc335667-02fd-46c4-a3d9-0a5113c9c03b'}
)
# List of all files packaged with this module
FileList = 'PowerSploit.psd1', 'PowerSploit.psm1'
# 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 = ''
} }

100
README.md
View File

@ -1,4 +1,6 @@
### PowerSploit is a collection of Microsoft PowerShell modules that can be used to aid reverse engineers, forensic analysts, and penetration testers during all phases of an assessment. PowerSploit is comprised of the following modules and scripts: ### PowerSploit is a collection of Microsoft PowerShell modules that can be used to aid penetration testers during all phases of an assessment. PowerSploit is comprised of the following modules and scripts:
### Note: All reverse engineering components of PowerSploit now reside in the [PowerShellArsenal](https://github.com/mattifestation/PowerShellArsenal).
## CodeExecution ## CodeExecution
@ -64,86 +66,6 @@ Installs a security support provider (SSP) dll.
Enumerates all loaded security packages (SSPs). Enumerates all loaded security packages (SSPs).
## PETools
**Parse/manipulate Windows portable executables.**
#### `Get-PEHeader`
An in-memory and on-disk PE parsing utility.
#### `Get-ObjDump`
Displays information about one or more Windows object files.
#### `Get-LibSymbols`
Displays symbolic information from Windows lib files.
#### `Get-DllLoadPath`
Returns the path from which Windows will load a Dll for the given executable.
## Capstone
**A PowerShell binding for the Capstone Engine disassembly framework.**
#### `Get-CSDisassembly`
Disassembles a byte array using the Capstone Engine disassembly framework.
## ReverseEngineering
**Tools to aid in reverse engineering.**
#### `Get-PEB`
Returns the process environment block (PEB) of a process.
#### `Get-ILDisassembly`
Disassembles a raw MSIL byte array passed in from a MethodInfo object in a manner similar to that of Ildasm.
#### `Get-NtSystemInformation`
A utility that calls and parses the output of the ntdll!NtQuerySystemInformation function. This utility can be used to query internal OS information that is typically not made visible to a user.
#### `Get-StructFromMemory`
Marshals data from an unmanaged block of memory in an arbitrary process to a newly allocated managed object of the specified type.
#### `Get-Member`
A proxy function used to extend the built-in Get-Member cmdlet. It adds the '-Private' parameter allowing you to display non-public .NET members
#### `Get-Strings`
Dumps strings from files in both Unicode and Ascii. This cmdlet replicates the functionality of strings.exe from Sysinternals.
#### `ConvertTo-String`
Converts the bytes of a file to a string that has a 1-to-1 mapping back to the file's original bytes. ConvertTo-String is useful for performing binary regular expressions.
#### `Get-MethodAddress`
Get the unmanaged function address of a .NET method.
#### `Register-ProcessModuleTrace`
Starts a trace of loaded process modules
#### `Get-ProcessModuleTrace`
Displays the process modules that have been loaded since the call to Register-ProcessModuleTrace
#### `Unregister-ProcessModuleTrace`
Stops the running process module trace
#### `Get-Entropy`
Calculates the entropy of a file or byte array.
## AntivirusBypass ## AntivirusBypass
**AV doesn't stand a chance against PowerShell!** **AV doesn't stand a chance against PowerShell!**
@ -275,7 +197,7 @@ Note: The tools contained within this module were all designed such that they ca
* Always provide descriptive, comment-based help for every script. Also, be sure to include your name and a BSD 3-Clause license (unless there are extenuating circumstances that prevent the application of the BSD license). * Always provide descriptive, comment-based help for every script. Also, be sure to include your name and a BSD 3-Clause license (unless there are extenuating circumstances that prevent the application of the BSD license).
* Make sure all functions follow the proper PowerShell verb-noun agreement. Use Get-Verb to list the default verbs used by PowerShell. * Make sure all functions follow the proper PowerShell verb-noun agreement. Use Get-Verb to list the default verbs used by PowerShell. Exceptions to supported verbs will be considered on a case-by-case basis.
* I prefer that variable names be capitalized and be as descriptive as possible. * I prefer that variable names be capitalized and be as descriptive as possible.
@ -285,29 +207,23 @@ Note: The tools contained within this module were all designed such that they ca
* Catch all anticipated errors and provide meaningful output. If you have an error that should stop execution of the script, use 'Throw'. If you have an error that doesn't need to stop execution, use Write-Error. * Catch all anticipated errors and provide meaningful output. If you have an error that should stop execution of the script, use 'Throw'. If you have an error that doesn't need to stop execution, use Write-Error.
* If you are writing a script that interfaces with the Win32 API, do not compile C# code unless absolutely necessary. It is imperative that nothing aside from the script touches the disk. * If you are writing a script that interfaces with the Win32 API, try to avoid compiling C# inline with Add-Type. Try to use the PSReflect module, if possible.
* Do not use hardcoded paths. A script should be useable right out of the box. No one should have to modify the code unless they want to. * Do not use hardcoded paths. A script should be useable right out of the box. No one should have to modify the code unless they want to.
* I don't want any v3 dependencies right now. In fact, it would be ideal to use `Set-StrictMode -Version 2.0` to ensure you are conforming to PowerShell v2 best practices. * PowerShell v2 compatibility is highly desired.
* Use positional parameters and make parameters mandatory when it makes sense to do so. For example, I'm looking for something like the following: * Use positional parameters and make parameters mandatory when it makes sense to do so. For example, I'm looking for something like the following:
* `[Parameter(Position = 0, Mandatory = $True)]` * `[Parameter(Position = 0, Mandatory = $True)]`
* Don't use any aliases unless it makes sense for receiving pipeline input. They make code more difficult to read for people who are unfamiliar with a particular alias. * Don't use any aliases unless it makes sense for receiving pipeline input. They make code more difficult to read for people who are unfamiliar with a particular alias.
* Don't let commands run on for too long. For example, a pipeline is a natural place for a line break. * Try not to let commands run on for too long. For example, a pipeline is a natural place for a line break.
* Don't go overboard with inline comments. Only use them when certain aspects of the code might be confusing to a reader. * Don't go overboard with inline comments. Only use them when certain aspects of the code might be confusing to a reader.
* Use Out-Null to suppress unwanted/irrelevant output. * Rather than using Out-Null to suppress unwanted/irrelevant output, save the unwanted output to $null. Doing so provides a slight performance enhancement.
* Only use .NET code when absolutely necessary.
* Use the Write-Output keyword when returning an object from a function. I know it's not necessary but it makes the code more readable.
* Use default values for your parameters when it makes sense. Ideally, you want a script that will work without requiring any parameters. * Use default values for your parameters when it makes sense. Ideally, you want a script that will work without requiring any parameters.
* Scripts that are intended to run on a remote machine should be self-contained and not rely upon any additional scripts. Scripts that are designed to run on your host machine can have dependencies on other scripts.
* If a script creates complex custom objects, include a ps1xml file that will properly format the object's output. * If a script creates complex custom objects, include a ps1xml file that will properly format the object's output.

View File

@ -1,70 +0,0 @@
filter ConvertTo-String
{
<#
.SYNOPSIS
Converts the bytes of a file to a string.
PowerSploit Function: ConvertTo-String
Author: Matthew Graeber (@mattifestation)
License: BSD 3-Clause
Required Dependencies: None
Optional Dependencies: None
.DESCRIPTION
ConvertTo-String converts the bytes of a file to a string that has a
1-to-1 mapping back to the file's original bytes. ConvertTo-String is
useful for performing binary regular expressions.
.PARAMETER Path
Specifies the path to the file to convert.
.EXAMPLE
PS C:\>$BinaryString = ConvertTo-String C:\Windows\SysWow64\kernel32.dll
PS C:\>$HotpatchableRegex = [Regex] '[\xCC\x90]{5}\x8B\xFF'
PS C:\>$HotpatchableRegex.Matches($BinaryString)
Description
-----------
Converts kernel32.dll into a string. A binary regular expression is
then performed on the string searching for a hotpatchable code
sequence - i.e. 5 nop/int3 followed by a mov edi, edi instruction.
.NOTES
The intent of ConvertTo-String is not to replicate the functionality
of strings.exe, rather it is intended to be used when
performing regular expressions on binary data.
.LINK
http://www.exploit-monday.com
#>
[OutputType([String])]
Param (
[Parameter( Mandatory = $True,
Position = 0,
ValueFromPipeline = $True )]
[ValidateScript({-not (Test-Path $_ -PathType Container)})]
[String]
$Path
)
$FileStream = New-Object -TypeName IO.FileStream -ArgumentList (Resolve-Path $Path), 'Open', 'Read'
# Note: Codepage 28591 returns a 1-to-1 char to byte mapping
$Encoding = [Text.Encoding]::GetEncoding(28591)
$StreamReader = New-Object IO.StreamReader($FileStream, $Encoding)
$BinaryText = $StreamReader.ReadToEnd()
$StreamReader.Close()
$FileStream.Close()
Write-Output $BinaryText
}

View File

@ -1,106 +0,0 @@
function Get-Entropy
{
<#
.SYNOPSIS
Calculates the entropy of a file or byte array.
PowerSploit Function: Get-Entropy
Author: Matthew Graeber (@mattifestation)
License: BSD 3-Clause
Required Dependencies: None
Optional Dependencies: None
.PARAMETER ByteArray
Specifies the byte array containing the data from which entropy will be calculated.
.PARAMETER FilePath
Specifies the path to the input file from which entropy will be calculated.
.EXAMPLE
C:\PS>Get-Entropy -FilePath C:\Windows\System32\kernel32.dll
.EXAMPLE
C:\PS>ls C:\Windows\System32\*.dll | % { Get-Entropy -FilePath $_ }
.EXAMPLE
C:\PS>$RandArray = New-Object Byte[](10000)
C:\PS>foreach ($Offset in 0..9999) { $RandArray[$Offset] = [Byte] (Get-Random -Min 0 -Max 256) }
C:\PS>$RandArray | Get-Entropy
Description
-----------
Calculates the entropy of a large array containing random bytes.
.EXAMPLE
C:\PS> 0..255 | Get-Entropy
Description
-----------
Calculates the entropy of 0-255. This should equal exactly 8.
.OUTPUTS
System.Double
Get-Entropy outputs a double representing the entropy of the byte array.
.LINK
http://www.exploit-monday.com
#>
[CmdletBinding()] Param (
[Parameter(Mandatory = $True, Position = 0, ValueFromPipeline = $True, ParameterSetName = 'Bytes')]
[ValidateNotNullOrEmpty()]
[Byte[]]
$ByteArray,
[Parameter(Mandatory = $True, Position = 0, ParameterSetName = 'File')]
[ValidateNotNullOrEmpty()]
[IO.FileInfo]
$FilePath
)
BEGIN
{
$FrequencyTable = @{}
$ByteArrayLength = 0
}
PROCESS
{
if ($PsCmdlet.ParameterSetName -eq 'File')
{
$ByteArray = [IO.File]::ReadAllBytes($FilePath.FullName)
}
foreach ($Byte in $ByteArray)
{
$FrequencyTable[$Byte]++
$ByteArrayLength++
}
}
END
{
$Entropy = 0.0
foreach ($Byte in 0..255)
{
$ByteProbability = ([Double] $FrequencyTable[[Byte]$Byte]) / $ByteArrayLength
if ($ByteProbability -gt 0)
{
$Entropy += -$ByteProbability * [Math]::Log($ByteProbability, 2)
}
}
Write-Output $Entropy
}
}

View File

@ -1,46 +0,0 @@
<?xml version="1.0" encoding="utf-8" ?>
<Configuration>
<ViewDefinitions>
<View>
<Name>ILInstructionView</Name>
<ViewSelectedBy>
<TypeName>IL_INSTRUCTION</TypeName>
</ViewSelectedBy>
<TableControl>
<AutoSize/>
<TableHeaders>
<TableColumnHeader>
<Label>Position</Label>
</TableColumnHeader>
<TableColumnHeader>
<Label>Instruction</Label>
</TableColumnHeader>
<TableColumnHeader>
<Label>Operand</Label>
</TableColumnHeader>
<TableColumnHeader>
<Label>MetadataToken</Label>
</TableColumnHeader>
</TableHeaders>
<TableRowEntries>
<TableRowEntry>
<TableColumnItems>
<TableColumnItem>
<PropertyName>Position</PropertyName>
</TableColumnItem>
<TableColumnItem>
<PropertyName>Instruction</PropertyName>
</TableColumnItem>
<TableColumnItem>
<PropertyName>Operand</PropertyName>
</TableColumnItem>
<TableColumnItem>
<ScriptBlock>if ($_.MetadataToken) {"0x$($_.MetadataToken.ToString('X8'))"}</ScriptBlock>
</TableColumnItem>
</TableColumnItems>
</TableRowEntry>
</TableRowEntries>
</TableControl>
</View>
</ViewDefinitions>
</Configuration>

View File

@ -1,215 +0,0 @@
function Get-ILDisassembly
{
<#
.SYNOPSIS
A MSIL (Microsoft Intermediate Language) disassembler.
PowerSploit Function: Get-ILDisassembly
Author: Matthew Graeber (@mattifestation)
License: BSD 3-Clause
Required Dependencies: None
Optional Dependencies: None
.DESCRIPTION
Get-ILDisassembly disassembles a raw MSIL byte array passed in from a MethodInfo object in a manner similar to that of Ildasm.
The majority of this code was simply translated from C# (with permission) from a code example taken from: "C# 4.0 in a Nutshell", Copyright 2010, Joseph Albahari and Ben Albahari, pg. 728-733
.PARAMETER MethodInfo
A MethodInfo object that describes the implementation of the method and contains the IL for the method.
.EXAMPLE
C:\PS> [Int].GetMethod('Parse', [String]) | Get-ILDisassembly | Format-Table Position, Instruction, Operand -AutoSize
Position Instruction Operand
-------- ----------- -------
IL_0000 ldarg.0
IL_0001 ldc.i4.7
IL_0002 call System.Globalization.NumberFormatInfo.get_CurrentInfo
IL_0007 call System.Number.ParseInt32
IL_000C ret
Description
-----------
Disassembles the System.Int32.Parse(String) method
.EXAMPLE
C:\PS> $MethodInfo = [Array].GetMethod('BinarySearch', [Type[]]([Array], [Object]))
C:\PS> Get-ILDisassembly $MethodInfo | Format-Table Position, Instruction, Operand -AutoSize
Position Instruction Operand
-------- ----------- -------
IL_0000 ldarg.0
IL_0001 brtrue.s IL_000E
IL_0003 ldstr 'array'
IL_0008 newobj System.ArgumentNullException..ctor
IL_000D throw
IL_000E ldarg.0
IL_000F ldc.i4.0
IL_0010 callvirt System.Array.GetLowerBound
IL_0015 stloc.0
IL_0016 ldarg.0
IL_0017 ldloc.0
IL_0018 ldarg.0
IL_0019 callvirt System.Array.get_Length
IL_001E ldarg.1
IL_001F ldnull
IL_0020 call System.Array.BinarySearch
IL_0025 ret
Description
-----------
Disassembles the System.Array.BinarySearch(Array, Object) method
.INPUTS
System.Reflection.MethodInfo, System.Reflection.ConstructorInfo
A method or constructor description containing the raw IL bytecodes.
.OUTPUTS
System.Object
Returns a custom object consisting of a position, instruction, and opcode parameter.
.LINK
http://www.exploit-monday.com
http://www.albahari.com/nutshell/cs4ch18.aspx
http://msdn.microsoft.com/en-us/library/system.reflection.emit.opcodes.aspx
http://www.ecma-international.org/publications/files/ECMA-ST/Ecma-335.pdf
#>
Param (
[Parameter(Mandatory = $True, ValueFromPipeline = $True)]
[ValidateScript({$_ -is [Reflection.MethodInfo] -or $_ -is [Reflection.ConstructorInfo]})]
[Object]
$MethodInfo
)
if (!($MethodInfo.GetMethodBody())) {
return
}
$IL = $MethodInfo.GetMethodBody().GetILAsByteArray()
$MethodModule = $MethodInfo.DeclaringType.Module
$OpCodeTable = @{}
# Fill OpCodeTable with every OpCode so that it can be referenced by numeric byte value
[System.Reflection.Emit.OpCodes].GetMembers() |
ForEach-Object {
try {
$OpCode = $_.GetValue($null)
$OpCodeTable[[Int16] $OpCode.Value] = $OpCode
} catch {}
}
$Position = 0
# Disassemble every instruction until the end of the IL bytecode array is reached
while ($Position -lt $IL.Length) {
# Get current instruction position
$InstructionPostion = "IL_{0}" -f ($Position.ToString('X4'))
if ($IL[$Position] -eq 0xFE) {
# You are dealing with a two-byte opcode in this case
$Op = $OpCodeTable[[Int16] ([BitConverter]::ToInt16($IL[($Position+1)..$Position], 0))]
$Position++
} else {
# Otherwise, it's a one-byte opcode
$Op = $OpCodeTable[[Int16] $IL[$Position]]
}
$Position++
$Type = $Op.OperandType
$Operand = $null
$OpInt = $null
if ($Type -eq 'InlineNone') {
$OperandLength = 0
} elseif (($Type -eq 'ShortInlineBrTarget') -or ($Type -eq 'ShortInlineI') -or ($Type -eq 'ShortInlineVar')) {
$OperandLength = 1
if ($Type -eq 'ShortInlineBrTarget') { # Short relative jump instruction
# [SByte]::Parse was used because PowerShell doesn't handle signed bytes well
$Target = $Position + ([SByte]::Parse($IL[$Position].ToString('X2'), 'AllowHexSpecifier')) + 1
$Operand = "IL_{0}" -f ($Target.ToString('X4'))
}
} elseif ($Type -eq 'InlineVar') {
$OperandLength = 2
} elseif (($Type -eq 'InlineI8') -or (($Type -eq 'InlineR'))) {
$OperandLength = 8
} elseif ($Type -eq 'InlineSwitch') {
# This is the only operand type with a variable number of operands
$TargetCount = [BitConverter]::ToInt32($IL, $Position)
$OperandLength = 4 * ($TargetCount + 1)
$Targets = New-Object String[]($TargetCount)
foreach ($i in 0..($TargetCount - 1)) {
# Get all switch jump targets
$Target = [BitConverter]::ToInt32($IL, ($Position + ($i + 1) * 4))
$Targets[$i] = "IL_{0}" -f (($Position + $Target + $OperandLength).ToString('X4'))
}
$Operand = "({0})" -f ($Targets -join ',')
} else {
$OperandLength = 4
$Operand = $null
$OpInt = [BitConverter]::ToInt32($IL, $Position)
if (($Type -eq 'InlineTok') -or ($Type -eq 'InlineMethod') -or ($Type -eq 'InlineField') -or ($Type -eq 'InlineType')) {
# Resolve all operands with metadata tokens
Write-Verbose "OpCode Metadata for member: $OpInt"
try { $MemberInfo = $MethodModule.ResolveMember($OpInt) } catch { $Operand = $null }
if (!$MemberInfo) { $Operand = $null }
# Retrieve the actual name of the class and method
if ($MemberInfo.ReflectedType) {
$Operand = "{0}.{1}" -f ($MemberInfo.ReflectedType.Fullname), ($MemberInfo.Name)
} elseif ($MemberInfo -is [Type]) {
$Operand = $MemberInfo.GetType().FullName
} else {
$Operand = $MemberInfo.Name
}
} elseif ($Type -eq 'InlineString') {
# Retrieve the referenced string
$Operand = "`'{0}`'" -f ($MethodModule.ResolveString($OpInt))
} elseif ($Type -eq 'InlineBrTarget') {
$Operand = "IL_{0}" -f (($Position + $OpInt + 4).ToString('X4'))
} else {
$Operand = $null
}
}
if (($OperandLength -gt 0) -and ($OperandLength -ne 4) -and ($Type -ne 'InlineSwitch') -and ($Type -ne 'ShortInlineBrTarget')) {
# Simply print the hex for all operands with immediate values
$Operand = "0x{0}" -f (($IL[($Position+$OperandLength-1)..$Position] | ForEach-Object { $_.ToString('X2') }) -join '')
}
$Instruction = @{
Position = $InstructionPostion
Instruction = $Op
Operand = $Operand
MetadataToken = $OpInt
}
# Return a custom object containing a position, instruction, and fully-qualified operand
$InstructionObject = New-Object PSObject -Property $Instruction
$InstructionObject.PSObject.TypeNames.Insert(0, 'IL_INSTRUCTION')
$InstructionObject
# Adjust the position in the opcode array accordingly
$Position += $OperandLength
}
}

View File

@ -1,369 +0,0 @@
function Get-Member
{
<#
.SYNOPSIS
Gets the properties and methods of objects.
PowerSploit Proxy Function: Get-Member
Author: Matthew Graeber (@mattifestation)
License: BSD 3-Clause (Except for the help documentation derived from the original Get-Member)
Required Dependencies: None
Optional Dependencies: None
.DESCRIPTION
The Get-Member cmdlet gets the "members" (properties and methods) of objects.
To specify the object, use the InputObject parameter or pipe an object to Get-Member. To retrieve information about static members (members of the class, not of the instance), use the Static parameter. To get only certain types of members, such as NoteProperties, use the MemberType parameter.
.PARAMETER Private
Gets only the non-public members of the object.
These members are typically not exposed and are extracted using reflection.
.PARAMETER Static
Gets only the static properties and methods of the object.
Static properties and methods are defined on the class of objects, not on any particular instance of the class.
If you use the Static parameter with the View parameter, the View parameter is ignored. If you use the Static parameter with the MemberType parameter, Get-Member gets only the members that belong to both sets.
.PARAMETER Force
Adds the intrinsic members (PSBase, PSAdapted, PSObject, PSTypeNames) and the compiler-generated get_, set_, op_, .ctor, and .cctor methods to the display. By default, Get-Member gets these properties in all views other than "Base" and "Adapted," but it does not display them.
The following list describes the properties that are added when you use the Force parameter:
-- PSBase: The original properties of the .NET Framework object without extension or adaptation. These are the properties defined for the object class and listed in MSDN.
-- PSAdapted: The properties and methods defined in the Windows PowerShell extended type system.
-- PSExtended: The properties and methods that were added in the Types.ps1xml files or by using the Add-Member cmdlet.
-- PSObject: The adapter that converts the base object to a Windows PowerShell PSObject object.
-- PSTypeNames: A list of object types that describe the object, in order of specificity. When formatting the object, Windows PowerShell searches for the types in the Format.ps1xml files in the Windows PowerShell installation directory ($pshome). It uses the formatting definition for the first type that it finds.
-- get_*: The object's getter methods
-- set_*: The object's setter methods
-- op_*: The object's operator methods
-- .ctor: The object's constructor
-- .cctor: The object's copy constructor
.PARAMETER InputObject
Specifies the object whose members are retrieved.
Using the InputObject parameter is not the same as piping an object to Get-Member. The differences are as follows:
-- When you pipe a collection of objects to Get-Member, Get-Member gets the members of the individual objects in the collection, such as the properties of the integers in an array of integers.
-- When you use InputObject to submit a collection of objects, Get-Member gets the members of the collection, such as the properties of the array in an array of integers.
.PARAMETER PrivateMemberType
When the 'Private' parameter is specified, only members with the specified member type. The default is All.
The valid values for this parameter are:
-- Constructor: A constructor method of the underlying .NET Framework object.
-- Event: Indicates that the object sends a message to indicate an action or a change in state.
-- Field: A private field of the underlying .NET Framework object.
-- Method: A method of the underlying .NET Framework object.
-- Property: A property of the underlying .NET Framework object.
-- TypeInfo: A type of the underlying .NET Framework object.
-- Custom: A custom member type
-- NestedType: A nested type of the underlying .NET Framework object.
-- All: Gets all member types.
.PARAMETER MemberType
Gets only members with the specified PowerShell member type. The default is All.
The valid values for this parameter are:
-- AliasProperty: A property that defines a new name for an existing property.
-- CodeMethod: A method that references a static method of a .NET Framework class.
-- CodeProperty: A property that references a static property of a .NET Framework class.
-- Event: Indicates that the object sends a message to indicate an action or a change in state.
-- MemberSet: A predefined collection of properties and methods, such as PSBase, PSObject, and PSTypeNames.
-- Method: A method of the underlying .NET Framework object.
-- NoteProperty: A property with a static value.
-- ParameterizedProperty: A property that takes parameters and parameter values.
-- Property: A property of the underlying .NET Framework object.
-- PropertySet: A predefined collection of object properties.
-- ScriptMethod: A method whose value is the output of a script.
-- ScriptProperty: A property whose value is the output of a script.
-- All: Gets all member types.
-- Methods: Gets all types of methods of the object (for example, Method, CodeMethod, ScriptMethod).
-- Properties: Gets all types of properties of the object (for example, Property, CodeProperty, AliasProperty, ScriptProperty).
Not all objects have every type of member. If you specify a member type that the object does not have, Windows PowerShell returns a null value.
To get related types of members, such as all extended members, use the View parameter. If you use the MemberType parameter with the Static or View parameters, Get-Member gets the members that belong to both sets.
.PARAMETER Name
Specifies the names of one or more properties or methods of the object. Get-Member gets only the specified properties and methods.
If you use the Name parameter with the MemberType, View, or Static parameters, Get-Member gets only the members that satisfy the criteria of all parameters.
To get a static member by name, use the Static parameter with the Name parameter.
.PARAMETER View
Gets only particular types of members (properties and methods). Specify one or more of the values. The default is "Adapted, Extended".
Valid values are:
-- Base: Gets only the original properties and methods of the .NET Framework object (without extension or adaptation).
-- Adapted: Gets only the properties and methods defined in the Windows PowerShell extended type system.
-- Extended: Gets only the properties and methods that were added in the Types.ps1xml files or by using the Add-Member cmdlet.
-- All: Gets the members in the Base, Adapted, and Extended views.
The View parameter determines the members retrieved, not just the display of those members.
To get particular member types, such as script properties, use the MemberType parameter. If you use the MemberType and View parameters in the same command, Get-Member gets the members that belong to both sets. If you use the Static and View parameters in the same command, the View parameter is ignored.
.EXAMPLE
C:\PS> [String] | Get-Member -Static -Private
Description
-----------
Returns all staic, non-public members of the String class.
.EXAMPLE
C:\PS> [Diagnostics.Process] | Get-Member -Private -PrivateMemberType Method
Description
-----------
Returns all non-public instance methods of the Diagnostics.Process class
.EXAMPLE
C:\PS> "Hello, World" | Get-Member -Private -Force
Description
-----------
Returns all instance members including those with special names (like .ctor) of the string instance
.LINK
http://www.exploit-monday.com/2012/08/surgical-net-dissection.html
#>
[CmdletBinding(DefaultParameterSetName = 'Default')]
Param (
[Parameter(ValueFromPipeline=$true, ParameterSetName = 'Default')]
[Parameter(ValueFromPipeline=$true, ParameterSetName = 'Private')]
[System.Management.Automation.PSObject]
$InputObject,
[Parameter(Position=0, ParameterSetName = 'Default')]
[Parameter(Position=0, ParameterSetName = 'Private')]
[ValidateNotNullOrEmpty()]
[System.String[]]
$Name,
[Parameter(ParameterSetName = 'Default')]
[Alias('Type')]
[System.Management.Automation.PSMemberTypes]
$MemberType,
[Parameter(ParameterSetName = 'Private')]
[System.Reflection.MemberTypes]
$PrivateMemberType = [System.Reflection.MemberTypes]::All,
[Parameter(ParameterSetName = 'Default')]
[System.Management.Automation.PSMemberViewTypes]
$View,
[Parameter(ParameterSetName = 'Default')]
[Parameter(ParameterSetName = 'Private')]
[Switch]
$Static,
[Parameter(ParameterSetName = 'Default')]
[Parameter(ParameterSetName = 'Private')]
[Switch]
$Force,
[Parameter(ParameterSetName = 'Private')]
[Switch]
$Private
)
BEGIN
{
try {
$outBuffer = $null
if ($PSBoundParameters.TryGetValue('OutBuffer', [ref]$outBuffer))
{
$PSBoundParameters['OutBuffer'] = 1
}
$wrappedCmd = $ExecutionContext.InvokeCommand.GetCommand('Microsoft.PowerShell.Utility\Get-Member', [System.Management.Automation.CommandTypes]::Cmdlet)
# Redirect the output of the command to $out variable
$null = $PSBoundParameters.Add('OutVariable', 'out')
# Redirect original output to $null
if ($PSBoundParameters['Private']) {
$null = $PSBoundParameters.Remove('Private')
$Private = $True
}
if ($PSBoundParameters['PrivateMemberType']) {
$PrivateMemberType = $PSBoundParameters['PrivateMemberType']
$null = $PSBoundParameters.Remove('PrivateMemberType')
}
$scriptCmd = {& $wrappedCmd @PSBoundParameters | Out-Null }
$steppablePipeline = $scriptCmd.GetSteppablePipeline($myInvocation.CommandOrigin)
$steppablePipeline.Begin($PSCmdlet)
} catch {
}
}
PROCESS
{
try {
$steppablePipeline.Process($_)
} catch {
}
}
END
{
try {
$steppablePipeline.End()
if ($Private) {
$Object = $PSBoundParameters['InputObject']
if ($Object.GetType().FullName -ne 'System.RuntimeType') {
# If InputObject is an instance of an object, get its type
# Otherwise, it's assumed that what was passed in was already a type
$Object = $Object.GetType()
}
if ($PSBoundParameters['Static']) {
$Flags = 'Static, NonPublic'
# Retrieve all static, nonpublic members except for constructors
$Types = foreach ($Val in [Enum]::GetValues([System.Reflection.MemberTypes])) {
$Object.GetMembers($Flags) | Where-Object { ($_.MemberType -eq ($Val.value__ -band $PrivateMemberType)) -and ($Val -ne [System.Reflection.MemberTypes]::All) -and ($_.MemberType -ne 'Constructor') }
}
# Retrieve all static constructors (both public and nonpublic)
# Public constructors are retrieved because the original 'Get-Member -Force' does not retrieve constructors
$Types += $Object.GetConstructors('Static, NonPublic, Public')
} else {
$Flags = 'Instance, NonPublic'
# Retrieve all instance, nonpublic members except for constructors
$Types = foreach ($Val in [Enum]::GetValues([System.Reflection.MemberTypes])) {
$Object.GetMembers($Flags) | Where-Object { ($_.MemberType -eq ($Val.value__ -band $PrivateMemberType)) -and ($Val -ne [System.Reflection.MemberTypes]::All) -and ($_.MemberType -ne 'Constructor') }
}
# Retrieve all instance constructors (both public and nonpublic)
# Public constructors are retrieved because the original 'Get-Member -Force' does not retrieve constructors
$Types += $Object.GetConstructors('Instance, NonPublic, Public')
}
# Filter out types with special names if '-Force' is not specified
if (!$Force) {
$Types = $Types | Where-Object { !$_.IsSpecialName }
}
$TypeTable = @{}
# For each type, build an array of object equivalent to an array of Microsoft.PowerShell.Commands.MemberDefinition objects.
# An array of custom objects is required because the MemberDefinition object doesn't take System.Reflection.MemberTypes
# objects in its constructor.
$Results = $Types | ForEach-Object {
$Type = $_
switch ($Type.MemberType) {
'Constructor' {
$Parameters = ($Type.GetParameters() | % {$_.ParameterType.FullName}) -join ', '
$Definition = "$(if ($Type.IsStatic){'static '})$($Type.Name)($($Parameters))"
}
'Field' {
$Definition = "$(if ($Type.IsStatic){'static '})$($Type.FieldType)"
}
'Method' {
$Parameters = ($Type.GetParameters() | % {$_.ParameterType.FullName}) -join ', '
$Definition = "$(if ($Type.IsStatic){'static '})$($Type.ReturnType) $($Type.Name)($($Parameters))"
}
'Property' {
$Definition = "$(if ($Type.IsStatic){'static '})$($Type.PropertyType) $($Type.Name) {$(if ($Type.CanRead){'get;'})$(if ($Type.CanWrite){'set;'})}"
}
'NestedType' {
$Definition = "$(if ($Type.IsStatic){'static '})$($Type.FullName) BaseType=$($Type.BaseType)"
}
'Event' {
$Parameters = ($Type.GetAddMethod().GetParameters() | % {$_.ParameterType.FullName}) -join ', '
$Definition = "$(if ($Type.IsStatic){'static '})$($Type.EventHandlerType) $($Type.Name)(System.Object, $($Parameters))"
}
}
# Identical properties as the Microsoft.PowerShell.Commands.MemberDefinition object
$InternalMemberType = @{
TypeName = $Type.DeclaringType.FullName
Name = $Type.Name
MemberType = $Type.MemberType
Definition = $Definition
}
New-Object PSObject -Property $InternalMemberType
}
# For members with the same name, compress them into an array that will be stored in a hashtable
$Results | ForEach-Object {
$TypeTable["$($_.Name)"] += @($_)
}
$Results = foreach ($Type in $TypeTable.Keys) {
$ReturnType = @{
TypeName = $TypeTable[$Type][0].TypeName
Name = $TypeTable[$Type][0].Name
MemberType = $TypeTable[$Type][0].MemberType
# Append each definition into a single definition.
# This behavior is indentical to what the unmodified
# Get-Member does.
Definition = ($TypeTable[$Type] | ForEach-Object { $_.Definition }) -join ', '
}
$MemberDef = New-Object PSObject -Property $ReturnType
<#
Cool trick. Even though the custom object is actually a Microsoft.PowerShell.Commands.MemberDefinition
object, you can trick it into thinking it is so that it will display the same way the result of the
original Get-Member cmdlet would.
#>
$MemberDef.PSObject.TypeNames.Insert(0, 'Microsoft.PowerShell.Commands.MemberDefinition')
$MemberDef
}
# If '-Name' parameter is specified, only return members matching the name specified
if ($PSBoundParameters['Name']) {
$MemberNames = [String[]] $PSBoundParameters['Name']
$Tmp = New-Object PSObject[](0)
foreach ($MemberName in $MemberNames) {
$Tmp += $Results | Where-Object { $_.Name -eq $MemberName }
}
$Results = $Tmp
}
# Return the results if the results are non-null
if ($Results.Count) {
$Results | Sort-Object TypeName, MemberType, Name
}
} else {
# If '-Private' is not set, return the results of the original Get-Member cmdlet
$out | Sort-Object TypeName, MemberType, Name
}
} catch {
}
}
}

View File

@ -1,120 +0,0 @@
function Get-MethodAddress
{
<#
.SYNOPSIS
Get the unmanaged function address of a .NET method.
PowerSploit Function: Get-MethodAddress
Author: Matthew Graeber (@mattifestation)
License: BSD 3-Clause
Required Dependencies: None
Optional Dependencies: None
.DESCRIPTION
Get-MethodAddress aids in the process of reverse engineering and exploitation by returning an unmanaged function pointer to any .NET method. This method is useful for those interested in seeing what JITed MSIL opcodes look like in their assembly language representation.
For example, here is the MSIL representation of [System.IntPtr].ToPointer:
0x02 ldarg.0
0x7B,0x53,0x04,0x00,0x04 ldfld void* System.IntPtr::m_value
0x2A ret
After calling Get-MethodAddress and inspecting it in WinDbg, here is the x86_64 ASM representation:
C:\PS> Get-MethodAddress ([IntPtr].GetMethod('ToPointer'))
0x000007FF35544CC0
mscorlib_ni+0xd04cc0:
000007ff`35544cc0 488b01 mov rax,qword ptr [rcx]
000007ff`35544cc3 c3 ret
000007ff`35544cc4 cc int 3
This MSIL to ASM translation makes sense because all the assembly instructions are doing is dereferencing the pointer in rcx.
.PARAMETER MethodInfo
The method whose unmanaged address will be returned.
.EXAMPLE
C:\PS> Get-MethodAddress ([String].GetMethod('Trim', [Type[]]@()))
Description
-----------
Returns the unmanaged address of [System.Object].Trim() method.
.EXAMPLE
C:\PS> [Int].Module.GetTypes().GetMethods() | ForEach-Object {Get-MethodAddress $_ -ErrorAction SilentlyContinue -WarningAction SilentlyContinue}
Description
-----------
Returns an unmanaged address for every method (in which an address can be returned) in mscorlib.
.OUTPUTS
System.String
A hexadecimal representation of the method address.
.NOTES
Not all methods will be able to return an address. For example, methods with implementation flags of AggressiveInlining, Synchronized, or CodeTypeMask will not return an address. Also note that any InternalCall method will return the same pointer every time because the CLR determines its address at runtime.
Lastly, note that the MSIL opcodes used to implement this cmdlet are unverifiable. This means for example, that this technique won't aid exploiting Silverlight applications. :'(
.LINK
http://www.exploit-monday.com/2012/11/Get-MethodAddress.html
#>
[CmdletBinding()] Param (
[Parameter(Mandatory = $True, ValueFromPipeline = $True)]
[System.Reflection.MethodInfo]
$MethodInfo
)
if ($MethodInfo.MethodImplementationFlags -eq 'InternalCall')
{
Write-Warning "$($MethodInfo.Name) is an InternalCall method. These methods always point to the same address."
}
if ([IntPtr]::Size -eq 4)
{
$ReturnType = [UInt32]
}
else
{
$ReturnType = [UInt64]
}
$Domain = [AppDomain]::CurrentDomain
$DynAssembly = New-Object System.Reflection.AssemblyName('MethodLeakAssembly')
# Assemble in memory
$AssemblyBuilder = $Domain.DefineDynamicAssembly($DynAssembly, [System.Reflection.Emit.AssemblyBuilderAccess]::Run)
$ModuleBuilder = $AssemblyBuilder.DefineDynamicModule('MethodLeakModule')
$TypeBuilder = $ModuleBuilder.DefineType('MethodLeaker', [System.Reflection.TypeAttributes]::Public)
# Declaration of the LeakMethod method
$MethodBuilder = $TypeBuilder.DefineMethod('LeakMethod', [System.Reflection.MethodAttributes]::Public -bOr [System.Reflection.MethodAttributes]::Static, $ReturnType, $null)
$Generator = $MethodBuilder.GetILGenerator()
# Push unmanaged pointer to MethodInfo onto the evaluation stack
$Generator.Emit([System.Reflection.Emit.OpCodes]::Ldftn, $MethodInfo)
$Generator.Emit([System.Reflection.Emit.OpCodes]::Ret)
# Assemble everything
$Type = $TypeBuilder.CreateType()
$Method = $Type.GetMethod('LeakMethod')
try
{
# Call the method and return its JITed address
$Address = $Method.Invoke($null, @())
Write-Output (New-Object IntPtr -ArgumentList $Address)
}
catch [System.Management.Automation.MethodInvocationException]
{
Write-Error "$($MethodInfo.Name) cannot return an unmanaged address."
}
}

View File

@ -1,440 +0,0 @@
<?xml version="1.0" encoding="utf-8" ?>
<Configuration>
<ViewDefinitions>
<View>
<Name>SystemModuleView</Name>
<ViewSelectedBy>
<TypeName>_SYSTEM_MODULE</TypeName>
</ViewSelectedBy>
<TableControl>
<AutoSize/>
<TableHeaders>
<TableColumnHeader>
<Label>ImageBaseAddress</Label>
</TableColumnHeader>
<TableColumnHeader>
<Label>ImageSize</Label>
</TableColumnHeader>
<TableColumnHeader>
<Label>Flags</Label>
</TableColumnHeader>
<TableColumnHeader>
<Label>Index</Label>
</TableColumnHeader>
<TableColumnHeader>
<Label>Rank</Label>
</TableColumnHeader>
<TableColumnHeader>
<Label>LoadCount</Label>
</TableColumnHeader>
<TableColumnHeader>
<Label>NameOffset</Label>
</TableColumnHeader>
<TableColumnHeader>
<Label>Name</Label>
</TableColumnHeader>
</TableHeaders>
<TableRowEntries>
<TableRowEntry>
<TableColumnItems>
<TableColumnItem>
<ScriptBlock>"0x$($_.ImageBaseAddress.ToString("X$([IntPtr]::Size * 2)"))"</ScriptBlock>
</TableColumnItem>
<TableColumnItem>
<PropertyName>ImageSize</PropertyName>
<FormatString>0x{0:X8}</FormatString>
</TableColumnItem>
<TableColumnItem>
<PropertyName>Flags</PropertyName>
<FormatString>0x{0:X8}</FormatString>
</TableColumnItem>
<TableColumnItem>
<PropertyName>Index</PropertyName>
<FormatString>0x{0:X4}</FormatString>
</TableColumnItem>
<TableColumnItem>
<PropertyName>Rank</PropertyName>
<FormatString>0x{0:X4}</FormatString>
</TableColumnItem>
<TableColumnItem>
<PropertyName>LoadCount</PropertyName>
<FormatString>0x{0:X4}</FormatString>
</TableColumnItem>
<TableColumnItem>
<PropertyName>NameOffset</PropertyName>
<FormatString>0x{0:X4}</FormatString>
</TableColumnItem>
<TableColumnItem>
<ScriptBlock>$_.Name -replace '\\SystemRoot', $Env:SystemRoot</ScriptBlock>
</TableColumnItem>
</TableColumnItems>
</TableRowEntry>
</TableRowEntries>
</TableControl>
</View>
<View>
<Name>SystemLockView</Name>
<ViewSelectedBy>
<TypeName>_SYSTEM_LOCK_INFORMATION</TypeName>
</ViewSelectedBy>
<TableControl>
<TableHeaders>
<TableColumnHeader>
<Label>Address</Label>
</TableColumnHeader>
<TableColumnHeader>
<Label>Type</Label>
</TableColumnHeader>
<TableColumnHeader>
<Label>ExclusiveOwnerThreadId</Label>
</TableColumnHeader>
<TableColumnHeader>
<Label>ActiveCount</Label>
</TableColumnHeader>
<TableColumnHeader>
<Label>ContentionCount</Label>
</TableColumnHeader>
<TableColumnHeader>
<Label>NumberOfSharedWaiters</Label>
</TableColumnHeader>
<TableColumnHeader>
<Label>NumberOfExclusiveWaiters</Label>
</TableColumnHeader>
</TableHeaders>
<TableRowEntries>
<TableRowEntry>
<TableColumnItems>
<TableColumnItem>
<ScriptBlock>"0x$($_.Address.ToString("X$([IntPtr]::Size * 2)"))"</ScriptBlock>
</TableColumnItem>
<TableColumnItem>
<PropertyName>Type</PropertyName>
<FormatString>0x{0:X4}</FormatString>
</TableColumnItem>
<TableColumnItem>
<PropertyName>ExclusiveOwnerThreadId</PropertyName>
<FormatString>0x{0:X4}</FormatString>
</TableColumnItem>
<TableColumnItem>
<PropertyName>ActiveCount</PropertyName>
<FormatString>0x{0:X8}</FormatString>
</TableColumnItem>
<TableColumnItem>
<PropertyName>ContentionCount</PropertyName>
<FormatString>0x{0:X8}</FormatString>
</TableColumnItem>
<TableColumnItem>
<PropertyName>NumberOfSharedWaiters</PropertyName>
<FormatString>0x{0:X8}</FormatString>
</TableColumnItem>
<TableColumnItem>
<PropertyName>NumberOfExclusiveWaiters</PropertyName>
<FormatString>0x{0:X8}</FormatString>
</TableColumnItem>
</TableColumnItems>
</TableRowEntry>
</TableRowEntries>
</TableControl>
</View>
<View>
<Name>PoolTagView</Name>
<ViewSelectedBy>
<TypeName>_SYSTEM_POOL_TAG_INFORMATION</TypeName>
</ViewSelectedBy>
<TableControl>
<AutoSize/>
<TableHeaders>
<TableColumnHeader>
<Label>Tag</Label>
</TableColumnHeader>
<TableColumnHeader>
<Label>PagedPoolAllocs</Label>
</TableColumnHeader>
<TableColumnHeader>
<Label>PagedPoolFrees</Label>
</TableColumnHeader>
<TableColumnHeader>
<Label>PagedPoolUsage</Label>
</TableColumnHeader>
<TableColumnHeader>
<Label>NonPagedPoolAllocs</Label>
</TableColumnHeader>
<TableColumnHeader>
<Label>NonPagedPoolFrees</Label>
</TableColumnHeader>
<TableColumnHeader>
<Label>NonPagedPoolUsage</Label>
</TableColumnHeader>
</TableHeaders>
<TableRowEntries>
<TableRowEntry>
<TableColumnItems>
<TableColumnItem>
<PropertyName>Tag</PropertyName>
</TableColumnItem>
<TableColumnItem>
<PropertyName>PagedPoolAllocs</PropertyName>
<FormatString>0x{0:X8}</FormatString>
</TableColumnItem>
<TableColumnItem>
<PropertyName>PagedPoolFrees</PropertyName>
<FormatString>0x{0:X8}</FormatString>
</TableColumnItem>
<TableColumnItem>
<PropertyName>PagedPoolUsage</PropertyName>
<FormatString>0x{0:X8}</FormatString>
</TableColumnItem>
<TableColumnItem>
<PropertyName>NonPagedPoolAllocs</PropertyName>
<FormatString>0x{0:X8}</FormatString>
</TableColumnItem>
<TableColumnItem>
<PropertyName>NonPagedPoolFrees</PropertyName>
<FormatString>0x{0:X8}</FormatString>
</TableColumnItem>
<TableColumnItem>
<PropertyName>NonPagedPoolUsage</PropertyName>
<FormatString>0x{0:X8}</FormatString>
</TableColumnItem>
</TableColumnItems>
</TableRowEntry>
</TableRowEntries>
</TableControl>
</View>
<View>
<Name>SystemHandleView</Name>
<ViewSelectedBy>
<TypeName>_SYSTEM_HANDLE_INFORMATION</TypeName>
</ViewSelectedBy>
<TableControl>
<TableHeaders>
<TableColumnHeader>
<Label>UniqueProcessId</Label>
</TableColumnHeader>
<TableColumnHeader>
<Label>CreatorBackTraceIndex</Label>
</TableColumnHeader>
<TableColumnHeader>
<Label>ObjectType</Label>
</TableColumnHeader>
<TableColumnHeader>
<Label>HandleAttribute</Label>
</TableColumnHeader>
<TableColumnHeader>
<Label>HandleValue</Label>
</TableColumnHeader>
<TableColumnHeader>
<Label>Object</Label>
</TableColumnHeader>
<TableColumnHeader>
<Label>GrantedAccess</Label>
</TableColumnHeader>
</TableHeaders>
<TableRowEntries>
<TableRowEntry>
<TableColumnItems>
<TableColumnItem>
<PropertyName>UniqueProcessId</PropertyName>
<FormatString>0x{0:X4}</FormatString>
</TableColumnItem>
<TableColumnItem>
<PropertyName>CreatorBackTraceIndex</PropertyName>
<FormatString>0x{0:X4}</FormatString>
</TableColumnItem>
<TableColumnItem>
<PropertyName>ObjectType</PropertyName>
</TableColumnItem>
<TableColumnItem>
<PropertyName>HandleAttribute</PropertyName>
</TableColumnItem>
<TableColumnItem>
<PropertyName>HandleValue</PropertyName>
<FormatString>0x{0:X4}</FormatString>
</TableColumnItem>
<TableColumnItem>
<ScriptBlock>"0x$($_.Object.ToString("X$([IntPtr]::Size * 2)"))"</ScriptBlock>
</TableColumnItem>
<TableColumnItem>
<PropertyName>GrantedAccess</PropertyName>
</TableColumnItem>
</TableColumnItems>
</TableRowEntry>
</TableRowEntries>
</TableControl>
</View>
<View>
<Name>GenericMappingView</Name>
<ViewSelectedBy>
<TypeName>_GENERIC_MAPPING</TypeName>
</ViewSelectedBy>
<TableControl>
<AutoSize/>
<TableHeaders>
<TableColumnHeader>
<Label>GenericRead</Label>
</TableColumnHeader>
<TableColumnHeader>
<Label>GenericWrite</Label>
</TableColumnHeader>
<TableColumnHeader>
<Label>GenericExecute</Label>
</TableColumnHeader>
<TableColumnHeader>
<Label>GenericAll</Label>
</TableColumnHeader>
</TableHeaders>
<TableRowEntries>
<TableRowEntry>
<TableColumnItems>
<TableColumnItem>
<PropertyName>GenericRead</PropertyName>
<FormatString>0x{0:X8}</FormatString>
</TableColumnItem>
<TableColumnItem>
<PropertyName>GenericWrite</PropertyName>
<FormatString>0x{0:X8}</FormatString>
</TableColumnItem>
<TableColumnItem>
<PropertyName>GenericExecute</PropertyName>
<FormatString>0x{0:X8}</FormatString>
</TableColumnItem>
<TableColumnItem>
<PropertyName>GenericAll</PropertyName>
<FormatString>0x{0:X8}</FormatString>
</TableColumnItem>
</TableColumnItems>
</TableRowEntry>
</TableRowEntries>
</TableControl>
</View>
<View>
<Name>ObjectTypeView</Name>
<ViewSelectedBy>
<TypeName>_SYSTEM_OBJECTTYPE_INFORMATION</TypeName>
</ViewSelectedBy>
<ListControl>
<ListEntries>
<ListEntry>
<ListItems>
<ListItem>
<PropertyName>NumberOfObjects</PropertyName>
<FormatString>0x{0:X8}</FormatString>
</ListItem>
<ListItem>
<PropertyName>NumberOfHandles</PropertyName>
<FormatString>0x{0:X8}</FormatString>
</ListItem>
<ListItem>
<PropertyName>TypeIndex</PropertyName>
<FormatString>0x{0:X8}</FormatString>
</ListItem>
<ListItem>
<PropertyName>InvalidAttributes</PropertyName>
</ListItem>
<ListItem>
<PropertyName>GenericMapping</PropertyName>
</ListItem>
<ListItem>
<PropertyName>ValidAccessMask</PropertyName>
</ListItem>
<ListItem>
<PropertyName>PoolType</PropertyName>
</ListItem>
<ListItem>
<PropertyName>SecurityRequired</PropertyName>
<FormatString>0x{0:X2}</FormatString>
</ListItem>
<ListItem>
<PropertyName>WaitableObject</PropertyName>
<FormatString>0x{0:X2}</FormatString>
</ListItem>
<ListItem>
<PropertyName>TypeName</PropertyName>
</ListItem>
<ListItem>
<PropertyName>Objects</PropertyName>
</ListItem>
</ListItems>
</ListEntry>
</ListEntries>
</ListControl>
</View>
<View>
<Name>ObjectView</Name>
<ViewSelectedBy>
<TypeName>_SYSTEM_OBJECT_INFORMATION</TypeName>
</ViewSelectedBy>
<ListControl>
<ListEntries>
<ListEntry>
<ListItems>
<ListItem>
<Label>Object</Label>
<ScriptBlock>"0x$($_.Object.ToString("X$([IntPtr]::Size * 2)"))"</ScriptBlock>
</ListItem>
<ListItem>
<Label>CreatorUniqueProcess</Label>
<ScriptBlock>"0x$($_.CreatorUniqueProcess.ToString("X$([IntPtr]::Size * 2)"))"</ScriptBlock>
</ListItem>
<ListItem>
<PropertyName>CreatorBackTraceIndex</PropertyName>
<FormatString>0x{0:X4}</FormatString>
</ListItem>
<ListItem>
<PropertyName>Flags</PropertyName>
</ListItem>
<ListItem>
<PropertyName>PointerCount</PropertyName>
<FormatString>0x{0:X8}</FormatString>
</ListItem>
<ListItem>
<PropertyName>HandleCount</PropertyName>
<FormatString>0x{0:X8}</FormatString>
</ListItem>
<ListItem>
<PropertyName>PagedPoolCharge</PropertyName>
<FormatString>0x{0:X8}</FormatString>
</ListItem>
<ListItem>
<PropertyName>NonPagedPoolCharge</PropertyName>
<FormatString>0x{0:X8}</FormatString>
</ListItem>
<ListItem>
<Label>ExclusiveProcessId</Label>
<ScriptBlock>"0x$($_.ExclusiveProcessId.ToString("X$([IntPtr]::Size * 2)"))"</ScriptBlock>
</ListItem>
<ListItem>
<Label>SecurityDescriptor</Label>
<ScriptBlock>"0x$($_.SecurityDescriptor.ToString("X$([IntPtr]::Size * 2)"))"</ScriptBlock>
</ListItem>
<ListItem>
<PropertyName>NameInfo</PropertyName>
</ListItem>
</ListItems>
</ListEntry>
</ListEntries>
</ListControl>
</View>
<View>
<Name>CodeIntegrityTypeView</Name>
<ViewSelectedBy>
<TypeName>_SYSTEM_CODEINTEGRITY_INFORMATION</TypeName>
</ViewSelectedBy>
<ListControl>
<ListEntries>
<ListEntry>
<ListItems>
<ListItem>
<PropertyName>CodeIntegrityOptions</PropertyName>
<FormatString>0x{0:X8}</FormatString>
</ListItem>
<ListItem>
<PropertyName>LockdownState</PropertyName>
</ListItem>
</ListItems>
</ListEntry>
</ListEntries>
</ListControl>
</View>
</ViewDefinitions>
</Configuration>

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -1,98 +0,0 @@
function Get-Strings
{
<#
.SYNOPSIS
Gets strings from a file.
PowerSploit Function: Get-Strings
Author: Matthew Graeber (@mattifestation)
License: BSD 3-Clause
Required Dependencies: None
Optional Dependencies: None
.DESCRIPTION
The Get-Strings cmdlet returns strings (Unicode and/or Ascii) from a file. This cmdlet is useful for dumping strings from binary file and was designed to replicate the functionality of strings.exe from Sysinternals.
.PARAMETER Path
Specifies the path to an item.
.PARAMETER Encoding
Specifies the file encoding. The default value returns both Unicode and Ascii.
.PARAMETER MinimumLength
Specifies the minimum length string to return. The default string length is 3.
.EXAMPLE
C:\PS> Get-Strings C:\Windows\System32\calc.exe
Description
-----------
Dump Unicode and Ascii strings of calc.exe.
.EXAMPLE
C:\PS> Get-ChildItem C:\Windows\System32\*.dll | Get-Strings -MinimumLength 12 -Encoding Ascii
Description
-----------
Dumps Ascii strings of at least length 12 of every dll located in C:\Windows\System32.
.NOTES
This cmdlet was designed to intentionally use only PowerShell cmdlets (no .NET methods) in order to be compatible with PowerShell on Windows RT (or any ConstrainedLanguage runspace).
.LINK
http://www.exploit-monday.com
#>
Param
(
[Parameter(Position = 1, Mandatory = $True, ValueFromPipelineByPropertyName = $True)]
[ValidateNotNullOrEmpty()]
[ValidateScript({Test-Path $_ -PathType 'Leaf'})]
[String[]]
[Alias('PSPath')]
$Path,
[ValidateSet('Default','Ascii','Unicode')]
[String]
$Encoding = 'Default',
[UInt32]
$MinimumLength = 3
)
BEGIN
{
$FileContents = ''
}
PROCESS
{
foreach ($File in $Path)
{
if ($Encoding -eq 'Unicode' -or $Encoding -eq 'Default')
{
$UnicodeFileContents = Get-Content -Encoding 'Unicode' $File
$UnicodeRegex = [Regex] "[\u0020-\u007E]{$MinimumLength,}"
$Results += $UnicodeRegex.Matches($UnicodeFileContents)
}
if ($Encoding -eq 'Ascii' -or $Encoding -eq 'Default')
{
$AsciiFileContents = Get-Content -Encoding 'UTF7' $File
$AsciiRegex = [Regex] "[\x20-\x7E]{$MinimumLength,}"
$Results = $AsciiRegex.Matches($AsciiFileContents)
}
$Results | ForEach-Object { Write-Output $_.Value }
}
}
END {}
}

View File

@ -1,203 +0,0 @@
function Get-StructFromMemory
{
<#
.SYNOPSIS
Marshals data from an unmanaged block of memory in an arbitrary process to a newly allocated managed object of the specified type.
PowerSploit Function: Get-StructFromMemory
Author: Matthew Graeber (@mattifestation)
License: BSD 3-Clause
Required Dependencies: None
Optional Dependencies: None
.DESCRIPTION
Get-StructFromMemory is similar to the Marshal.PtrToStructure method but will parse and return a structure from any process.
.PARAMETER Id
Process ID of the process whose virtual memory space you want to access.
.PARAMETER MemoryAddress
The address containing the structure to be parsed.
.PARAMETER StructType
The type (System.Type) of the desired structure to be parsed.
.EXAMPLE
C:\PS> Get-Process | ForEach-Object { Get-StructFromMemory -Id $_.Id -MemoryAddress $_.MainModule.BaseAddress -StructType ([PE+_IMAGE_DOS_HEADER]) }
Description
-----------
Parses the DOS headers of every loaded process. Note: In this example, this assumes that [PE+_IMAGE_DOS_HEADER] is defined. You can get the code to define [PE+_IMAGE_DOS_HEADER] here: http://www.exploit-monday.com/2012/07/structs-and-enums-using-reflection.html
.NOTES
Be sure to enclose the StructType parameter with parenthesis in order to force PowerShell to cast it as a Type object.
Get-StructFromMemory does a good job with error handling however it will crash if the structure contains fields that attempt to marshal pointers. For example, if a field has a custom attribute of UnmanagedType.LPStr, when the structure is parsed, it will attempt to dererence a string pointer for virtual memory in another process and access violate.
.LINK
http://www.exploit-monday.com
#>
[CmdletBinding()] Param (
[Parameter(Position = 0, Mandatory = $True)]
[Alias('ProcessId')]
[Alias('PID')]
[UInt16]
$Id,
[Parameter(Position = 1, Mandatory = $True)]
[IntPtr]
$MemoryAddress,
[Parameter(Position = 2, Mandatory = $True)]
[Alias('Type')]
[Type]
$StructType
)
Set-StrictMode -Version 2
$PROCESS_VM_READ = 0x0010 # The process permissions we'l ask for when getting a handle to the process
# Get a reference to the private GetProcessHandle method is System.Diagnostics.Process
$GetProcessHandle = [Diagnostics.Process].GetMethod('GetProcessHandle', [Reflection.BindingFlags] 'NonPublic, Instance', $null, @([Int]), $null)
try
{
# Make sure user didn't pass in a non-existent PID
$Process = Get-Process -Id $Id -ErrorVariable GetProcessError
# Get the default process handle
$Handle = $Process.Handle
}
catch [Exception]
{
throw $GetProcessError
}
if ($Handle -eq $null)
{
throw "Unable to obtain a handle for PID $Id. You will likely need to run this script elevated."
}
# Get a reference to MEMORY_BASIC_INFORMATION. I don't feel like making the structure myself
$mscorlib = [AppDomain]::CurrentDomain.GetAssemblies() | ? { $_.FullName.Split(',')[0].ToLower() -eq 'mscorlib' }
$Win32Native = $mscorlib.GetTypes() | ? { $_.FullName -eq 'Microsoft.Win32.Win32Native' }
$MEMORY_BASIC_INFORMATION = $Win32Native.GetNestedType('MEMORY_BASIC_INFORMATION', [Reflection.BindingFlags] 'NonPublic')
if ($MEMORY_BASIC_INFORMATION -eq $null)
{
throw 'Unable to get a reference to the MEMORY_BASIC_INFORMATION structure.'
}
# Get references to private fields in MEMORY_BASIC_INFORMATION
$ProtectField = $MEMORY_BASIC_INFORMATION.GetField('Protect', [Reflection.BindingFlags] 'NonPublic, Instance')
$AllocationBaseField = $MEMORY_BASIC_INFORMATION.GetField('BaseAddress', [Reflection.BindingFlags] 'NonPublic, Instance')
$RegionSizeField = $MEMORY_BASIC_INFORMATION.GetField('RegionSize', [Reflection.BindingFlags] 'NonPublic, Instance')
try { $NativeUtils = [NativeUtils] } catch [Management.Automation.RuntimeException] # Only build the assembly if it hasn't already been defined
{
# Build dynamic assembly in order to use P/Invoke for interacting with the following Win32 functions: ReadProcessMemory, VirtualQueryEx
$DynAssembly = New-Object Reflection.AssemblyName('MemHacker')
$AssemblyBuilder = [AppDomain]::CurrentDomain.DefineDynamicAssembly($DynAssembly, [Reflection.Emit.AssemblyBuilderAccess]::Run)
$ModuleBuilder = $AssemblyBuilder.DefineDynamicModule('MemHacker', $False)
$Attributes = 'AutoLayout, AnsiClass, Class, Public, SequentialLayout, Sealed, BeforeFieldInit'
$TypeBuilder = $ModuleBuilder.DefineType('NativeUtils', $Attributes, [ValueType])
$TypeBuilder.DefinePInvokeMethod('ReadProcessMemory', 'kernel32.dll', [Reflection.MethodAttributes] 'Public, Static', [Reflection.CallingConventions]::Standard, [Bool], @([IntPtr], [IntPtr], [IntPtr], [UInt32], [UInt32].MakeByRefType()), [Runtime.InteropServices.CallingConvention]::Winapi, 'Auto') | Out-Null
$TypeBuilder.DefinePInvokeMethod('VirtualQueryEx', 'kernel32.dll', [Reflection.MethodAttributes] 'Public, Static', [Reflection.CallingConventions]::Standard, [UInt32], @([IntPtr], [IntPtr], $MEMORY_BASIC_INFORMATION.MakeByRefType(), [UInt32]), [Runtime.InteropServices.CallingConvention]::Winapi, 'Auto') | Out-Null
$NativeUtils = $TypeBuilder.CreateType()
}
# Request a handle to the process in interest
try
{
$SafeHandle = $GetProcessHandle.Invoke($Process, @($PROCESS_VM_READ))
$Handle = $SafeHandle.DangerousGetHandle()
}
catch
{
throw $Error[0]
}
# Create an instance of MEMORY_BASIC_INFORMATION
$MemoryBasicInformation = [Activator]::CreateInstance($MEMORY_BASIC_INFORMATION)
# Confirm you can actually read the address you're interested in
$NativeUtils::VirtualQueryEx($Handle, $MemoryAddress, [Ref] $MemoryBasicInformation, [Runtime.InteropServices.Marshal]::SizeOf([Type] $MEMORY_BASIC_INFORMATION)) | Out-Null
$PAGE_EXECUTE_READ = 0x20
$PAGE_EXECUTE_READWRITE = 0x40
$PAGE_READONLY = 2
$PAGE_READWRITE = 4
$Protection = $ProtectField.GetValue($MemoryBasicInformation)
$AllocationBaseOriginal = $AllocationBaseField.GetValue($MemoryBasicInformation)
$GetPointerValue = $AllocationBaseOriginal.GetType().GetMethod('GetPointerValue', [Reflection.BindingFlags] 'NonPublic, Instance')
$AllocationBase = $GetPointerValue.Invoke($AllocationBaseOriginal, $null).ToInt64()
$RegionSize = $RegionSizeField.GetValue($MemoryBasicInformation).ToUInt64()
Write-Verbose "Protection: $Protection"
Write-Verbose "AllocationBase: $AllocationBase"
Write-Verbose "RegionSize: $RegionSize"
if (($Protection -ne $PAGE_READONLY) -and ($Protection -ne $PAGE_READWRITE) -and ($Protection -ne $PAGE_EXECUTE_READ) -and ($Protection -ne $PAGE_EXECUTE_READWRITE))
{
$SafeHandle.Close()
throw 'The address specified does not have read access.'
}
$StructSize = [Runtime.InteropServices.Marshal]::SizeOf([Type] $StructType)
$EndOfAllocation = $AllocationBase + $RegionSize
$EndOfStruct = $MemoryAddress.ToInt64() + $StructSize
if ($EndOfStruct -gt $EndOfAllocation)
{
$SafeHandle.Close()
throw 'You are attempting to read beyond what was allocated.'
}
try
{
# Allocate unmanaged memory. This will be used to store the memory read from ReadProcessMemory
$LocalStructPtr = [Runtime.InteropServices.Marshal]::AllocHGlobal($StructSize)
}
catch [OutOfMemoryException]
{
throw Error[0]
}
Write-Verbose "Memory allocated at 0x$($LocalStructPtr.ToString("X$([IntPtr]::Size * 2)"))"
# Zero out the memory that was just allocated. According to MSDN documentation:
# "When AllocHGlobal calls LocalAlloc, it passes a LMEM_FIXED flag, which causes the allocated memory to be locked in place. Also, the allocated memory is not zero-filled."
# http://msdn.microsoft.com/en-us/library/s69bkh17.aspx
$ZeroBytes = New-Object Byte[]($StructSize)
[Runtime.InteropServices.Marshal]::Copy($ZeroBytes, 0, $LocalStructPtr, $StructSize)
$BytesRead = [UInt32] 0
if ($NativeUtils::ReadProcessMemory($Handle, $MemoryAddress, $LocalStructPtr, $StructSize, [Ref] $BytesRead))
{
$SafeHandle.Close()
[Runtime.InteropServices.Marshal]::FreeHGlobal($LocalStructPtr)
throw ([ComponentModel.Win32Exception][Runtime.InteropServices.Marshal]::GetLastWin32Error())
}
Write-Verbose "Struct Size: $StructSize"
Write-Verbose "Bytes read: $BytesRead"
$ParsedStruct = [Runtime.InteropServices.Marshal]::PtrToStructure($LocalStructPtr, [Type] $StructType)
[Runtime.InteropServices.Marshal]::FreeHGlobal($LocalStructPtr)
$SafeHandle.Close()
Write-Output $ParsedStruct
}

View File

@ -1,36 +0,0 @@
<?xml version="1.0" encoding="utf-8" ?>
<Configuration>
<ViewDefinitions>
<View>
<Name>ProcessModuleTraceView</Name>
<ViewSelectedBy>
<TypeName>LOADED_MODULE</TypeName>
</ViewSelectedBy>
<ListControl>
<ListEntries>
<ListEntry>
<ListItems>
<ListItem>
<PropertyName>TimeCreated</PropertyName>
</ListItem>
<ListItem>
<PropertyName>ProcessId</PropertyName>
</ListItem>
<ListItem>
<PropertyName>FileName</PropertyName>
</ListItem>
<ListItem>
<Label>ImageBase</Label>
<ScriptBlock>"0x$($_.ImageBase.ToString("X$([IntPtr]::Size * 2)"))"</ScriptBlock>
</ListItem>
<ListItem>
<PropertyName>ImageSize</PropertyName>
<FormatString>0x{0:X8}</FormatString>
</ListItem>
</ListItems>
</ListEntry>
</ListEntries>
</ListControl>
</View>
</ViewDefinitions>
</Configuration>

View File

@ -1,103 +0,0 @@
function Register-ProcessModuleTrace
{
<#
.SYNOPSIS
Starts a trace of loaded process modules
PowerSploit Function: Register-ProcessModuleTrace
Author: Matthew Graeber (@mattifestation)
License: BSD 3-Clause
Required Dependencies: None
Optional Dependencies: None
.OUTPUTS
System.Management.Automation.PSEventJob
If desired, you can manipulate the event returned with the *-Event cmdlets.
.LINK
http://www.exploit-monday.com/
#>
[CmdletBinding()] Param ()
if (-not ([Security.Principal.WindowsPrincipal] [Security.Principal.WindowsIdentity]::GetCurrent()).IsInRole([Security.Principal.WindowsBuiltInRole] 'Administrator'))
{
throw 'You must run this cmdlet from an elevated PowerShell session.'
}
$ModuleLoadedAction = {
$Event = $EventArgs.NewEvent
$ModuleInfo = @{
TimeCreated = [DateTime]::FromFileTime($Event.TIME_CREATED)
ProcessId = $Event.ProcessId
FileName = $Event.FileName
ImageBase = $Event.ImageBase
ImageSize = $Event.ImageSize
}
$ModuleObject = New-Object PSObject -Property $ModuleInfo
$ModuleObject.PSObject.TypeNames[0] = 'LOADED_MODULE'
$ModuleObject
}
Register-WmiEvent 'Win32_ModuleLoadTrace' -SourceIdentifier 'ModuleLoaded' -Action $ModuleLoadedAction
}
function Get-ProcessModuleTrace
{
<#
.SYNOPSIS
Displays the process modules that have been loaded since the call to Register-ProcessModuleTrace
PowerSploit Function: Get-ProcessModuleTrace
Author: Matthew Graeber (@mattifestation)
License: BSD 3-Clause
Required Dependencies: Register-ProcessModuleTrace
Optional Dependencies: None
.OUTPUTS
PSObject
.LINK
http://www.exploit-monday.com/
#>
$Events = Get-EventSubscriber -SourceIdentifier 'ModuleLoaded' -ErrorVariable NoEventRegistered -ErrorAction SilentlyContinue
if ($NoEventRegistered)
{
throw 'You must execute Register-ProcessModuleTrace before you can retrieve a loaded module list'
}
$Events.Action.Output
}
function Unregister-ProcessModuleTrace
{
<#
.SYNOPSIS
Stops the running process module trace
PowerSploit Function: Unregister-ProcessModuleTrace
Author: Matthew Graeber (@mattifestation)
License: BSD 3-Clause
Required Dependencies: Register-ProcessModuleTrace
Optional Dependencies: None
.LINK
http://www.exploit-monday.com/
#>
Unregister-Event -SourceIdentifier 'ModuleLoaded'
}

View File

@ -1,91 +0,0 @@
@{
# Script module or binary module file associated with this manifest.
ModuleToProcess = 'ReverseEngineering.psm1'
# Version number of this module.
ModuleVersion = '1.0.0.0'
# ID used to uniquely identify this module
GUID = 'cbffaf47-c55a-4901-92e7-8d794fbe1fff'
# 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 Reverse Engineering 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 = 'Get-PEB.format.ps1xml', 'Get-NtSystemInformation.format.ps1xml', 'Get-ILDisassembly.format.ps1xml', 'ProcessModuleTrace.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 = 'ReverseEngineering'; ModuleVersion = '1.0.0.0'; GUID = 'cbffaf47-c55a-4901-92e7-8d794fbe1fff'})
# List of all files packaged with this module
FileList = 'ReverseEngineering.psm1', 'ReverseEngineering.psd1', 'Get-ILDisassembly.ps1', 'Get-NtSystemInformation.format.ps1xml',
'Get-NtSystemInformation.ps1', 'Get-Member.ps1', 'Get-MethodAddress.ps1', 'Get-PEB.format.ps1xml',
'Get-PEB.ps1', 'Get-Strings.ps1', 'Get-StructFromMemory.ps1', 'ConvertTo-String.ps1',
'Get-Entropy.ps1', 'Get-ILDisassembly.format.ps1xml', 'ProcessModuleTrace.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 = ''
}

View File

@ -1 +0,0 @@
Get-ChildItem (Join-Path $PSScriptRoot *.ps1) | % { . $_.FullName}

View File

@ -1,12 +0,0 @@
To install this module, drop the entire ReverseEngineering 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 ReverseEngineering`
To see the commands imported, type `Get-Command -Module ReverseEngineering`
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.