xref: /aosp_15_r20/external/capstone/bindings/powershell/Capstone/Capstone.psm1 (revision 9a0e4156d50a75a99ec4f1653a0e9602a5d45c18)
1*9a0e4156SSadaf Ebrahimi <#
2*9a0e4156SSadaf Ebrahimi .SYNOPSIS
3*9a0e4156SSadaf Ebrahimi     Get Capstone version as Version object
4*9a0e4156SSadaf Ebrahimi #>
Get-CapstoneVersionnull5*9a0e4156SSadaf Ebrahimi function Get-CapstoneVersion {
6*9a0e4156SSadaf Ebrahimi     $Version = [System.BitConverter]::GetBytes(
7*9a0e4156SSadaf Ebrahimi         [Capstone]::cs_version($null, $null)
8*9a0e4156SSadaf Ebrahimi     )
9*9a0e4156SSadaf Ebrahimi 
10*9a0e4156SSadaf Ebrahimi     New-Object -TypeName version -ArgumentList @(
11*9a0e4156SSadaf Ebrahimi         $Version[1]
12*9a0e4156SSadaf Ebrahimi         $Version[0]
13*9a0e4156SSadaf Ebrahimi         0
14*9a0e4156SSadaf Ebrahimi         0
15*9a0e4156SSadaf Ebrahimi     )
16*9a0e4156SSadaf Ebrahimi }
17*9a0e4156SSadaf Ebrahimi 
18*9a0e4156SSadaf Ebrahimi <#
19*9a0e4156SSadaf Ebrahimi .SYNOPSIS
20*9a0e4156SSadaf Ebrahimi     Create C# bindings for capstone.dll
21*9a0e4156SSadaf Ebrahimi 
22*9a0e4156SSadaf Ebrahimi .PARAMETER DllPath
23*9a0e4156SSadaf Ebrahimi     Path to capstone.dll
24*9a0e4156SSadaf Ebrahimi #>
Initialize-Capstone()25*9a0e4156SSadaf Ebrahimi function Initialize-Capstone {
26*9a0e4156SSadaf Ebrahimi     [CmdletBinding()]
27*9a0e4156SSadaf Ebrahimi     Param (
28*9a0e4156SSadaf Ebrahimi         [Parameter(Mandatory = $true)]
29*9a0e4156SSadaf Ebrahimi         [ValidateScript( {
30*9a0e4156SSadaf Ebrahimi                 try {
31*9a0e4156SSadaf Ebrahimi                     Test-Path -Path $_ -PathType Leaf -ErrorAction Stop
32*9a0e4156SSadaf Ebrahimi                 } catch {
33*9a0e4156SSadaf Ebrahimi                     throw "Capstone DLL is missing: $DllPath"
34*9a0e4156SSadaf Ebrahimi                 }
35*9a0e4156SSadaf Ebrahimi             })]
36*9a0e4156SSadaf Ebrahimi         [ValidateNotNullOrEmpty()]
37*9a0e4156SSadaf Ebrahimi         [string]$DllPath
38*9a0e4156SSadaf Ebrahimi     )
39*9a0e4156SSadaf Ebrahimi 
40*9a0e4156SSadaf Ebrahimi     # Escape path for use in inline C#
41*9a0e4156SSadaf Ebrahimi     $DllPath = $DllPath.Replace('\', '\\')
42*9a0e4156SSadaf Ebrahimi 
43*9a0e4156SSadaf Ebrahimi     # Inline C# to parse the unmanaged capstone DLL
44*9a0e4156SSadaf Ebrahimi     # http://stackoverflow.com/questions/16552801/how-do-i-conditionally-add-a-class-with-add-type-typedefinition-if-it-isnt-add
45*9a0e4156SSadaf Ebrahimi     if (-not ([System.Management.Automation.PSTypeName]'Capstone').Type) {
46*9a0e4156SSadaf Ebrahimi         Add-Type -TypeDefinition @"
47*9a0e4156SSadaf Ebrahimi         using System;
48*9a0e4156SSadaf Ebrahimi         using System.Diagnostics;
49*9a0e4156SSadaf Ebrahimi         using System.Runtime.InteropServices;
50*9a0e4156SSadaf Ebrahimi         using System.Security.Principal;
51*9a0e4156SSadaf Ebrahimi 
52*9a0e4156SSadaf Ebrahimi         [StructLayout(LayoutKind.Sequential)]
53*9a0e4156SSadaf Ebrahimi         public struct cs_insn
54*9a0e4156SSadaf Ebrahimi         {
55*9a0e4156SSadaf Ebrahimi             public uint id;
56*9a0e4156SSadaf Ebrahimi             public ulong address;
57*9a0e4156SSadaf Ebrahimi             public ushort size;
58*9a0e4156SSadaf Ebrahimi             [MarshalAs(UnmanagedType.ByValArray, SizeConst = 24)]
59*9a0e4156SSadaf Ebrahimi             public byte[] bytes;
60*9a0e4156SSadaf Ebrahimi             [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 32)]
61*9a0e4156SSadaf Ebrahimi             public string mnemonic;
62*9a0e4156SSadaf Ebrahimi             [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 160)]
63*9a0e4156SSadaf Ebrahimi             public string operands;
64*9a0e4156SSadaf Ebrahimi             public IntPtr detail;
65*9a0e4156SSadaf Ebrahimi         }
66*9a0e4156SSadaf Ebrahimi 
67*9a0e4156SSadaf Ebrahimi         /// Partial, only architecture-independent internal data
68*9a0e4156SSadaf Ebrahimi         [StructLayout(LayoutKind.Sequential)]
69*9a0e4156SSadaf Ebrahimi         public struct cs_detail
70*9a0e4156SSadaf Ebrahimi         {
71*9a0e4156SSadaf Ebrahimi             [MarshalAs(UnmanagedType.ByValArray, SizeConst = 16)]
72*9a0e4156SSadaf Ebrahimi             public byte[] regs_read;
73*9a0e4156SSadaf Ebrahimi             public byte regs_read_count;
74*9a0e4156SSadaf Ebrahimi             [MarshalAs(UnmanagedType.ByValArray, SizeConst = 20)]
75*9a0e4156SSadaf Ebrahimi             public byte[] regs_write;
76*9a0e4156SSadaf Ebrahimi             public byte regs_write_count;
77*9a0e4156SSadaf Ebrahimi             [MarshalAs(UnmanagedType.ByValArray, SizeConst = 8)]
78*9a0e4156SSadaf Ebrahimi             public byte[] groups;
79*9a0e4156SSadaf Ebrahimi             public byte groups_count;
80*9a0e4156SSadaf Ebrahimi         }
81*9a0e4156SSadaf Ebrahimi 
82*9a0e4156SSadaf Ebrahimi         public enum cs_err : int
83*9a0e4156SSadaf Ebrahimi         {
84*9a0e4156SSadaf Ebrahimi             CS_ERR_OK = 0,    /// No error: everything was fine
85*9a0e4156SSadaf Ebrahimi             CS_ERR_MEM,       /// Out-Of-Memory error: cs_open(), cs_disasm(), cs_disasm_iter()
86*9a0e4156SSadaf Ebrahimi             CS_ERR_ARCH,      /// Unsupported architecture: cs_open()
87*9a0e4156SSadaf Ebrahimi             CS_ERR_HANDLE,    /// Invalid handle: cs_op_count(), cs_op_index()
88*9a0e4156SSadaf Ebrahimi             CS_ERR_CSH,       /// Invalid csh argument: cs_close(), cs_errno(), cs_option()
89*9a0e4156SSadaf Ebrahimi             CS_ERR_MODE,      /// Invalid/unsupported mode: cs_open()
90*9a0e4156SSadaf Ebrahimi             CS_ERR_OPTION,    /// Invalid/unsupported option: cs_option()
91*9a0e4156SSadaf Ebrahimi             CS_ERR_DETAIL,    /// Information is unavailable because detail option is OFF
92*9a0e4156SSadaf Ebrahimi             CS_ERR_MEMSETUP,  /// Dynamic memory management uninitialized (see CS_OPT_MEM)
93*9a0e4156SSadaf Ebrahimi             CS_ERR_VERSION,   /// Unsupported version (bindings)
94*9a0e4156SSadaf Ebrahimi             CS_ERR_DIET,      /// Access irrelevant data in "diet" engine
95*9a0e4156SSadaf Ebrahimi             CS_ERR_SKIPDATA,  /// Access irrelevant data for "data" instruction in SKIPDATA mode
96*9a0e4156SSadaf Ebrahimi             CS_ERR_X86_ATT,   /// X86 AT&T syntax is unsupported (opt-out at compile time)
97*9a0e4156SSadaf Ebrahimi             CS_ERR_X86_INTEL, /// X86 Intel syntax is unsupported (opt-out at compile time)
98*9a0e4156SSadaf Ebrahimi         }
99*9a0e4156SSadaf Ebrahimi         public enum cs_arch : int
100*9a0e4156SSadaf Ebrahimi         {
101*9a0e4156SSadaf Ebrahimi             CS_ARCH_ARM = 0,      /// ARM architecture (including Thumb, Thumb-2)
102*9a0e4156SSadaf Ebrahimi             CS_ARCH_ARM64,        /// ARM-64, also called AArch64
103*9a0e4156SSadaf Ebrahimi             CS_ARCH_MIPS,         /// Mips architecture
104*9a0e4156SSadaf Ebrahimi             CS_ARCH_X86,          /// X86 architecture (including x86 & x86-64)
105*9a0e4156SSadaf Ebrahimi             CS_ARCH_PPC,          /// PowerPC architecture
106*9a0e4156SSadaf Ebrahimi             CS_ARCH_SPARC,        /// Sparc architecture
107*9a0e4156SSadaf Ebrahimi             CS_ARCH_SYSZ,         /// SystemZ architecture
108*9a0e4156SSadaf Ebrahimi             CS_ARCH_XCORE,        /// XCore architecture
109*9a0e4156SSadaf Ebrahimi             CS_ARCH_MAX,
110*9a0e4156SSadaf Ebrahimi             CS_ARCH_ALL = 0xFFFF, /// All architectures - for cs_support()
111*9a0e4156SSadaf Ebrahimi         }
112*9a0e4156SSadaf Ebrahimi         public enum cs_mode : int
113*9a0e4156SSadaf Ebrahimi         {
114*9a0e4156SSadaf Ebrahimi             CS_MODE_LITTLE_ENDIAN = 0,    /// little-endian mode (default mode)
115*9a0e4156SSadaf Ebrahimi             CS_MODE_ARM = 0,              /// 32-bit ARM
116*9a0e4156SSadaf Ebrahimi             CS_MODE_16 = 1 << 1,          /// 16-bit mode (X86)
117*9a0e4156SSadaf Ebrahimi             CS_MODE_32 = 1 << 2,          /// 32-bit mode (X86)
118*9a0e4156SSadaf Ebrahimi             CS_MODE_64 = 1 << 3,          /// 64-bit mode (X86, PPC)
119*9a0e4156SSadaf Ebrahimi             CS_MODE_THUMB = 1 << 4,       /// ARM's Thumb mode, including Thumb-2
120*9a0e4156SSadaf Ebrahimi             CS_MODE_MCLASS = 1 << 5,      /// ARM's Cortex-M series
121*9a0e4156SSadaf Ebrahimi             CS_MODE_V8 = 1 << 6,          /// ARMv8 A32 encodings for ARM
122*9a0e4156SSadaf Ebrahimi             CS_MODE_MICRO = 1 << 4,       /// MicroMips mode (MIPS)
123*9a0e4156SSadaf Ebrahimi             CS_MODE_MIPS3 = 1 << 5,       /// Mips III ISA
124*9a0e4156SSadaf Ebrahimi             CS_MODE_MIPS32R6 = 1 << 6,    /// Mips32r6 ISA
125*9a0e4156SSadaf Ebrahimi             CS_MODE_MIPSGP64 = 1 << 7,    /// General Purpose Registers are 64-bit wide (MIPS)
126*9a0e4156SSadaf Ebrahimi             CS_MODE_V9 = 1 << 4,          /// SparcV9 mode (Sparc)
127*9a0e4156SSadaf Ebrahimi             CS_MODE_BIG_ENDIAN = 1 << 31, /// big-endian mode
128*9a0e4156SSadaf Ebrahimi             CS_MODE_MIPS32 = CS_MODE_32,  /// Mips32 ISA (Mips)
129*9a0e4156SSadaf Ebrahimi             CS_MODE_MIPS64 = CS_MODE_64,  /// Mips64 ISA (Mips)
130*9a0e4156SSadaf Ebrahimi         }
131*9a0e4156SSadaf Ebrahimi 
132*9a0e4156SSadaf Ebrahimi         public static class Capstone
133*9a0e4156SSadaf Ebrahimi         {
134*9a0e4156SSadaf Ebrahimi             [DllImport("$DllPath")]
135*9a0e4156SSadaf Ebrahimi             public static extern cs_err cs_open(
136*9a0e4156SSadaf Ebrahimi                 cs_arch arch,
137*9a0e4156SSadaf Ebrahimi                 cs_mode mode,
138*9a0e4156SSadaf Ebrahimi                 ref IntPtr handle);
139*9a0e4156SSadaf Ebrahimi 
140*9a0e4156SSadaf Ebrahimi             [DllImport("$DllPath")]
141*9a0e4156SSadaf Ebrahimi             public static extern UInt32 cs_disasm(
142*9a0e4156SSadaf Ebrahimi                 IntPtr handle,
143*9a0e4156SSadaf Ebrahimi                 byte[] code,
144*9a0e4156SSadaf Ebrahimi                 int code_size,
145*9a0e4156SSadaf Ebrahimi                 ulong address,
146*9a0e4156SSadaf Ebrahimi                 int count,
147*9a0e4156SSadaf Ebrahimi                 ref IntPtr insn);
148*9a0e4156SSadaf Ebrahimi 
149*9a0e4156SSadaf Ebrahimi             [DllImport("$DllPath")]
150*9a0e4156SSadaf Ebrahimi             public static extern bool cs_free(
151*9a0e4156SSadaf Ebrahimi                 IntPtr insn,
152*9a0e4156SSadaf Ebrahimi                 int count);
153*9a0e4156SSadaf Ebrahimi 
154*9a0e4156SSadaf Ebrahimi             [DllImport("$DllPath")]
155*9a0e4156SSadaf Ebrahimi             public static extern cs_err cs_close(
156*9a0e4156SSadaf Ebrahimi                 ref IntPtr handle);
157*9a0e4156SSadaf Ebrahimi 
158*9a0e4156SSadaf Ebrahimi             [DllImport("$DllPath")]
159*9a0e4156SSadaf Ebrahimi             public static extern cs_err cs_option(
160*9a0e4156SSadaf Ebrahimi                 IntPtr handle,
161*9a0e4156SSadaf Ebrahimi                 int type,
162*9a0e4156SSadaf Ebrahimi                 int value);
163*9a0e4156SSadaf Ebrahimi 
164*9a0e4156SSadaf Ebrahimi             [DllImport("$DllPath", CallingConvention = CallingConvention.Cdecl)]
165*9a0e4156SSadaf Ebrahimi             public static extern IntPtr cs_reg_name(
166*9a0e4156SSadaf Ebrahimi                 IntPtr handle,
167*9a0e4156SSadaf Ebrahimi                 uint reg_id);
168*9a0e4156SSadaf Ebrahimi 
169*9a0e4156SSadaf Ebrahimi             [DllImport("$DllPath")]
170*9a0e4156SSadaf Ebrahimi             public static extern int cs_version(
171*9a0e4156SSadaf Ebrahimi                 uint major,
172*9a0e4156SSadaf Ebrahimi                 uint minor);
173*9a0e4156SSadaf Ebrahimi         }
174*9a0e4156SSadaf Ebrahimi "@
175*9a0e4156SSadaf Ebrahimi     } else {
176*9a0e4156SSadaf Ebrahimi         Write-Verbose 'C# bindings are already compiled'
177*9a0e4156SSadaf Ebrahimi     }
178*9a0e4156SSadaf Ebrahimi }
179*9a0e4156SSadaf Ebrahimi 
Get-CapstoneDisassembly()180*9a0e4156SSadaf Ebrahimi function Get-CapstoneDisassembly {
181*9a0e4156SSadaf Ebrahimi <#
182*9a0e4156SSadaf Ebrahimi .SYNOPSIS
183*9a0e4156SSadaf Ebrahimi     Powershell wrapper for Capstone (using inline C#).
184*9a0e4156SSadaf Ebrahimi 
185*9a0e4156SSadaf Ebrahimi .DESCRIPTION
186*9a0e4156SSadaf Ebrahimi     Author: Ruben Boonen (@FuzzySec), @beatcracker
187*9a0e4156SSadaf Ebrahimi     License: BSD 3-Clause
188*9a0e4156SSadaf Ebrahimi     Required Dependencies: None
189*9a0e4156SSadaf Ebrahimi     Optional Dependencies: None
190*9a0e4156SSadaf Ebrahimi 
191*9a0e4156SSadaf Ebrahimi .PARAMETER Architecture
192*9a0e4156SSadaf Ebrahimi     Architecture type.
193*9a0e4156SSadaf Ebrahimi 
194*9a0e4156SSadaf Ebrahimi .PARAMETER Mode
195*9a0e4156SSadaf Ebrahimi     Mode type.
196*9a0e4156SSadaf Ebrahimi 
197*9a0e4156SSadaf Ebrahimi .PARAMETER Bytes
198*9a0e4156SSadaf Ebrahimi     Byte array to be disassembled.
199*9a0e4156SSadaf Ebrahimi 
200*9a0e4156SSadaf Ebrahimi .PARAMETER Syntax
201*9a0e4156SSadaf Ebrahimi     Syntax for output assembly.
202*9a0e4156SSadaf Ebrahimi 
203*9a0e4156SSadaf Ebrahimi .PARAMETER Address
204*9a0e4156SSadaf Ebrahimi     Assign address for the first instruction to be disassembled.
205*9a0e4156SSadaf Ebrahimi 
206*9a0e4156SSadaf Ebrahimi .PARAMETER Detailed
207*9a0e4156SSadaf Ebrahimi     Return detailed output.
208*9a0e4156SSadaf Ebrahimi 
209*9a0e4156SSadaf Ebrahimi .PARAMETER Version
210*9a0e4156SSadaf Ebrahimi     Print ASCII version banner.
211*9a0e4156SSadaf Ebrahimi 
212*9a0e4156SSadaf Ebrahimi .EXAMPLE
213*9a0e4156SSadaf Ebrahimi 
214*9a0e4156SSadaf Ebrahimi     C:\PS> $Bytes = [byte[]] @( 0x10, 0xf1, 0x10, 0xe7, 0x11, 0xf2, 0x31, 0xe7, 0xdc, 0xa1, 0x2e, 0xf3, 0xe8, 0x4e, 0x62, 0xf3 )
215*9a0e4156SSadaf Ebrahimi     C:\PS> Get-CapstoneDisassembly -Architecture CS_ARCH_ARM -Mode CS_MODE_ARM -Bytes $Bytes
216*9a0e4156SSadaf Ebrahimi 
217*9a0e4156SSadaf Ebrahimi     Address     : 0x100000
218*9a0e4156SSadaf Ebrahimi     Instruction : sdiv r0, r0, r1
219*9a0e4156SSadaf Ebrahimi 
220*9a0e4156SSadaf Ebrahimi     Address     : 0x100004
221*9a0e4156SSadaf Ebrahimi     Instruction : udiv r1, r1, r2
222*9a0e4156SSadaf Ebrahimi 
223*9a0e4156SSadaf Ebrahimi     Address     : 0x100008
224*9a0e4156SSadaf Ebrahimi     Instruction : vbit q5, q15, q6
225*9a0e4156SSadaf Ebrahimi 
226*9a0e4156SSadaf Ebrahimi     Address     : 0x10000C
227*9a0e4156SSadaf Ebrahimi     Instruction : vcgt.f32 q10, q9, q12
228*9a0e4156SSadaf Ebrahimi 
229*9a0e4156SSadaf Ebrahimi .EXAMPLE
230*9a0e4156SSadaf Ebrahimi 
231*9a0e4156SSadaf Ebrahimi     # Detailed mode & ATT syntax
232*9a0e4156SSadaf Ebrahimi     C:\PS> $Bytes = [byte[]] @( 0xB8, 0x0A, 0x00, 0x00, 0x00, 0xF7, 0xF3 )
233*9a0e4156SSadaf Ebrahimi     C:\PS> Get-CapstoneDisassembly -Architecture CS_ARCH_X86 -Mode CS_MODE_32 -Bytes $Bytes -Syntax ATT -Detailed
234*9a0e4156SSadaf Ebrahimi 
235*9a0e4156SSadaf Ebrahimi     Address  : 0x100000
236*9a0e4156SSadaf Ebrahimi     Mnemonic : movl
237*9a0e4156SSadaf Ebrahimi     Operands : $0xa, %eax
238*9a0e4156SSadaf Ebrahimi     Bytes    : {184, 10, 0, 0...}
239*9a0e4156SSadaf Ebrahimi     Size     : 5
240*9a0e4156SSadaf Ebrahimi     RegRead  :
241*9a0e4156SSadaf Ebrahimi     RegWrite :
242*9a0e4156SSadaf Ebrahimi 
243*9a0e4156SSadaf Ebrahimi     Address  : 0x100005
244*9a0e4156SSadaf Ebrahimi     Mnemonic : divl
245*9a0e4156SSadaf Ebrahimi     Operands : %ebx
246*9a0e4156SSadaf Ebrahimi     Bytes    : {247, 243}
247*9a0e4156SSadaf Ebrahimi     Size     : 2
248*9a0e4156SSadaf Ebrahimi     RegRead  : {eax, edx}
249*9a0e4156SSadaf Ebrahimi     RegWrite : {eax, edx, eflags}
250*9a0e4156SSadaf Ebrahimi 
251*9a0e4156SSadaf Ebrahimi .EXAMPLE
252*9a0e4156SSadaf Ebrahimi 
253*9a0e4156SSadaf Ebrahimi     # Get-CapstoneDisassembly emits objects
254*9a0e4156SSadaf Ebrahimi     C:\PS> $Bytes = [byte[]] @( 0xB8, 0x0A, 0x00, 0x00, 0x00, 0xF7, 0xF3 )
255*9a0e4156SSadaf Ebrahimi     C:\PS> $Object = Get-CapstoneDisassembly -Architecture CS_ARCH_X86 -Mode CS_MODE_32 -Bytes $Bytes -Detailed
256*9a0e4156SSadaf Ebrahimi     C:\PS> $Object | Select-Object -Property Size, Mnemonic, Operands
257*9a0e4156SSadaf Ebrahimi 
258*9a0e4156SSadaf Ebrahimi     Size Mnemonic Operands
259*9a0e4156SSadaf Ebrahimi     ---- -------- --------
260*9a0e4156SSadaf Ebrahimi     5 mov      eax, 0xa
261*9a0e4156SSadaf Ebrahimi     2 div      ebx
262*9a0e4156SSadaf Ebrahimi #>
263*9a0e4156SSadaf Ebrahimi     [CmdletBinding(DefaultParameterSetName = 'Capstone')]
264*9a0e4156SSadaf Ebrahimi     Param (
265*9a0e4156SSadaf Ebrahimi         [Parameter(ParameterSetName = 'Capstone', Mandatory = $true)]
266*9a0e4156SSadaf Ebrahimi         [ValidateSet(
267*9a0e4156SSadaf Ebrahimi             'CS_ARCH_ARM',
268*9a0e4156SSadaf Ebrahimi             'CS_ARCH_ARM64',
269*9a0e4156SSadaf Ebrahimi             'CS_ARCH_MIPS',
270*9a0e4156SSadaf Ebrahimi             'CS_ARCH_X86',
271*9a0e4156SSadaf Ebrahimi             'CS_ARCH_PPC',
272*9a0e4156SSadaf Ebrahimi             'CS_ARCH_SPARC',
273*9a0e4156SSadaf Ebrahimi             'CS_ARCH_SYSZ',
274*9a0e4156SSadaf Ebrahimi             'CS_ARCH_XCORE',
275*9a0e4156SSadaf Ebrahimi             'CS_ARCH_MAX',
276*9a0e4156SSadaf Ebrahimi             'CS_ARCH_ALL'
277*9a0e4156SSadaf Ebrahimi         )]
278*9a0e4156SSadaf Ebrahimi         [string]$Architecture,
279*9a0e4156SSadaf Ebrahimi 
280*9a0e4156SSadaf Ebrahimi         [Parameter(ParameterSetName = 'Capstone', Mandatory = $true)]
281*9a0e4156SSadaf Ebrahimi         [ValidateSet(
282*9a0e4156SSadaf Ebrahimi             'CS_MODE_LITTLE_ENDIAN',
283*9a0e4156SSadaf Ebrahimi             'CS_MODE_ARM',
284*9a0e4156SSadaf Ebrahimi             'CS_MODE_16',
285*9a0e4156SSadaf Ebrahimi             'CS_MODE_32',
286*9a0e4156SSadaf Ebrahimi             'CS_MODE_64',
287*9a0e4156SSadaf Ebrahimi             'CS_MODE_THUMB',
288*9a0e4156SSadaf Ebrahimi             'CS_MODE_MCLASS',
289*9a0e4156SSadaf Ebrahimi             'CS_MODE_V8',
290*9a0e4156SSadaf Ebrahimi             'CS_MODE_MICRO',
291*9a0e4156SSadaf Ebrahimi             'CS_MODE_MIPS3',
292*9a0e4156SSadaf Ebrahimi             'CS_MODE_MIPS32R6',
293*9a0e4156SSadaf Ebrahimi             'CS_MODE_MIPSGP64',
294*9a0e4156SSadaf Ebrahimi             'CS_MODE_V9',
295*9a0e4156SSadaf Ebrahimi             'CS_MODE_BIG_ENDIAN',
296*9a0e4156SSadaf Ebrahimi             'CS_MODE_MIPS32',
297*9a0e4156SSadaf Ebrahimi             'CS_MODE_MIPS64'
298*9a0e4156SSadaf Ebrahimi         )]
299*9a0e4156SSadaf Ebrahimi         [string]$Mode,
300*9a0e4156SSadaf Ebrahimi 
301*9a0e4156SSadaf Ebrahimi         [Parameter(ParameterSetName = 'Capstone', Mandatory = $true)]
302*9a0e4156SSadaf Ebrahimi         [ValidateNotNullOrEmpty()]
303*9a0e4156SSadaf Ebrahimi         [byte[]]$Bytes,
304*9a0e4156SSadaf Ebrahimi 
305*9a0e4156SSadaf Ebrahimi         [Parameter(ParameterSetName = 'Capstone')]
306*9a0e4156SSadaf Ebrahimi         [ValidateSet(
307*9a0e4156SSadaf Ebrahimi             'Intel',
308*9a0e4156SSadaf Ebrahimi             'ATT'
309*9a0e4156SSadaf Ebrahimi         )]
310*9a0e4156SSadaf Ebrahimi         [string]$Syntax = 'Intel',
311*9a0e4156SSadaf Ebrahimi 
312*9a0e4156SSadaf Ebrahimi         [Parameter(ParameterSetName = 'Capstone')]
313*9a0e4156SSadaf Ebrahimi         [uint64]$Address = 0x100000,
314*9a0e4156SSadaf Ebrahimi 
315*9a0e4156SSadaf Ebrahimi         [Parameter(ParameterSetName = 'Capstone')]
316*9a0e4156SSadaf Ebrahimi         [switch]$Detailed,
317*9a0e4156SSadaf Ebrahimi 
318*9a0e4156SSadaf Ebrahimi         [Parameter(ParameterSetName = 'Version')]
319*9a0e4156SSadaf Ebrahimi         [switch]$Version
320*9a0e4156SSadaf Ebrahimi     )
321*9a0e4156SSadaf Ebrahimi 
322*9a0e4156SSadaf Ebrahimi     if ($Version) {
323*9a0e4156SSadaf Ebrahimi         $Banner = @'
324*9a0e4156SSadaf Ebrahimi 
325*9a0e4156SSadaf Ebrahimi                  (((;
326*9a0e4156SSadaf Ebrahimi               (; "((((\
327*9a0e4156SSadaf Ebrahimi            ;((((((; "((((;
328*9a0e4156SSadaf Ebrahimi           ((((""\(((( "((((
329*9a0e4156SSadaf Ebrahimi         ((((" ((\ "(((( "(((\
330*9a0e4156SSadaf Ebrahimi       ;(((/ ((((((( "(((( \(((
331*9a0e4156SSadaf Ebrahimi      ((((" (((* "(((( \(((;"(((\
332*9a0e4156SSadaf Ebrahimi     ((((";((("/(( \(((;"(((\"(((\
333*9a0e4156SSadaf Ebrahimi    (((( (((( ((((" "(((\ ((() (((\
334*9a0e4156SSadaf Ebrahimi   ;((("(((( (((*     **"" ((()"(((;
335*9a0e4156SSadaf Ebrahimi   (((" ((( (((( ((((((((((((((:*(((
336*9a0e4156SSadaf Ebrahimi  (((( (((*)((( ********"""" ;;(((((;
337*9a0e4156SSadaf Ebrahimi  (((* ((( (((((((((((((((((((((*"" (
338*9a0e4156SSadaf Ebrahimi  ((("(((( """***********"""" ;;(((((
339*9a0e4156SSadaf Ebrahimi   "" (((((((((((((((((((((((((((*""
340*9a0e4156SSadaf Ebrahimi          """****(((((****"""
341*9a0e4156SSadaf Ebrahimi 
342*9a0e4156SSadaf Ebrahimi      -=[Capstone Engine v{0}]=-
343*9a0e4156SSadaf Ebrahimi 
344*9a0e4156SSadaf Ebrahimi '@ -f (Get-CapstoneVersion).ToString(2)
345*9a0e4156SSadaf Ebrahimi         # Mmm ASCII version banner!
346*9a0e4156SSadaf Ebrahimi         return $Banner
347*9a0e4156SSadaf Ebrahimi     }
348*9a0e4156SSadaf Ebrahimi 
349*9a0e4156SSadaf Ebrahimi     # Disasm Handle
350*9a0e4156SSadaf Ebrahimi     $DisAsmHandle = [System.IntPtr]::Zero
351*9a0e4156SSadaf Ebrahimi 
352*9a0e4156SSadaf Ebrahimi     # Initialize Capstone with cs_open()
353*9a0e4156SSadaf Ebrahimi     $CallResult = [Capstone]::cs_open($Architecture, $Mode, [ref]$DisAsmHandle)
354*9a0e4156SSadaf Ebrahimi     if ($CallResult -ne 'CS_ERR_OK') {
355*9a0e4156SSadaf Ebrahimi         if ($CallResult -eq 'CS_ERR_MODE') {
356*9a0e4156SSadaf Ebrahimi             throw "Invalid Architecture/Mode combination: $Architecture/$Mode"
357*9a0e4156SSadaf Ebrahimi         } else {
358*9a0e4156SSadaf Ebrahimi             throw "cs_open error: $CallResult"
359*9a0e4156SSadaf Ebrahimi         }
360*9a0e4156SSadaf Ebrahimi     }
361*9a0e4156SSadaf Ebrahimi 
362*9a0e4156SSadaf Ebrahimi     # Set disassembly syntax
363*9a0e4156SSadaf Ebrahimi     #---
364*9a0e4156SSadaf Ebrahimi     # cs_opt_type  -> CS_OPT_SYNTAX = 1
365*9a0e4156SSadaf Ebrahimi     #---
366*9a0e4156SSadaf Ebrahimi     # cs_opt_value -> CS_OPT_SYNTAX_INTEL = 1
367*9a0e4156SSadaf Ebrahimi     #              -> CS_OPT_SYNTAX_ATT   = 2
368*9a0e4156SSadaf Ebrahimi     if ($Syntax -eq 'Intel') {
369*9a0e4156SSadaf Ebrahimi         $CS_OPT_SYNTAX = 1
370*9a0e4156SSadaf Ebrahimi     } else {
371*9a0e4156SSadaf Ebrahimi         $CS_OPT_SYNTAX = 2
372*9a0e4156SSadaf Ebrahimi     }
373*9a0e4156SSadaf Ebrahimi 
374*9a0e4156SSadaf Ebrahimi     $CallResult = [Capstone]::cs_option($DisAsmHandle, 1, $CS_OPT_SYNTAX)
375*9a0e4156SSadaf Ebrahimi     if ($CallResult -ne 'CS_ERR_OK') {
376*9a0e4156SSadaf Ebrahimi         $CallResult = [Capstone]::cs_close([ref]$DisAsmHandle)
377*9a0e4156SSadaf Ebrahimi         throw "cs_option error: $CallResult"
378*9a0e4156SSadaf Ebrahimi     }
379*9a0e4156SSadaf Ebrahimi 
380*9a0e4156SSadaf Ebrahimi     # Set disassembly detail
381*9a0e4156SSadaf Ebrahimi     #---
382*9a0e4156SSadaf Ebrahimi     # cs_opt_type  -> CS_OPT_DETAIL = 2
383*9a0e4156SSadaf Ebrahimi     #---
384*9a0e4156SSadaf Ebrahimi     # cs_opt_value -> CS_OPT_ON  = 3
385*9a0e4156SSadaf Ebrahimi     #              -> CS_OPT_OFF = 0
386*9a0e4156SSadaf Ebrahimi     if ($Detailed) {
387*9a0e4156SSadaf Ebrahimi         $CS_OPT = 3
388*9a0e4156SSadaf Ebrahimi     } else {
389*9a0e4156SSadaf Ebrahimi         $CS_OPT = 0
390*9a0e4156SSadaf Ebrahimi     }
391*9a0e4156SSadaf Ebrahimi 
392*9a0e4156SSadaf Ebrahimi     $CallResult = [Capstone]::cs_option($DisAsmHandle, 2, $CS_OPT)
393*9a0e4156SSadaf Ebrahimi     if ($CallResult -ne 'CS_ERR_OK') {
394*9a0e4156SSadaf Ebrahimi         $CallResult = [Capstone]::cs_close([ref]$DisAsmHandle)
395*9a0e4156SSadaf Ebrahimi         throw "cs_option error: $CallResult"
396*9a0e4156SSadaf Ebrahimi     }
397*9a0e4156SSadaf Ebrahimi 
398*9a0e4156SSadaf Ebrahimi     # Out Buffer Handle
399*9a0e4156SSadaf Ebrahimi     $InsnHandle = [System.IntPtr]::Zero
400*9a0e4156SSadaf Ebrahimi 
401*9a0e4156SSadaf Ebrahimi     # Disassemble bytes
402*9a0e4156SSadaf Ebrahimi     $Count = [Capstone]::cs_disasm($DisAsmHandle, $Bytes, $Bytes.Count, $Address, 0, [ref]$InsnHandle)
403*9a0e4156SSadaf Ebrahimi 
404*9a0e4156SSadaf Ebrahimi     if ($Count -gt 0) {
405*9a0e4156SSadaf Ebrahimi         # Result struct
406*9a0e4156SSadaf Ebrahimi         $cs_insn = if ($PSVersionTable.PSVersion.Major -gt 2) {
407*9a0e4156SSadaf Ebrahimi             [cs_insn]@{}
408*9a0e4156SSadaf Ebrahimi         } else {
409*9a0e4156SSadaf Ebrahimi             New-Object -TypeName cs_insn
410*9a0e4156SSadaf Ebrahimi         }
411*9a0e4156SSadaf Ebrahimi 
412*9a0e4156SSadaf Ebrahimi         $cs_insn_size = [System.Runtime.InteropServices.Marshal]::SizeOf($cs_insn)
413*9a0e4156SSadaf Ebrahimi         $cs_insn = $cs_insn.GetType()
414*9a0e4156SSadaf Ebrahimi 
415*9a0e4156SSadaf Ebrahimi         # Result detail struct
416*9a0e4156SSadaf Ebrahimi         $cs_detail = if ($PSVersionTable.PSVersion.Major -gt 2) {
417*9a0e4156SSadaf Ebrahimi             [cs_detail]@{}
418*9a0e4156SSadaf Ebrahimi         } else {
419*9a0e4156SSadaf Ebrahimi             New-Object -TypeName cs_detail
420*9a0e4156SSadaf Ebrahimi         }
421*9a0e4156SSadaf Ebrahimi         $cs_detail = $cs_detail.GetType()
422*9a0e4156SSadaf Ebrahimi 
423*9a0e4156SSadaf Ebrahimi         # Result buffer offset
424*9a0e4156SSadaf Ebrahimi         $BuffOffset = $InsnHandle.ToInt64()
425*9a0e4156SSadaf Ebrahimi 
426*9a0e4156SSadaf Ebrahimi         for ($i = 0 ; $i -lt $Count ; $i++) {
427*9a0e4156SSadaf Ebrahimi             # Cast Offset to cs_insn
428*9a0e4156SSadaf Ebrahimi             $Cast = [System.Runtime.InteropServices.Marshal]::PtrToStructure([System.Intptr]$BuffOffset, [type]$cs_insn)
429*9a0e4156SSadaf Ebrahimi 
430*9a0e4156SSadaf Ebrahimi             if ($CS_OPT -eq 0) {
431*9a0e4156SSadaf Ebrahimi                 $Disassembly = @{
432*9a0e4156SSadaf Ebrahimi                     Address     = $Cast.address
433*9a0e4156SSadaf Ebrahimi                     Instruction = '{0} {1}' -f $Cast.mnemonic, $Cast.operands
434*9a0e4156SSadaf Ebrahimi                 }
435*9a0e4156SSadaf Ebrahimi 
436*9a0e4156SSadaf Ebrahimi                 if ($PSVersionTable.PSVersion.Major -gt 2) {
437*9a0e4156SSadaf Ebrahimi                     # Add TypeName for PS formatting and output result
438*9a0e4156SSadaf Ebrahimi                     $Disassembly.PSTypeName ='CapstoneDisassembly.Simple'
439*9a0e4156SSadaf Ebrahimi                     [pscustomobject]$Disassembly
440*9a0e4156SSadaf Ebrahimi                 } else {
441*9a0e4156SSadaf Ebrahimi                     $Disassembly = New-Object -TypeName PSObject -Property $Disassembly
442*9a0e4156SSadaf Ebrahimi                     # Add TypeName for PS formatting and output result
443*9a0e4156SSadaf Ebrahimi                     $Disassembly.PSObject.TypeNames.Insert(0, 'CapstoneDisassembly.Simple')
444*9a0e4156SSadaf Ebrahimi                     $Disassembly
445*9a0e4156SSadaf Ebrahimi                 }
446*9a0e4156SSadaf Ebrahimi             } else {
447*9a0e4156SSadaf Ebrahimi                 $DetailCast = [System.Runtime.InteropServices.Marshal]::PtrToStructure($Cast.detail, [type]$cs_detail)
448*9a0e4156SSadaf Ebrahimi                 if ($DetailCast.regs_read_count -gt 0) {
449*9a0e4156SSadaf Ebrahimi                     $RegRead = for ($r = 0 ; $r -lt $DetailCast.regs_read_count ; $r++) {
450*9a0e4156SSadaf Ebrahimi                         $NamePointer = [Capstone]::cs_reg_name($DisAsmHandle, $DetailCast.regs_read[$r])
451*9a0e4156SSadaf Ebrahimi                         [System.Runtime.InteropServices.Marshal]::PtrToStringAnsi($NamePointer)
452*9a0e4156SSadaf Ebrahimi                     }
453*9a0e4156SSadaf Ebrahimi                 }
454*9a0e4156SSadaf Ebrahimi 
455*9a0e4156SSadaf Ebrahimi                 if ($DetailCast.regs_write_count -gt 0) {
456*9a0e4156SSadaf Ebrahimi                     $RegWrite = for ($r = 0 ; $r -lt $DetailCast.regs_write_count ; $r++) {
457*9a0e4156SSadaf Ebrahimi                         $NamePointer = [Capstone]::cs_reg_name($DisAsmHandle, $DetailCast.regs_write[$r])
458*9a0e4156SSadaf Ebrahimi                         [System.Runtime.InteropServices.Marshal]::PtrToStringAnsi($NamePointer)
459*9a0e4156SSadaf Ebrahimi                     }
460*9a0e4156SSadaf Ebrahimi                 }
461*9a0e4156SSadaf Ebrahimi 
462*9a0e4156SSadaf Ebrahimi                 $Disassembly = @{
463*9a0e4156SSadaf Ebrahimi                     Address    = $Cast.address
464*9a0e4156SSadaf Ebrahimi                     Mnemonic   = $Cast.mnemonic
465*9a0e4156SSadaf Ebrahimi                     Operands   = $Cast.operands
466*9a0e4156SSadaf Ebrahimi                     Bytes      = $Cast.bytes[0..($Cast.size - 1)]
467*9a0e4156SSadaf Ebrahimi                     Size       = $Cast.size
468*9a0e4156SSadaf Ebrahimi                     RegRead    = $RegRead
469*9a0e4156SSadaf Ebrahimi                     RegWrite   = $RegWrite
470*9a0e4156SSadaf Ebrahimi                 }
471*9a0e4156SSadaf Ebrahimi 
472*9a0e4156SSadaf Ebrahimi                 if ($PSVersionTable.PSVersion.Major -gt 2) {
473*9a0e4156SSadaf Ebrahimi                     # Add TypeName for PS formatting and output result
474*9a0e4156SSadaf Ebrahimi                     $Disassembly.PSTypeName = 'CapstoneDisassembly.Detailed'
475*9a0e4156SSadaf Ebrahimi                     [pscustomobject]$Disassembly
476*9a0e4156SSadaf Ebrahimi                 } else {
477*9a0e4156SSadaf Ebrahimi                     $Disassembly = New-Object -TypeName PSObject -Property $Disassembly
478*9a0e4156SSadaf Ebrahimi                     # Add TypeName for PS formatting and output result
479*9a0e4156SSadaf Ebrahimi                     $Disassembly.PSObject.TypeNames.Insert(0, 'CapstoneDisassembly.Detailed')
480*9a0e4156SSadaf Ebrahimi                     $Disassembly
481*9a0e4156SSadaf Ebrahimi                 }
482*9a0e4156SSadaf Ebrahimi             }
483*9a0e4156SSadaf Ebrahimi             $BuffOffset = $BuffOffset + $cs_insn_size
484*9a0e4156SSadaf Ebrahimi         }
485*9a0e4156SSadaf Ebrahimi     } else {
486*9a0e4156SSadaf Ebrahimi         $CallResult = [Capstone]::cs_close([ref]$DisAsmHandle)
487*9a0e4156SSadaf Ebrahimi         throw 'Disassembly Failed'
488*9a0e4156SSadaf Ebrahimi     }
489*9a0e4156SSadaf Ebrahimi 
490*9a0e4156SSadaf Ebrahimi     # Free Buffer Handle
491*9a0e4156SSadaf Ebrahimi     $CallResult = [Capstone]::cs_free($InsnHandle, $Count)
492*9a0e4156SSadaf Ebrahimi }
493*9a0e4156SSadaf Ebrahimi 
494*9a0e4156SSadaf Ebrahimi #region Init
495*9a0e4156SSadaf Ebrahimi 
496*9a0e4156SSadaf Ebrahimi Initialize-Capstone -DllPath (
497*9a0e4156SSadaf Ebrahimi     Join-Path -Path $PSScriptRoot -ChildPath 'Lib\Capstone\capstone.dll'
498*9a0e4156SSadaf Ebrahimi ) -ErrorAction Stop
499*9a0e4156SSadaf Ebrahimi 
500*9a0e4156SSadaf Ebrahimi #endregion