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