VERSION 1.0 CLASS BEGIN MultiUse = -1 'True Persistable = 0 'NotPersistable DataBindingBehavior = 0 'vbNone DataSourceBehavior = 0 'vbNone MTSTransactionMode = 0 'NotAnMTSObject END Attribute VB_Name = "CX86Inst" Attribute VB_GlobalNameSpace = False Attribute VB_Creatable = True Attribute VB_PredeclaredId = False Attribute VB_Exposed = False Option Explicit 'Capstone Disassembly Engine bindings for VB6 'Contributed by FireEye FLARE Team 'Author: David Zimmer , 'License: Apache 'Copyright: FireEye 2017 '// Instruction structure sizeof() = 432 bytes 'typedef struct cs_x86 { ' // Instruction prefix, which can be up to 4 bytes. ' // A prefix byte gets value 0 when irrelevant. ' // prefix[0] indicates REP/REPNE/LOCK prefix (See X86_PREFIX_REP/REPNE/LOCK above) ' // prefix[1] indicates segment override (irrelevant for x86_64): ' // See X86_PREFIX_CS/SS/DS/ES/FS/GS above. ' // prefix[2] indicates operand-size override (X86_PREFIX_OPSIZE) ' // prefix[3] indicates address-size override (X86_PREFIX_ADDRSIZE) ' uint8_t prefix[4]; ' ' // Instruction opcode, wich can be from 1 to 4 bytes in size. ' // This contains VEX opcode as well. ' // An trailing opcode byte gets value 0 when irrelevant. ' uint8_t opcode[4]; ' ' // REX prefix: only a non-zero value is relavant for x86_64 ' uint8_t rex; ' ' // Address size, which can be overrided with above prefix[5]. ' uint8_t addr_size; ' ' // ModR/M byte ' uint8_t modrm; ' ' // SIB value, or 0 when irrelevant. ' uint8_t sib; ' ' // Displacement value, or 0 when irrelevant. ' int32_t disp; ' ' /* SIB state */ ' // SIB index register, or X86_REG_INVALID when irrelevant. ' x86_reg sib_index; ' // SIB scale. only applicable if sib_index is relavant. ' int8_t sib_scale; ' // SIB base register, or X86_REG_INVALID when irrelevant. ' x86_reg sib_base; ' ' // SSE Code Condition ' x86_sse_cc sse_cc; ' ' // AVX Code Condition ' x86_avx_cc avx_cc; ' ' // AVX Suppress all Exception ' bool avx_sae; ' ' // AVX static rounding mode ' x86_avx_rm avx_rm; ' ' // Number of operands of this instruction, ' // or 0 when instruction has no operand. ' uint8_t op_count; ' ' cs_x86_op operands[8]; // operands for this instruction. '} cs_x86; Private m_prefix() As Byte Private m_opcode() As Byte Public rex As Byte Public addr_size As Byte Public modrm As Byte Public sib As Byte Public disp As Long Public sib_index As x86_reg Public sib_scale As Byte Public sib_base As x86_reg Public sse_cc As x86_sse_cc Public avx_cc As x86_avx_cc Public avx_sae As Boolean Public avx_rm As x86_avx_rm Public operands As New Collection Public parent As CDisassembler Private hEngine As Long Private m_raw() As Byte Property Get prefix() As Byte() prefix = m_prefix End Property Property Get opcode() As Byte() opcode = m_opcode End Property Function toString() As String Dim r() As String Dim o As CX86Operand push r, "X86 Instruction Details:" push r, String(40, "-") If DEBUG_DUMP Then push r, "Raw: " push r, HexDump(m_raw) End If push r, "Prefix: " & b2Str(m_prefix) push r, "OpCode: " & b2Str(m_opcode) push r, "Rex: " & rex push r, "addr_size: " & addr_size push r, "modrm: " & Hex(modrm) push r, "disp: " & Hex(disp) If parent.mode <> CS_MODE_16 Then push r, "sib: " & Hex(sib) push r, "sib_index: " & regName(hEngine, sib_index) push r, "sib_scale: " & Hex(sib_scale) push r, "sib_base: " & regName(hEngine, sib_base) End If If sse_cc <> 0 Then push r, "sse_cc: " & x86_sse_cc2str(sse_cc) If avx_cc <> 0 Then push r, "avx_cc: " & x86_avx_cc2str(avx_cc) If avx_sae <> 0 Then push r, "avx_sae: " & avx_sae If avx_rm <> 0 Then push r, "avx_rm: " & x86_avx_rm2str(avx_rm) push r, "Operands: " & operands.count For Each o In operands push r, String(40, "-") push r, o.toString Next toString = Join(r, vbCrLf) End Function Friend Sub LoadDetails(lpStruct As Long, parent As CDisassembler) Dim cs As cs_x86 Dim o As CX86Operand Dim ptr As Long Dim i As Long Const sizeOfx86Operand = 48 Set Me.parent = parent hEngine = parent.hCapstone CopyMemory ByVal VarPtr(cs), ByVal lpStruct, LenB(cs) If DEBUG_DUMP Then ReDim m_raw(LenB(cs)) CopyMemory ByVal VarPtr(m_raw(0)), ByVal lpStruct, LenB(cs) End If Me.rex = cs.rex Me.addr_size = cs.addr_size Me.modrm = cs.modrm Me.sib = cs.sib Me.disp = cs.disp Me.sib_index = cs.sib_index Me.sib_scale = cs.sib_scale Me.sib_base = cs.sib_base Me.sse_cc = cs.sse_cc Me.avx_cc = cs.avx_cc Me.avx_sae = cs.avx_sae Me.avx_rm = cs.avx_rm m_prefix = cs.prefix m_opcode = cs.opcode ptr = lpStruct + LenB(cs) 'we dont include the operands in our vb struct.. For i = 1 To cs.op_count Set o = New CX86Operand o.LoadDetails ptr, hEngine operands.Add o ptr = ptr + sizeOfx86Operand Next End Sub