1VERSION 1.0 CLASS 2BEGIN 3 MultiUse = -1 'True 4 Persistable = 0 'NotPersistable 5 DataBindingBehavior = 0 'vbNone 6 DataSourceBehavior = 0 'vbNone 7 MTSTransactionMode = 0 'NotAnMTSObject 8END 9Attribute VB_Name = "CX86Operand" 10Attribute VB_GlobalNameSpace = False 11Attribute VB_Creatable = True 12Attribute VB_PredeclaredId = False 13Attribute VB_Exposed = False 14Option Explicit 15 16'Capstone Disassembly Engine bindings for VB6 17'Contributed by FireEye FLARE Team 18'Author: David Zimmer <david.zimmer@fireeye.com>, <dzzie@yahoo.com> 19'License: Apache 20'Copyright: FireEye 2017 21 22 23'// Instruction operand sizeof() reports 48 bytes 24'typedef struct cs_x86_op { 25' x86_op_type type; // operand type 26' 27' union { 28' x86_reg reg; // register value for REG operand 29' int64_t imm; // immediate value for IMM operand 30' double fp; // floating point value for FP operand 31' x86_op_mem mem; // base/index/scale/disp value for MEM operand (24bytes max) 32' }; 33' 34' // size of this operand (in bytes). 35' uint8_t size; 36' 37' // AVX broadcast type, or 0 if irrelevant 38' x86_avx_bcast avx_bcast; 39' 40' // AVX zero opmask {z} 41' bool avx_zero_opmask; 42'} cs_x86_op; 43 44'Instruction's operand referring to memory 45'This is associated with X86_OP_MEM operand type above 46'Public Type x86_op_mem 47' segment As Long ' segment register (or X86_REG_INVALID if irrelevant) UNSIGNED 48' base As Long ' base register (or X86_REG_INVALID if irrelevant) UNSIGNED 49' index As Long ' index register (or X86_REG_INVALID if irrelevant) UNSIGNED 50' scale As Long ' scale for index register 51' disp As Currency ' displacement value 52'End Type 53 54'this shows the alignment padding used by compiler.. 55' cs_x86_op op; 56' op.type = (x86_op_type)1; 57' op.reg = (x86_reg)2; 58' op.avx_bcast = (x86_avx_bcast)3; 59' op.avx_zero_opmask = 4; 60' op.size = 0xaa; 61' printf("&cs_x86_op = %x", &op); 62' _asm int 3 63' 64' 65'0x0012FF34 01 00 00 00 cc cc cc cc 02 00 00 00 cc cc cc cc ....����....���� 66'0x0012FF44 cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc ���������������� 67'0x0012FF54 aa cc cc cc 03 00 00 00 01 cc cc cc cc cc cc cc ����.....������� 68 69Public optype As x86_op_type 70Public size As Byte 71Public avx_bcast As x86_avx_bcast 72Public avx_zero_opmask As Boolean 73 74'only one of the following will be set based on type 75Public reg As x86_reg 76Public fp As Currency 77Public imm As Currency 78Public mem As CX86OpMem 79 80Private hEngine As Long 81Private m_raw() As Byte 82 83Function toString() As String 84 85 Dim ret() As String 86 87 push ret, "X86 Operand:" 88 push ret, String(45, "-") 89 90 If DEBUG_DUMP Then 91 push ret, "Raw: " 92 push ret, HexDump(m_raw) 93 End If 94 95 push ret, "Type: " & opStr() 96 push ret, "Size: " & size 97 If avx_bcast <> 0 Then push ret, "BCast: " & bcastStr() 98 If avx_zero_opmask Then push ret, "AvxOpMask: " & avx_zero_opmask 99 100 If optype = X86_OP_FP Then 101 push ret, "FP: " & cur2str(fp) 102 ElseIf optype = X86_OP_IMM Then 103 push ret, "IMM: " & cur2str(imm) 104 ElseIf optype = x86_op_mem Then 105 If mem.base <> 0 Then push ret, "Base: " & regName(hEngine, mem.base) 106 If mem.index <> 0 Then push ret, "Index: " & regName(hEngine, mem.index) 107 If mem.scale_ <> 1 Then push ret, "Scale: " & Hex(mem.scale_) 108 If mem.segment <> 0 Then push ret, "Seg: " & regName(hEngine, mem.segment) 109 If mem.disp <> 0 Then push ret, "Disp: " & cur2str(mem.disp) 110 ElseIf optype = X86_OP_REG Then 111 push ret, "Reg: " & regName(hEngine, reg) 112 End If 113 114 toString = Join(ret, vbCrLf) 115 116End Function 117 118Function opStr() As String 119 120 If optype = X86_OP_FP Then opStr = "X86_OP_FP" 121 If optype = x86_op_mem Then opStr = "x86_op_mem" 122 If optype = X86_OP_IMM Then opStr = "X86_OP_IMM" 123 If optype = X86_OP_REG Then opStr = "X86_OP_REG" 124 If optype = X86_OP_INVALID Then opStr = "X86_OP_INVALID" 125 126 If Len(opStr) = 0 Then 127 opStr = "Error: " & Hex(optype) 128 ElseIf DEBUG_DUMP Then 129 opStr = opStr & " (" & Hex(optype) & ")" 130 End If 131 132End Function 133 134Function bcastStr() As String 135 Dim r As String 136 137 If avx_bcast = X86_AVX_BCAST_INVALID Then r = "X86_AVX_BCAST_INVALID" 138 If avx_bcast = X86_AVX_BCAST_2 Then r = "X86_AVX_BCAST_2" 139 If avx_bcast = X86_AVX_BCAST_4 Then r = "X86_AVX_BCAST_4" 140 If avx_bcast = X86_AVX_BCAST_8 Then r = "X86_AVX_BCAST_8" 141 If avx_bcast = X86_AVX_BCAST_16 Then r = "X86_AVX_BCAST_16" 142 143 If Len(r) = 0 Then 144 r = "Unknown: " & Hex(avx_bcast) 145 ElseIf DEBUG_DUMP Then 146 r = r & " (" & Hex(avx_bcast) & ")" 147 End If 148 149 bcastStr = r 150End Function 151 152 153Friend Sub LoadDetails(lpStruct As Long, hCapstone As Long) 154 155 Dim opMem As x86_op_mem 156 Dim ptr As Long 157 158 Const align4 = 4 159 Const align3 = 3 160 161 hEngine = hCapstone 162 163 If DEBUG_DUMP Then 164 ReDim m_raw(48) 165 CopyMemory ByVal VarPtr(m_raw(0)), ByVal lpStruct, 48 166 End If 167 168 optype = readLng(lpStruct) 169 ptr = lpStruct + 4 + align4 170 171 If optype = X86_OP_FP Then 172 fp = readCur(ptr) 173 ElseIf optype = X86_OP_IMM Then 174 imm = readCur(ptr) 175 ElseIf optype = x86_op_mem Then 176 CopyMemory ByVal VarPtr(opMem), ByVal ptr, LenB(opMem) 177 Set mem = New CX86OpMem 178 mem.base = opMem.base 179 mem.disp = opMem.disp 180 mem.index = opMem.index 181 mem.scale_ = opMem.scale 182 mem.segment = opMem.segment 183 ElseIf optype = X86_OP_REG Then 184 reg = readLng(ptr) 185 End If 186 187 ptr = ptr + LenB(opMem) 188 189 size = readByte(ptr) 190 ptr = ptr + 1 + align3 191 192 avx_bcast = readLng(ptr) 193 ptr = ptr + 4 194 195 avx_zero_opmask = (readByte(ptr) = 1) 196 197End Sub 198 199Private Sub Class_Terminate() 200 'looks like everything is freeing up ok 201 'Debug.Print "Cx86Operand.Terminate" 202End Sub 203