aboutsummaryrefslogtreecommitdiffstats
path: root/capstone/bindings/vb6/CX86Inst.cls
blob: daf7dd5b82a0d0e0b6d6ee6f0fe96f0f1fa712f4 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
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 <david.zimmer@fireeye.com>, <dzzie@yahoo.com>
'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