diff options
Diffstat (limited to 'ReverseEngineering/Get-ILDisassembly.ps1')
-rw-r--r-- | ReverseEngineering/Get-ILDisassembly.ps1 | 215 |
1 files changed, 0 insertions, 215 deletions
diff --git a/ReverseEngineering/Get-ILDisassembly.ps1 b/ReverseEngineering/Get-ILDisassembly.ps1 deleted file mode 100644 index 6948919..0000000 --- a/ReverseEngineering/Get-ILDisassembly.ps1 +++ /dev/null @@ -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
- }
-}
|