• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 = "CX86Inst"
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 structure  sizeof() = 432 bytes
24'typedef struct cs_x86 {
25'    // Instruction prefix, which can be up to 4 bytes.
26'    // A prefix byte gets value 0 when irrelevant.
27'    // prefix[0] indicates REP/REPNE/LOCK prefix (See X86_PREFIX_REP/REPNE/LOCK above)
28'    // prefix[1] indicates segment override (irrelevant for x86_64):
29'    // See X86_PREFIX_CS/SS/DS/ES/FS/GS above.
30'    // prefix[2] indicates operand-size override (X86_PREFIX_OPSIZE)
31'    // prefix[3] indicates address-size override (X86_PREFIX_ADDRSIZE)
32'    uint8_t prefix[4];
33'
34'    // Instruction opcode, wich can be from 1 to 4 bytes in size.
35'    // This contains VEX opcode as well.
36'    // An trailing opcode byte gets value 0 when irrelevant.
37'    uint8_t opcode[4];
38'
39'    // REX prefix: only a non-zero value is relavant for x86_64
40'    uint8_t rex;
41'
42'    // Address size, which can be overrided with above prefix[5].
43'    uint8_t addr_size;
44'
45'    // ModR/M byte
46'    uint8_t modrm;
47'
48'    // SIB value, or 0 when irrelevant.
49'    uint8_t sib;
50'
51'    // Displacement value, or 0 when irrelevant.
52'    int32_t disp;
53'
54'    /* SIB state */
55'    // SIB index register, or X86_REG_INVALID when irrelevant.
56'    x86_reg sib_index;
57'    // SIB scale. only applicable if sib_index is relavant.
58'    int8_t sib_scale;
59'    // SIB base register, or X86_REG_INVALID when irrelevant.
60'    x86_reg sib_base;
61'
62'    // SSE Code Condition
63'    x86_sse_cc sse_cc;
64'
65'    // AVX Code Condition
66'    x86_avx_cc avx_cc;
67'
68'    // AVX Suppress all Exception
69'    bool avx_sae;
70'
71'    // AVX static rounding mode
72'    x86_avx_rm avx_rm;
73'
74'    // Number of operands of this instruction,
75'    // or 0 when instruction has no operand.
76'    uint8_t op_count;
77'
78'    cs_x86_op operands[8];  // operands for this instruction.
79'} cs_x86;
80
81Private m_prefix() As Byte
82Private m_opcode() As Byte
83Public rex As Byte
84Public addr_size As Byte
85Public modrm As Byte
86Public sib As Byte
87Public disp As Long
88Public sib_index As x86_reg
89Public sib_scale As Byte
90Public sib_base As x86_reg
91Public sse_cc As x86_sse_cc
92Public avx_cc As x86_avx_cc
93Public avx_sae As Boolean
94Public avx_rm As x86_avx_rm
95Public operands As New Collection
96
97Public parent As CDisassembler
98Private hEngine As Long
99Private m_raw() As Byte
100
101Property Get prefix() As Byte()
102    prefix = m_prefix
103End Property
104
105Property Get opcode() As Byte()
106    opcode = m_opcode
107End Property
108
109Function toString() As String
110
111    Dim r() As String
112    Dim o As CX86Operand
113
114    push r, "X86 Instruction Details:"
115    push r, String(40, "-")
116
117    If DEBUG_DUMP Then
118        push r, "Raw: "
119        push r, HexDump(m_raw)
120    End If
121
122    push r, "Prefix: " & b2Str(m_prefix)
123    push r, "OpCode: " & b2Str(m_opcode)
124    push r, "Rex: " & rex
125    push r, "addr_size: " & addr_size
126    push r, "modrm: " & Hex(modrm)
127    push r, "disp: " & Hex(disp)
128
129    If parent.mode <> CS_MODE_16 Then
130        push r, "sib: " & Hex(sib)
131        push r, "sib_index: " & regName(hEngine, sib_index)
132        push r, "sib_scale: " & Hex(sib_scale)
133        push r, "sib_base: " & regName(hEngine, sib_base)
134    End If
135
136    If sse_cc <> 0 Then push r, "sse_cc: " & x86_sse_cc2str(sse_cc)
137    If avx_cc <> 0 Then push r, "avx_cc: " & x86_avx_cc2str(avx_cc)
138    If avx_sae <> 0 Then push r, "avx_sae: " & avx_sae
139    If avx_rm <> 0 Then push r, "avx_rm: " & x86_avx_rm2str(avx_rm)
140
141    push r, "Operands: " & operands.count
142
143    For Each o In operands
144        push r, String(40, "-")
145        push r, o.toString
146    Next
147
148    toString = Join(r, vbCrLf)
149
150End Function
151
152Friend Sub LoadDetails(lpStruct As Long, parent As CDisassembler)
153
154    Dim cs As cs_x86
155    Dim o As CX86Operand
156    Dim ptr As Long
157    Dim i As Long
158
159    Const sizeOfx86Operand = 48
160
161    Set Me.parent = parent
162    hEngine = parent.hCapstone
163
164    CopyMemory ByVal VarPtr(cs), ByVal lpStruct, LenB(cs)
165
166    If DEBUG_DUMP Then
167        ReDim m_raw(LenB(cs))
168        CopyMemory ByVal VarPtr(m_raw(0)), ByVal lpStruct, LenB(cs)
169    End If
170
171    Me.rex = cs.rex
172    Me.addr_size = cs.addr_size
173    Me.modrm = cs.modrm
174    Me.sib = cs.sib
175    Me.disp = cs.disp
176    Me.sib_index = cs.sib_index
177    Me.sib_scale = cs.sib_scale
178    Me.sib_base = cs.sib_base
179    Me.sse_cc = cs.sse_cc
180    Me.avx_cc = cs.avx_cc
181    Me.avx_sae = cs.avx_sae
182    Me.avx_rm = cs.avx_rm
183    m_prefix = cs.prefix
184    m_opcode = cs.opcode
185
186    ptr = lpStruct + LenB(cs) 'we dont include the operands in our vb struct..
187    For i = 1 To cs.op_count
188        Set o = New CX86Operand
189        o.LoadDetails ptr, hEngine
190        operands.Add o
191        ptr = ptr + sizeOfx86Operand
192    Next
193
194
195
196End Sub
197
198