1 VERSION 1.0 CLASS 2 BEGIN 3 MultiUse = -1 'True 4 Persistable = 0 'NotPersistable 5 DataBindingBehavior = 0 'vbNone 6 DataSourceBehavior = 0 'vbNone 7 MTSTransactionMode = 0 'NotAnMTSObject 8 END 9 Attribute VB_Name = "CX86Operand" 10 Attribute VB_GlobalNameSpace = False 11 Attribute VB_Creatable = True 12 Attribute VB_PredeclaredId = False 13 Attribute VB_Exposed = False 14 Option Explicit 15 16 'Capstone Disassembly Engine bindings for VB6 17 'Contributed by FireEye FLARE Team 18 'Author: David Zimmer <david.zimmer (a] fireeye.com>, <dzzie (a] 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 69 Public optype As x86_op_type 70 Public size As Byte 71 Public avx_bcast As x86_avx_bcast 72 Public avx_zero_opmask As Boolean 73 74 'only one of the following will be set based on type 75 Public reg As x86_reg 76 Public fp As Currency 77 Public imm As Currency 78 Public mem As CX86OpMem 79 80 Private hEngine As Long 81 Private m_raw() As Byte 82 83 Function 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 116 End Function 117 118 Function 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 132 End Function 133 134 Function 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 150 End Function 151 152 153 Friend 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 197 End Sub 198 199 Private Sub Class_Terminate() 200 'looks like everything is freeing up ok 201 'Debug.Print "Cx86Operand.Terminate" 202 End Sub 203