-
Notifications
You must be signed in to change notification settings - Fork 6
/
decoder.go
143 lines (125 loc) · 3.99 KB
/
decoder.go
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
// Copyright 2019 John Papandriopoulos. All rights reserved.
// Use of this source code is governed by a MIT-style
// license that can be found in the LICENSE file.
package zydis
/*
#cgo CFLAGS: -I./lib/include
#include <Zydis/Zydis.h>
const ZyanStatus statusSuccess = ZYAN_STATUS_SUCCESS;
*/
import "C"
import (
"fmt"
"unsafe"
)
// Decoder performs decoding of instruction bytes to a machine interpretable
// struct.
type Decoder struct {
zdecoder C.ZydisDecoder
}
// NewDecoder returns a new instruction decoder.
func NewDecoder(mm MachineMode, aw AddressWidth) *Decoder {
d := &Decoder{}
C.ZydisDecoderInit(&d.zdecoder, C.ZydisMachineMode(mm), C.ZydisAddressWidth(aw))
return d
}
// EnableMode enables/disables the given decoder mode.
func (d *Decoder) EnableMode(m DecoderMode, en bool) error {
enValue := 0
if en {
enValue = 1
}
ret := C.ZydisDecoderEnableMode(&d.zdecoder, C.ZydisDecoderMode(m), C.ZyanBool(enValue))
if zyanFailure(ret) {
return fmt.Errorf("zydis: error enabling mode: 0x%x", ret)
}
return nil
}
// Decode decodes the instruction in the given input buffer.
func (d *Decoder) Decode(buffer []byte) (*DecodedInstruction, error) {
var zinst C.ZydisDecodedInstruction
ret := C.ZydisDecoderDecodeBuffer(
&d.zdecoder,
unsafe.Pointer(&buffer[0]),
C.ZyanUSize(len(buffer)),
&zinst,
)
if zyanFailure(ret) {
return nil, fmt.Errorf("zydis: error decoding buffer: 0x%x", ret)
}
// Convert ZydisDecodedInstruction to a DecodedInstruction
return newInstructionFromZydis(&zinst), nil
}
func zyanFailure(zs C.ZyanStatus) bool {
return zs != C.statusSuccess
}
// DecoderMode is an enum of decoder modes.
type DecoderMode int
// DecoderMode enum values.
const (
// Enables minimal instruction decoding without semantic analysis.
//
// This mode provides access to the mnemonic, the instruction-length, the
// effective operand-size, the effective address-width, some attributes
// (e.g. `ZYDIS_ATTRIB_IS_RELATIVE`) and all of the information in the
// `raw` field of the `ZydisDecodedInstruction` struct.
//
// Operands, most attributes and other specific information (like `AVX`
// info) are not accessible in this mode.
//
// This mode is NOT enabled by default.
DecoderModeMinimal DecoderMode = iota
// Enables the `AMD`-branch mode.
//
// Intel ignores the operand-size override-prefix (`0x66`) for all branches with 32-bit
// immediates and forces the operand-size of the instruction to 64-bit in 64-bit mode.
// In `AMD`-branch mode `0x66` is not ignored and changes the operand-size and the size of the
// immediate to 16-bit.
//
// This mode is NOT enabled by default.
DecoderModeAMDBranches
// Enables `KNC` compatibility-mode.
//
// `KNC` and `KNL+` chips are sharing opcodes and encodings for some mask-related instructions.
// Enable this mode to use the old `KNC` specifications (different mnemonics, operands, ..).
//
// This mode is NOT enabled by default.
DecoderModeKNC
// Enables the `MPX` mode.
//
// The `MPX` isa-extension reuses (overrides) some of the widenop instruction opcodes.
//
// This mode is enabled by default.
DecoderModeMPX
// Enables the `CET` mode.
//
// The `CET` isa-extension reuses (overrides) some of the widenop instruction opcodes.
//
// This mode is enabled by default.
DecoderModeCET
// Enables the `LZCNT` mode.
//
// The `LZCNT` isa-extension reuses (overrides) some of the widenop instruction opcodes.
//
// This mode is enabled by default.
DecoderModeLZCNT
// Enables the `TZCNT` mode.
//
// The `TZCNT` isa-extension reuses (overrides) some of the widenop instruction opcodes.
//
// This mode is enabled by default.
DecoderModeTZCNT
// Enables the `WBNOINVD` mode.
//
// The `WBINVD` instruction is interpreted as `WBNOINVD` on ICL chips, if a `F3` prefix is
// used.
//
// This mode is disabled by default.
DecoderModeWBNOINVD
// Enables the `CLDEMOTE` mode.
//
// The `CLDEMOTE` isa-extension reuses (overrides) some of the widenop instruction opcodes.
//
// This mode is enabled by default.
DecoderModeCLDEMOTE
)