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
#![allow(non_camel_case_types)]
use bitflags::bitflags;
pub const API_MAJOR: u64 = 2;
pub const API_MINOR: u64 = 0;
pub const VERSION_MAJOR: u64 = 2;
pub const VERSION_MINOR: u64 = 0;
pub const VERSION_PATCH: u64 = 0;
pub const VERSION_EXTRA: u64 = 7;
pub const SECOND_SCALE: u64 = 1_000_000;
pub const MILISECOND_SCALE: u64 = 1_000;
#[repr(C)]
#[derive(PartialEq, Debug, Clone, Copy)]
#[allow(clippy::upper_case_acronyms)]
pub enum uc_error {
OK = 0,
NOMEM = 1,
ARCH = 2,
HANDLE = 3,
MODE = 4,
VERSION = 5,
READ_UNMAPPED = 6,
WRITE_UNMAPPED = 7,
FETCH_UNMAPPED = 8,
HOOK = 9,
INSN_INVALID = 10,
MAP = 11,
WRITE_PROT = 12,
READ_PROT = 13,
FETCH_PROT = 14,
ARG = 15,
READ_UNALIGNED = 16,
WRITE_UNALIGNED = 17,
FETCH_UNALIGNED = 18,
HOOK_EXIST = 19,
RESOURCE = 20,
EXCEPTION = 21,
}
#[repr(C)]
#[derive(PartialEq, Debug, Clone, Copy)]
pub enum MemType {
READ = 16,
WRITE = 17,
FETCH = 18,
READ_UNMAPPED = 19,
WRITE_UNMAPPED = 20,
FETCH_UNMAPPED = 21,
WRITE_PROT = 22,
READ_PROT = 23,
FETCH_PROT = 24,
READ_AFTER = 25,
}
bitflags! {
#[repr(C)]
pub struct HookType: i32 {
const INTR = 1;
const INSN = 2;
const CODE = 4;
const BLOCK = 8;
const MEM_READ_UNMAPPED = 0x10;
const MEM_WRITE_UNMAPPED = 0x20;
const MEM_FETCH_UNMAPPED = 0x40;
const MEM_UNMAPPED = Self::MEM_READ_UNMAPPED.bits | Self::MEM_WRITE_UNMAPPED.bits | Self::MEM_FETCH_UNMAPPED.bits;
const MEM_READ_PROT = 0x80;
const MEM_WRITE_PROT = 0x100;
const MEM_FETCH_PROT = 0x200;
const MEM_PROT = Self::MEM_READ_PROT.bits | Self::MEM_WRITE_PROT.bits | Self::MEM_FETCH_PROT.bits;
const MEM_READ = 0x400;
const MEM_WRITE = 0x800;
const MEM_FETCH = 0x1000;
const MEM_VALID = Self::MEM_READ.bits | Self::MEM_WRITE.bits | Self::MEM_FETCH.bits;
const MEM_READ_AFTER = 0x2000;
const INSN_INVALID = 0x4000;
const MEM_READ_INVALID = Self::MEM_READ_UNMAPPED.bits | Self::MEM_READ_PROT.bits;
const MEM_WRITE_INVALID = Self::MEM_WRITE_UNMAPPED.bits | Self::MEM_WRITE_PROT.bits;
const MEM_FETCH_INVALID = Self::MEM_FETCH_UNMAPPED.bits | Self::MEM_FETCH_PROT.bits;
const MEM_INVALID = Self::MEM_READ_INVALID.bits | Self::MEM_WRITE_INVALID.bits | Self::MEM_FETCH_INVALID.bits;
const MEM_ALL = Self::MEM_VALID.bits | Self::MEM_INVALID.bits;
}
}
#[repr(C)]
#[derive(PartialEq, Debug, Clone, Copy)]
#[allow(clippy::upper_case_acronyms)]
pub enum Query {
MODE = 1,
PAGE_SIZE = 2,
ARCH = 3,
TIMEOUT = 4,
}
bitflags! {
#[repr(C)]
pub struct Permission : u32 {
const NONE = 0;
const READ = 1;
const WRITE = 2;
const EXEC = 4;
const ALL = Self::READ.bits | Self::WRITE.bits | Self::EXEC.bits;
}
}
#[repr(C)]
#[derive(Debug, Clone)]
pub struct MemRegion {
pub begin: u64,
pub end: u64,
pub perms: Permission,
}
#[repr(C)]
#[derive(PartialEq, Debug, Clone, Copy)]
pub enum Arch {
ARM = 1,
ARM64 = 2,
MIPS = 3,
X86 = 4,
PPC = 5,
SPARC = 6,
M68K = 7,
RISCV = 8,
S390X = 9,
TRICORE = 10,
MAX = 11,
}
impl TryFrom<usize> for Arch {
type Error = uc_error;
fn try_from(v: usize) -> Result<Self, Self::Error> {
match v {
x if x == Self::ARM as usize => Ok(Self::ARM),
x if x == Self::ARM64 as usize => Ok(Self::ARM64),
x if x == Self::MIPS as usize => Ok(Self::MIPS),
x if x == Self::X86 as usize => Ok(Self::X86),
x if x == Self::PPC as usize => Ok(Self::PPC),
x if x == Self::SPARC as usize => Ok(Self::SPARC),
x if x == Self::M68K as usize => Ok(Self::M68K),
x if x == Self::RISCV as usize => Ok(Self::RISCV),
x if x == Self::S390X as usize => Ok(Self::S390X),
x if x == Self::TRICORE as usize => Ok(Self::TRICORE),
x if x == Self::MAX as usize => Ok(Self::MAX),
_ => Err(uc_error::ARCH),
}
}
}
bitflags! {
#[repr(C)]
pub struct Mode: i32 {
const LITTLE_ENDIAN = 0;
const BIG_ENDIAN = 0x4000_0000;
const ARM = 0;
const THUMB = 0x10;
const MCLASS = 0x20;
const V8 = 0x40;
const ARMBE8 = 0x400;
const ARM926 = 0x80;
const ARM946 = 0x100;
const ARM1176 = 0x200;
const MICRO = Self::THUMB.bits;
const MIPS3 = Self::MCLASS.bits;
const MIPS32R6 = Self::V8.bits;
const MIPS32 = 4;
const MIPS64 = 8;
const MODE_16 = 2;
const MODE_32 = Self::MIPS32.bits;
const MODE_64 = Self::MIPS64.bits;
const PPC32 = Self::MIPS32.bits;
const PPC64 = Self::MIPS64.bits;
const QPX = Self::THUMB.bits;
const SPARC32 = Self::MIPS32.bits;
const SPARC64 = Self::MIPS64.bits;
const V9 = Self::THUMB.bits;
const RISCV32 = Self::MIPS32.bits;
const RISCV64 = Self::MIPS64.bits;
}
}