从放寒假摆到现在,哈哈,再不学 re 👶要被开咯,本来想写写安洵杯的题的,结果从 pyc 开始后面全几把粪题,出题人自己都没玩明白,果断放弃(笑嘻了),RCTF 据说有个 unicorn ,之前大爹也说过 unicorn 模拟执行这个玩意儿,感觉很高级,找了一篇还能看的懂的年前起个头学一下。

什么是unicorn

一些官方翻译

Unicorn是一个轻量级,多平台,多架构的CPU模拟器框架,基于qemu开发,它可以代替CPU模拟代码的执行,就比如说我们需要调试某个程序,常见的调试器需要配置可执行文件需要的环境并且还需要考虑一些恶意代码导致的安全问题,但是通过unicorn我们就可以单纯的模拟代码的执行(甚至可以指定从某个地址开始执行)而不需要考虑这些问题。

它的亮点(这也归功于Unicorn是基于qemu而开发的)有:

  • 支持多种架构: Arm, Arm64 (Armv8), M68K, Mips, Sparc, & X86 (include X86_64).
  • 对Windows和nix系统(已确认包含Mac OSX, Linux, BSD & Solaris)的原生支持
  • 具有平台独立且简洁易于使用的API
  • 使用JIT编译技术, 性能表现优异

Unicorn 快速入门

摘自博客 汇编与反汇编神器Unicorn - 『移动安全区』 - 吾爱破解 - LCG - LSG |安卓破解|病毒分析|www.52pojie.cn

多架构

Unicorn 是一款基于qemu模拟器的模拟执行框架,支持Arm, Arm64 (Armv8), M68K, Mips, Sparc, & X86 (include X86_64)等指令集。

多语言

Unicorn 为多种语言提供编程接口比如C/C++、Python、Java 等语言。Unicorn的DLL 可以被更多的语言调用,比如易语言、Delphi,前途无量。

多线程安全

Unicorn 设计之初就考虑到线程安全问题,能够同时并发模拟执行代码,极大的提高了实用性。

虚拟内存

Unicorn 采用虚拟内存机制,使得虚拟CPU的内存与真实CPU的内存隔离。Unicorn 使用如下API来操作内存:

1
2
3
uc_mem_map
uc_mem_read
uc_mem_write

使用uc_mem_map映射内存的时候,address 与 size 都需要与0x1000对齐,也就是0x1000的整数倍,否则会报UC_ERR_ARG 异常。

Hook 机制

Unicorn的Hook机制为编程控制虚拟CPU提供了便利。
Unicorn 支持多种不同类型的Hook。
大致可以分为(hook_add第一参数,Unicorn常量):

指令执行类

1
2
3
4
UC_HOOK_INTR
UC_HOOK_INSN
UC_HOOK_CODE
UC_HOOK_BLOCK

内存访问类

1
2
3
4
5
6
7
8
UC_HOOK_MEM_READ
UC_HOOK_MEM_WRITE
UC_HOOK_MEM_FETCH
UC_HOOK_MEM_READ_AFTER
UC_HOOK_MEM_PROT
UC_HOOK_MEM_FETCH_INVALID
UC_HOOK_MEM_INVALID
UC_HOOK_MEM_VALID

异常处理类

1
2
3
UC_HOOK_MEM_READ_UNMAPPED
UC_HOOK_MEM_WRITE_UNMAPPED
UC_HOOK_MEM_FETCH_UNMAPPED

调用hook_add函数可添加一个Hook。Unicorn的Hook是链式的,而不是传统Hook的覆盖式,也就是说,可以同时添加多个同类型的Hook,Unicorn会依次调用每一个handler。hook callback 是有作用范围的(见hook_add begin参数)。

Task1

程序逻辑

一个 ELF 文件,打开以后自动输出flag,但是输出的越来越便秘

1674054916412

用 ida 分析一下发现是通过斐波那契数列拖慢程序执行速度并且和输出的 flag 之间进行绑定:

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
__int64 __fastcall main(int a1, char **a2, char **a3)
{
char *v3; // rbp
int v4; // ebx
__int64 v5; // r8
char v6; // r9
__int64 v7; // r8
char v8; // cl
int v10[7]; // [rsp+Ch] [rbp-1Ch] BYREF

v3 = (char *)&unk_4007E1;
v4 = 0;
setbuf(stdout, 0LL);
printf("The flag is: ");
while ( 1 )
{
LODWORD(v5) = 0;
do
{
v10[0] = 0;
fibonacci(v4 + v5, v10);
v8 = v7;
v5 = v7 + 1;
}
while ( v5 != 8 );
v4 += 8;
if ( (unsigned __int8)(v10[0] << v8) == v6 )
break;
++v3;
_IO_putc(v6 ^ (unsigned __int8)(LOBYTE(v10[0]) << v8), stdout);
}
_IO_putc(10, stdout);
return 0LL;
}

可以考虑把整个程序重写一遍然后优化一下,但是对于这道题来说有些麻烦,我们考虑用unicorn来获得 flag。(好吧对于我来说这个方法更麻烦)

unicorn模拟执行

使用Unicorn引擎之前需要手动初始化内存,我们需要初始化所有的寄存器,把这段代码装载到某个地方,并且分配一段栈空间,同时在执行代码之前我们还得在模拟执行之前加入hook函数,参数如下:

  • Uc实例句柄
  • 指令的地址
  • 执行的长度
  • 用户自定义数据(我们可以在hook_add的可选参数中传递这个值)

具体代码如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
from unicorn import * # 加载主要的二进制模块和一些Unicorn中的一些基本常量
from unicorn.x86_const import * # 加载一些特定的x86和x64的常量
from pwn import * # 这里主要用到 u32 和 p32 两个函数,u32将4字节的string转换为integer,以小端序表示这个数据,p32与u32相反

mu = Uc(UC_ARCH_X86, UC_MODE_64) # 第一个参数:架构类型,第二个参数:架构细节说明,为x86-64架构初始化一下Unicorn引擎
BASE_ADDR = 0x400000 # 基址
STACK_ADDR = 0x0 # 栈地址
STACK_SIZE = 1024 * 1024 # 栈空间

mu.mem_map(BASE_ADDR, 1024 * 1024)
mu.mem_map(STACK_ADDR, STACK_SIZE) # mem_map函数来映射内存
mu.mem_write(BASE_ADDR, read("./fibonacci")) # read仅仅返回文件中的内容,加载二进制文件到基址上
mu.reg_write(UC_X86_REG_RSP, STACK_ADDR + STACK_SIZE - 1) # 初始化RSP寄存器指向栈底(倒着的)

def hook_code(mu, address, size, user_data): # 在启动之前写一个hook函数来输出我们需要的信息
print('>>> Tracing instruction at 0x%x, instruction size = 0x%x' % (address, size))

mu.hook_add(UC_HOOK_CODE, hook_code) # 添加hook
mu.emu_start(0x4004E0, 0x400575) # 启动模拟执行,起始从main函数开始,遇到while循坏外面的IO_putc结束

执行该文件,我们就可以获取从main函数开始每一步指令的地址和指令大小

1674056409459

并且我们也知道了从 0x3003EF这个地方出现了问题,我们看一眼这里是个啥代码

1674056457576

1674056660721

这里的stdout是 bss 段的,但是我们并没有分配该区段,所以会报错,同时这一行对我们的模拟执行并没有影响,我们可以将其地址加入黑名单,遇到了直接跳过即可,此外,对于其它的会报错但是我们不需要的指令我们采用同样的方法进行跳过。

1
2
3
4
.text:0x4004EF                 mov     rdi, cs:stdout  ; stream
.text:0x4004F6 call _setbuf
.text:0x400502 call _printf
.text:0x40054F mov rsi, cs:stdout ; fp

我们采用修改 RIP 寄存器的方法进行指令的跳过:

1
mu.reg_write(UC_X86_REG_RIP, address + size)

同时修改 hook 函数,先判断 instruction 是否在黑名单中,之后我们需要关注的就是输出 flag,由于 IO_putc 会把输出结果暂存到 RDI 寄存器中,我们直接打印 RDI 寄存器的内容即可,得到如下代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
from unicorn import * # 加载主要的二进制模块和一些Unicorn中的一些基本常量
from unicorn.x86_const import * # 加载一些特定的x86和x64的常量
from pwn import * # 这里主要用到 u32 和 p32 两个函数,u32将4字节的string转换为integer,以小端序表示这个数据,p32与u32相反

mu = Uc(UC_ARCH_X86, UC_MODE_64) # 第一个参数:架构类型,第二个参数:架构细节说明,为x86-64架构初始化一下Unicorn引擎
BASE_ADDR = 0x400000 # 基址
STACK_ADDR = 0x0 # 栈地址
STACK_SIZE = 1024 * 1024 # 栈空间
mu.mem_map(BASE_ADDR, 1024 * 1024)
mu.mem_map(STACK_ADDR, STACK_SIZE) # mem_map函数来映射内存
mu.mem_write(BASE_ADDR, read("./fibonacci")) # read仅仅返回文件中的内容,加载二进制文件到基址上
mu.reg_write(UC_X86_REG_RSP, STACK_ADDR + STACK_SIZE - 1) # 初始化RSP寄存器指向栈底(倒着的)

Inst_skip_list = [0x4004EF, 0x4004F6, 0x400502, 0x40054F] # 需要跳过的黑名单
def hook_code(mu, address, size, user_data): # 在启动之前写一个hook函数来输出我们需要的信息
#print('>>> Tracing instruction at 0x%x, instruction size = 0x%x' % (address, size))
if address in Inst_skip_list: # 遇到了就跳过避免报错
mu.reg_write(UC_X86_REG_RIP, address + size)
elif address == 0x400560: # 如果遇到了输出函数就打印输出的内容
flag = mu.reg_read(UC_X86_REG_RDI)
print((chr(flag)), end = "")
mu.reg_write(UC_X86_REG_RIP, address + size)
mu.hook_add(UC_HOOK_CODE, hook_code) # 添加hook
mu.emu_start(0x4004E0, 0x400575) # 启动模拟执行

此时我们可以通过模拟执行来实现对 main 函数的模拟,但是却并没有解决 flag 输出便秘的问题。

1674057234095

那么如何提高程序执行的效率呢?

修改hook函数提高效率

根据之前的分析,斐波那契函数是一个递归函数,而且在该程序中反复调用,当所求项数越来越大,那么程序运行必然也越来越慢,且时间呈指数级上升,此时如果我们采用记忆化搜索的方法,那么就可以大大提升数列的求解效率。

我们可以看到 fibonacci 这个函数有两个参数

1674057879022

第一个参数在进入的时候存在 EDI 寄存器中,第二个参数是一个指针,用 RSI 寄存器储存,同时返回值也有两个,第一个存在 RAX 寄存器中,第二个就是指针存在 RSI 寄存器中。

我们考虑用一个 dp 数组来存储这两个参数,并在入口处判断输入进该函数的两个参数之前是否被访问过,如果被访问过就直接 return 相应的返回值,否则就执行该函数并且记录下该参数对应的返回值。

由于这是一个递归过程,我们还需要用一个栈来存储每个参数对应的返回值,此外,也是由于递归的特性,我们在返回的时候由于函数本身处于hook中,所以我们需要从其它没有被hook的函数中随便找一个retn指令进行返回。

基于上述分析得到最终的 exp:

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
from unicorn import * # 加载主要的二进制模块和一些Unicorn中的一些基本常量
from unicorn.x86_const import * # 加载一些特定的x86和x64的常量
from pwn import * # 这里主要用到 u32 和 p32 两个函数,u32将4字节的string转换为integer,以小端序表示这个数据,p32与u32相反

mu = Uc(UC_ARCH_X86, UC_MODE_64) # 第一个参数:架构类型,第二个参数:架构细节说明,为x86-64架构初始化一下Unicorn引擎
BASE_ADDR = 0x400000 # 基址
STACK_ADDR = 0x0 # 栈地址
STACK_SIZE = 1024 * 1024 # 栈空间

mu.mem_map(BASE_ADDR, 1024 * 1024)
mu.mem_map(STACK_ADDR, STACK_SIZE) # mem_map函数来映射内存
mu.mem_write(BASE_ADDR, read("./fibonacci")) # read仅仅返回文件中的内容,加载二进制文件到基址上
mu.reg_write(UC_X86_REG_RSP, STACK_ADDR + STACK_SIZE - 1) # 初始化RSP寄存器指向栈底(倒着的)

Inst_skip_list = [0x4004EF, 0x4004F6, 0x400502, 0x40054F]
FIBONACCI_ENTRY = 0x400670

stack = []
dp = {}
FIBONACCI_ENTRY = 0x400670
FIBONACCI_END = [0x4006F1, 0x400709]

def hook_code(mu, address, size, user_data): # 在启动之前写一个hook函数来输出我们需要的信息
#print('>>> Tracing instruction at 0x%x, instruction size = 0x%x' % (address, size))
if address in Inst_skip_list: # 遇到了就跳过避免报错
mu.reg_write(UC_X86_REG_RIP, address + size)
elif address == 0x400560: # 如果遇到了输出函数就打印输出的内容
flag = mu.reg_read(UC_X86_REG_RDI)
print((chr(flag)), end = "")
mu.reg_write(UC_X86_REG_RIP, address + size)
elif address == FIBONACCI_ENTRY: # 遇到fibonacci函数的入口
# 把参数存储下来
arg0 = mu.reg_read(UC_X86_REG_RDI)
rsi = mu.reg_read(UC_X86_REG_RSI) # 用rsi存储地址,这里是间接寻址,(rsi)是数据
arg1 = u32(mu.mem_read(rsi, 4))
# 判断参数是否被访问过,如果被访问过就把dp数组中的第一个参数赋给RAX寄存器,第二个参数的数据写入rsi指向的地址中
if (arg0, arg1) in dp:
(ret_rax, ret_ref) = dp[(arg0, arg1)]
mu.reg_write(UC_X86_REG_RAX, ret_rax)
mu.mem_write(rsi, p32(ret_ref))
mu.reg_write(UC_X86_REG_RIP, 0x400582) # 由于此时fibonacci这个函数还在被hook中,所以不能跳转到该函数本身的ret指令
else:
stack.append((arg0, arg1, rsi)) # 不在dp数组中就入栈
elif address in FIBONACCI_END: # 遇到fibonacci函数的出口,从栈顶拿出数据建立dp数组的映射
(arg0, arg1, rsi) = stack.pop()
ret_rax = mu.reg_read(UC_X86_REG_RAX)
ret_ref = u32(mu.mem_read(rsi, 4))
dp[(arg0, arg1)] = (ret_rax, ret_ref)

mu.hook_add(UC_HOOK_CODE, hook_code) # 添加hook
mu.emu_start(0x4004E0, 0x400575) # 启动模拟执行

此时再运行我们就可以得到 flag hxp{F1b0n4cCi_numZ_4r3_T0O_3a5Y}

Task2

1
2
shellcode = b"\xe8\xff\xff\xff\xff\xc0\x5d\x6a\x05\x5b\x29\xdd\x83\xc5\x4e\x89\xe9\x6a\x02\x03\x0c\x24\x5b\x31\xd2\x66\xba\x12\x00\x8b\x39\xc1\xe7\x10\xc1\xef\x10\x81\xe9\xfe\xff\xff\xff\x8b\x45\x00\xc1\xe0\x10\xc1\xe8\x10\x89\xc3\x09\xfb\x21\xf8\xf7\xd0\x21\xd8\x66\x89\x45\x00\x83\xc5\x02\x4a\x85\xd2\x0f\x85\xcf\xff\xff\xff\xec\x37\x75\x5d\x7a\x05\x28\xed\x24\xed\x24\xed\x0b\x88\x7f\xeb\x50\x98\x38\xf9\x5c\x96\x2b\x96\x70\xfe\xc6\xff\xc6\xff\x9f\x32\x1f\x58\x1e\x00\xd3\x80"

一些hint

注意:代码基于x86-32架构。syscall 的调用号所对应的功能可以在这里找到

你可以HOOKint 80h指令,二进制代码是cd 80,然后读取寄存器和内存。请记住,shellcode是可以在任何地址被加载执行的代码,绝大多数的shellcode使用栈来执行。

shellcode转汇编

1675429793726

得到的汇编语言如下:

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
 0:    e8 ff ff ff ff           call   0x4
5: c0 5d 6a 05 rcr BYTE PTR [ebp+0x6a], 0x5
9: 5b pop ebx
a: 29 dd sub ebp, ebx
c: 83 c5 4e add ebp, 0x4e
f: 89 e9 mov ecx, ebp
11: 6a 02 push 0x2
13: 03 0c 24 add ecx, DWORD PTR [esp]
16: 5b pop ebx
17: 31 d2 xor edx, edx
19: 66 ba 12 00 mov dx, 0x12
1d: 8b 39 mov edi, DWORD PTR [ecx]
1f: c1 e7 10 shl edi, 0x10
22: c1 ef 10 shr edi, 0x10
25: 81 e9 fe ff ff ff sub ecx, 0xfffffffe
2b: 8b 45 00 mov eax, DWORD PTR [ebp+0x0]
2e: c1 e0 10 shl eax, 0x10
31: c1 e8 10 shr eax, 0x10
34: 89 c3 mov ebx, eax
36: 09 fb or ebx, edi
38: 21 f8 and eax, edi
3a: f7 d0 not eax
3c: 21 d8 and eax, ebx
3e: 66 89 45 00 mov WORD PTR [ebp+0x0], ax
42: 83 c5 02 add ebp, 0x2
45: 4a dec edx
46: 85 d2 test edx, edx
48: 0f 85 cf ff ff ff jne 0x1d
4e: ec in al, dx
4f: 37 aaa
50: 75 5d jne 0xaf
52: 7a 05 jp 0x59
54: 28 ed sub ch, ch
56: 24 ed and al, 0xed
58: 24 ed and al, 0xed
5a: 0b 88 7f eb 50 98 or ecx, DWORD PTR [eax-0x67af1481]
60: 38 f9 cmp cl, bh
62: 5c pop esp
63: 96 xchg esi, eax
64: 2b 96 70 fe c6 ff sub edx, DWORD PTR [esi-0x390190]
6a: c6 (bad)
6b: ff 9f 32 1f 58 1e call FWORD PTR [edi+0x1e581f32]
71: 00 d3 add bl, dl
73: 80 .byte 0x80

unicorn模拟执行

可以看到汇编的最下面是一条 int 80语句,那么我们对其进行hook,在遇到 int 80 指令的时候输出 syscall 的调用号来确定程序都进行了哪些调用,通过查询汇编可知,在进行 syscall 调用时, eax 寄存器存的是调用号。

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
from unicorn import *
from unicorn.x86_const import *

shellcode = b"\xe8\xff\xff\xff\xff\xc0\x5d\x6a\x05\x5b\x29\xdd\x83\xc5\x4e\x89\xe9\x6a\x02\x03\x0c\x24\x5b\x31\xd2\x66\xba\x12\x00\x8b\x39\xc1\xe7\x10\xc1\xef\x10\x81\xe9\xfe\xff\xff\xff\x8b\x45\x00\xc1\xe0\x10\xc1\xe8\x10\x89\xc3\x09\xfb\x21\xf8\xf7\xd0\x21\xd8\x66\x89\x45\x00\x83\xc5\x02\x4a\x85\xd2\x0f\x85\xcf\xff\xff\xff\xec\x37\x75\x5d\x7a\x05\x28\xed\x24\xed\x24\xed\x0b\x88\x7f\xeb\x50\x98\x38\xf9\x5c\x96\x2b\x96\x70\xfe\xc6\xff\xc6\xff\x9f\x32\x1f\x58\x1e\x00\xd3\x80"

BASE = 0x400000
STACK_ADDR = 0x0
STACK_SIZE = 1024 * 1024

mu = Uc(UC_ARCH_X86, UC_MODE_32)

mu.mem_map(BASE, 1024 * 1024)
mu.mem_map(STACK_ADDR, STACK_SIZE)

mu.mem_write(BASE, shellcode)
mu.reg_write(UC_X86_REG_ESP, STACK_ADDR + STACK_SIZE)

def hook_code(mu, address, size, user_data):
#print('>>> Tracing instruction at 0x%x, instruction size = 0x%x' %(address, size))

machine_code = mu.mem_read(address, size)

if (machine_code == b"\xcd\x80"): # 对 int 8 指令进行hook
r_eax = mu.reg_read(UC_X86_REG_EAX) # dump eax 寄存器
print("intercepted system call: " + str(r_eax))
mu.reg_write(UC_X86_REG_EIP, address + size) # 跳过int8指令

mu.hook_add(UC_HOOK_CODE, hook_code)
mu.emu_start(BASE, BASE - 1)

1675432495733

打印 chmod 和 exit 的参数

通过对照发现是 chmodexit 两个系统调用,修改 hook 函数对其进行特判输出详细信息,同时结合汇编一共用到了 eax, ebx, ecx, edx 四个寄存器存储对应调用的参数,我们也把这几个寄存器的数据给 dump 下来。

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
from unicorn import *
from unicorn.x86_const import *

shellcode = b"\xe8\xff\xff\xff\xff\xc0\x5d\x6a\x05\x5b\x29\xdd\x83\xc5\x4e\x89\xe9\x6a\x02\x03\x0c\x24\x5b\x31\xd2\x66\xba\x12\x00\x8b\x39\xc1\xe7\x10\xc1\xef\x10\x81\xe9\xfe\xff\xff\xff\x8b\x45\x00\xc1\xe0\x10\xc1\xe8\x10\x89\xc3\x09\xfb\x21\xf8\xf7\xd0\x21\xd8\x66\x89\x45\x00\x83\xc5\x02\x4a\x85\xd2\x0f\x85\xcf\xff\xff\xff\xec\x37\x75\x5d\x7a\x05\x28\xed\x24\xed\x24\xed\x0b\x88\x7f\xeb\x50\x98\x38\xf9\x5c\x96\x2b\x96\x70\xfe\xc6\xff\xc6\xff\x9f\x32\x1f\x58\x1e\x00\xd3\x80"

BASE = 0x400000
STACK_ADDR = 0x0
STACK_SIZE = 1024 * 1024

mu = Uc(UC_ARCH_X86, UC_MODE_32)

mu.mem_map(BASE, 1024 * 1024)
mu.mem_map(STACK_ADDR, STACK_SIZE)

mu.mem_write(BASE, shellcode)
mu.reg_write(UC_X86_REG_ESP, STACK_ADDR + STACK_SIZE)


def syscall_num_to_name(num): # 一共只有两种syscall
syscalls = {1: "sys_exit", 15: "sys_chmod"}
return syscalls[num]


def hook_code(mu, address, size, user_data):
#print('>>> Tracing instruction at 0x%x, instruction size = 0x%x' %(address, size))

machine_code = mu.mem_read(address, size)

if (machine_code == b"\xcd\x80"): # 对 int 8 指令进行hook
r_eax = mu.reg_read(UC_X86_REG_EAX) # dump 需要用的寄存器
r_ebx = mu.reg_read(UC_X86_REG_EBX)
r_ecx = mu.reg_read(UC_X86_REG_ECX)
r_edx = mu.reg_read(UC_X86_REG_EDX)
syscall_name = syscall_num_to_name(r_eax)

print("--------------")
print("intercepted system call: " + syscall_name)

if(syscall_name == "sys_chmod"): # 输出 chmod 的参数
s = mu.mem_read(r_ebx, 20).split(b"\x00")[0]
print("arg0 = 0x%x -> %s" % (r_ebx, s))
print("arg1 = " + oct(r_ecx))
print("--------------")
elif(syscall_name == "sys_exit"):
print("arg0 = " + hex(r_ebx))
print("--------------")
exit()

mu.reg_write(UC_X86_REG_EIP, address + size) # 跳过int8指令

mu.hook_add(UC_HOOK_CODE, hook_code)

mu.emu_start(BASE, BASE - 1)

1675435047056

输出程序流

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
from unicorn import *
from unicorn.x86_const import *
from capstone import *

shellcode = b"\xe8\xff\xff\xff\xff\xc0\x5d\x6a\x05\x5b\x29\xdd\x83\xc5\x4e\x89\xe9\x6a\x02\x03\x0c\x24\x5b\x31\xd2\x66\xba\x12\x00\x8b\x39\xc1\xe7\x10\xc1\xef\x10\x81\xe9\xfe\xff\xff\xff\x8b\x45\x00\xc1\xe0\x10\xc1\xe8\x10\x89\xc3\x09\xfb\x21\xf8\xf7\xd0\x21\xd8\x66\x89\x45\x00\x83\xc5\x02\x4a\x85\xd2\x0f\x85\xcf\xff\xff\xff\xec\x37\x75\x5d\x7a\x05\x28\xed\x24\xed\x24\xed\x0b\x88\x7f\xeb\x50\x98\x38\xf9\x5c\x96\x2b\x96\x70\xfe\xc6\xff\xc6\xff\x9f\x32\x1f\x58\x1e\x00\xd3\x80"

BASE = 0x400000
STACK_ADDR = 0x0
STACK_SIZE = 1024 * 1024

md = Cs(CS_ARCH_X86, CS_MODE_32)
mu = Uc(UC_ARCH_X86, UC_MODE_32)

mu.mem_map(BASE, 1024 * 1024)
mu.mem_map(STACK_ADDR, STACK_SIZE)

mu.mem_write(BASE, shellcode)
mu.reg_write(UC_X86_REG_ESP, STACK_ADDR + STACK_SIZE)


def syscall_num_to_name(num):
syscalls = {1: "sys_exit", 15: "sys_chmod"}
return syscalls[num]


def hook_code(mu, address, size, user_data):
#print('>>> Tracing instruction at 0x%x, instruction size = 0x%x' %(address, size))

machine_code = mu.mem_read(address, size)

for code in md.disasm(machine_code,address):
print(" 0x%x:\t%s\t%s" % (code.address, code.mnemonic, code.op_str))

if (machine_code == b"\xcd\x80"):
r_eax = mu.reg_read(UC_X86_REG_EAX)
r_ebx = mu.reg_read(UC_X86_REG_EBX)
r_ecx = mu.reg_read(UC_X86_REG_ECX)
r_edx = mu.reg_read(UC_X86_REG_EDX)
syscall_name = syscall_num_to_name(r_eax)

print("--------------")
print("intercepted system call: " + syscall_name)

if(syscall_name == "sys_chmod"):
s = mu.mem_read(r_ebx, 20).split(b"\x00")[0]
print("arg0 = 0x%x -> %s" % (r_ebx, s))
print("arg1 = " + oct(r_ecx))
print("--------------")
elif(syscall_name == "sys_exit"):
print("arg0 = " + hex(r_ebx))
print("--------------")
exit()

mu.reg_write(UC_X86_REG_EIP, address + size)

mu.hook_add(UC_HOOK_CODE, hook_code)

mu.emu_start(BASE, BASE - 1)
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
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
     0x400000:	call	0x400004
0x400004: inc eax
0x400006: pop ebp
0x400007: push 5
0x400009: pop ebx
0x40000a: sub ebp, ebx
0x40000c: add ebp, 0x4e
0x40000f: mov ecx, ebp
0x400011: push 2
0x400013: add ecx, dword ptr [esp]
0x400016: pop ebx
0x400017: xor edx, edx
0x400019: mov dx, 0x12
0x40001d: mov edi, dword ptr [ecx]
0x40001f: shl edi, 0x10
0x400022: shr edi, 0x10
0x400025: sub ecx, 0xfffffffe
0x40002b: mov eax, dword ptr [ebp]
0x40002e: shl eax, 0x10
0x400031: shr eax, 0x10
0x400034: mov ebx, eax
0x400036: or ebx, edi
0x400038: and eax, edi
0x40003a: not eax
0x40003c: and eax, ebx
0x40003e: mov word ptr [ebp], ax
0x400042: add ebp, 2
0x400045: dec edx
0x400046: test edx, edx
0x400048: jne 0x40001d
0x40001d: mov edi, dword ptr [ecx]
0x40001f: shl edi, 0x10
0x400022: shr edi, 0x10
0x400025: sub ecx, 0xfffffffe
0x40002b: mov eax, dword ptr [ebp]
0x40002e: shl eax, 0x10
0x400031: shr eax, 0x10
0x400034: mov ebx, eax
0x400036: or ebx, edi
0x400038: and eax, edi
0x40003a: not eax
0x40003c: and eax, ebx
0x40003e: mov word ptr [ebp], ax
0x400042: add ebp, 2
0x400045: dec edx
0x400046: test edx, edx
0x400048: jne 0x40001d
0x40001d: mov edi, dword ptr [ecx]
0x40001f: shl edi, 0x10
0x400022: shr edi, 0x10
0x400025: sub ecx, 0xfffffffe
0x40002b: mov eax, dword ptr [ebp]
0x40002e: shl eax, 0x10
0x400031: shr eax, 0x10
0x400034: mov ebx, eax
0x400036: or ebx, edi
0x400038: and eax, edi
0x40003a: not eax
0x40003c: and eax, ebx
0x40003e: mov word ptr [ebp], ax
0x400042: add ebp, 2
0x400045: dec edx
0x400046: test edx, edx
0x400048: jne 0x40001d
0x40001d: mov edi, dword ptr [ecx]
0x40001f: shl edi, 0x10
0x400022: shr edi, 0x10
0x400025: sub ecx, 0xfffffffe
0x40002b: mov eax, dword ptr [ebp]
0x40002e: shl eax, 0x10
0x400031: shr eax, 0x10
0x400034: mov ebx, eax
0x400036: or ebx, edi
0x400038: and eax, edi
0x40003a: not eax
0x40003c: and eax, ebx
0x40003e: mov word ptr [ebp], ax
0x400042: add ebp, 2
0x400045: dec edx
0x400046: test edx, edx
0x400048: jne 0x40001d
0x40001d: mov edi, dword ptr [ecx]
0x40001f: shl edi, 0x10
0x400022: shr edi, 0x10
0x400025: sub ecx, 0xfffffffe
0x40002b: mov eax, dword ptr [ebp]
0x40002e: shl eax, 0x10
0x400031: shr eax, 0x10
0x400034: mov ebx, eax
0x400036: or ebx, edi
0x400038: and eax, edi
0x40003a: not eax
0x40003c: and eax, ebx
0x40003e: mov word ptr [ebp], ax
0x400042: add ebp, 2
0x400045: dec edx
0x400046: test edx, edx
0x400048: jne 0x40001d
0x40001d: mov edi, dword ptr [ecx]
0x40001f: shl edi, 0x10
0x400022: shr edi, 0x10
0x400025: sub ecx, 0xfffffffe
0x40002b: mov eax, dword ptr [ebp]
0x40002e: shl eax, 0x10
0x400031: shr eax, 0x10
0x400034: mov ebx, eax
0x400036: or ebx, edi
0x400038: and eax, edi
0x40003a: not eax
0x40003c: and eax, ebx
0x40003e: mov word ptr [ebp], ax
0x400042: add ebp, 2
0x400045: dec edx
0x400046: test edx, edx
0x400048: jne 0x40001d
0x40001d: mov edi, dword ptr [ecx]
0x40001f: shl edi, 0x10
0x400022: shr edi, 0x10
0x400025: sub ecx, 0xfffffffe
0x40002b: mov eax, dword ptr [ebp]
0x40002e: shl eax, 0x10
0x400031: shr eax, 0x10
0x400034: mov ebx, eax
0x400036: or ebx, edi
0x400038: and eax, edi
0x40003a: not eax
0x40003c: and eax, ebx
0x40003e: mov word ptr [ebp], ax
0x400042: add ebp, 2
0x400045: dec edx
0x400046: test edx, edx
0x400048: jne 0x40001d
0x40001d: mov edi, dword ptr [ecx]
0x40001f: shl edi, 0x10
0x400022: shr edi, 0x10
0x400025: sub ecx, 0xfffffffe
0x40002b: mov eax, dword ptr [ebp]
0x40002e: shl eax, 0x10
0x400031: shr eax, 0x10
0x400034: mov ebx, eax
0x400036: or ebx, edi
0x400038: and eax, edi
0x40003a: not eax
0x40003c: and eax, ebx
0x40003e: mov word ptr [ebp], ax
0x400042: add ebp, 2
0x400045: dec edx
0x400046: test edx, edx
0x400048: jne 0x40001d
0x40001d: mov edi, dword ptr [ecx]
0x40001f: shl edi, 0x10
0x400022: shr edi, 0x10
0x400025: sub ecx, 0xfffffffe
0x40002b: mov eax, dword ptr [ebp]
0x40002e: shl eax, 0x10
0x400031: shr eax, 0x10
0x400034: mov ebx, eax
0x400036: or ebx, edi
0x400038: and eax, edi
0x40003a: not eax
0x40003c: and eax, ebx
0x40003e: mov word ptr [ebp], ax
0x400042: add ebp, 2
0x400045: dec edx
0x400046: test edx, edx
0x400048: jne 0x40001d
0x40001d: mov edi, dword ptr [ecx]
0x40001f: shl edi, 0x10
0x400022: shr edi, 0x10
0x400025: sub ecx, 0xfffffffe
0x40002b: mov eax, dword ptr [ebp]
0x40002e: shl eax, 0x10
0x400031: shr eax, 0x10
0x400034: mov ebx, eax
0x400036: or ebx, edi
0x400038: and eax, edi
0x40003a: not eax
0x40003c: and eax, ebx
0x40003e: mov word ptr [ebp], ax
0x400042: add ebp, 2
0x400045: dec edx
0x400046: test edx, edx
0x400048: jne 0x40001d
0x40001d: mov edi, dword ptr [ecx]
0x40001f: shl edi, 0x10
0x400022: shr edi, 0x10
0x400025: sub ecx, 0xfffffffe
0x40002b: mov eax, dword ptr [ebp]
0x40002e: shl eax, 0x10
0x400031: shr eax, 0x10
0x400034: mov ebx, eax
0x400036: or ebx, edi
0x400038: and eax, edi
0x40003a: not eax
0x40003c: and eax, ebx
0x40003e: mov word ptr [ebp], ax
0x400042: add ebp, 2
0x400045: dec edx
0x400046: test edx, edx
0x400048: jne 0x40001d
0x40001d: mov edi, dword ptr [ecx]
0x40001f: shl edi, 0x10
0x400022: shr edi, 0x10
0x400025: sub ecx, 0xfffffffe
0x40002b: mov eax, dword ptr [ebp]
0x40002e: shl eax, 0x10
0x400031: shr eax, 0x10
0x400034: mov ebx, eax
0x400036: or ebx, edi
0x400038: and eax, edi
0x40003a: not eax
0x40003c: and eax, ebx
0x40003e: mov word ptr [ebp], ax
0x400042: add ebp, 2
0x400045: dec edx
0x400046: test edx, edx
0x400048: jne 0x40001d
0x40001d: mov edi, dword ptr [ecx]
0x40001f: shl edi, 0x10
0x400022: shr edi, 0x10
0x400025: sub ecx, 0xfffffffe
0x40002b: mov eax, dword ptr [ebp]
0x40002e: shl eax, 0x10
0x400031: shr eax, 0x10
0x400034: mov ebx, eax
0x400036: or ebx, edi
0x400038: and eax, edi
0x40003a: not eax
0x40003c: and eax, ebx
0x40003e: mov word ptr [ebp], ax
0x400042: add ebp, 2
0x400045: dec edx
0x400046: test edx, edx
0x400048: jne 0x40001d
0x40001d: mov edi, dword ptr [ecx]
0x40001f: shl edi, 0x10
0x400022: shr edi, 0x10
0x400025: sub ecx, 0xfffffffe
0x40002b: mov eax, dword ptr [ebp]
0x40002e: shl eax, 0x10
0x400031: shr eax, 0x10
0x400034: mov ebx, eax
0x400036: or ebx, edi
0x400038: and eax, edi
0x40003a: not eax
0x40003c: and eax, ebx
0x40003e: mov word ptr [ebp], ax
0x400042: add ebp, 2
0x400045: dec edx
0x400046: test edx, edx
0x400048: jne 0x40001d
0x40001d: mov edi, dword ptr [ecx]
0x40001f: shl edi, 0x10
0x400022: shr edi, 0x10
0x400025: sub ecx, 0xfffffffe
0x40002b: mov eax, dword ptr [ebp]
0x40002e: shl eax, 0x10
0x400031: shr eax, 0x10
0x400034: mov ebx, eax
0x400036: or ebx, edi
0x400038: and eax, edi
0x40003a: not eax
0x40003c: and eax, ebx
0x40003e: mov word ptr [ebp], ax
0x400042: add ebp, 2
0x400045: dec edx
0x400046: test edx, edx
0x400048: jne 0x40001d
0x40001d: mov edi, dword ptr [ecx]
0x40001f: shl edi, 0x10
0x400022: shr edi, 0x10
0x400025: sub ecx, 0xfffffffe
0x40002b: mov eax, dword ptr [ebp]
0x40002e: shl eax, 0x10
0x400031: shr eax, 0x10
0x400034: mov ebx, eax
0x400036: or ebx, edi
0x400038: and eax, edi
0x40003a: not eax
0x40003c: and eax, ebx
0x40003e: mov word ptr [ebp], ax
0x400042: add ebp, 2
0x400045: dec edx
0x400046: test edx, edx
0x400048: jne 0x40001d
0x40001d: mov edi, dword ptr [ecx]
0x40001f: shl edi, 0x10
0x400022: shr edi, 0x10
0x400025: sub ecx, 0xfffffffe
0x40002b: mov eax, dword ptr [ebp]
0x40002e: shl eax, 0x10
0x400031: shr eax, 0x10
0x400034: mov ebx, eax
0x400036: or ebx, edi
0x400038: and eax, edi
0x40003a: not eax
0x40003c: and eax, ebx
0x40003e: mov word ptr [ebp], ax
0x400042: add ebp, 2
0x400045: dec edx
0x400046: test edx, edx
0x400048: jne 0x40001d
0x40001d: mov edi, dword ptr [ecx]
0x40001f: shl edi, 0x10
0x400022: shr edi, 0x10
0x400025: sub ecx, 0xfffffffe
0x40002b: mov eax, dword ptr [ebp]
0x40002e: shl eax, 0x10
0x400031: shr eax, 0x10
0x400034: mov ebx, eax
0x400036: or ebx, edi
0x400038: and eax, edi
0x40003a: not eax
0x40003c: and eax, ebx
0x40003e: mov word ptr [ebp], ax
0x400042: add ebp, 2
0x400045: dec edx
0x400046: test edx, edx
0x400048: jne 0x40001d
0x40004e: cdq
0x40004f: push 0xf
0x400051: pop eax
0x400052: push edx
0x400053: call 0x400064
0x400064: pop ebx
0x400065: push 0x1b6
0x40006a: pop ecx
0x40006b: int 0x80
--------------
intercepted system call: sys_chmod
arg0 = 0x400058 -> bytearray(b'/etc/shadow')
arg1 = 0o666
--------------
0x40006d: push 1
0x40006f: pop eax
0x400070: int 0x80
--------------
intercepted system call: sys_exit
arg0 = 0x400058
--------------

Task3

程序分析

用 ida 分析,源码很简,只有一个比较函数,任务就是让这个函数返回 1

1
2
3
4
5
6
7
8
9
10
_BOOL4 __stdcall super_function(int a1, int a2)
{
return a1 == 5 && !strcmp(a2, "batman");
}

int __cdecl main(int argc, const char **argv, const char **envp)
{
super_function(1, "spiderman");
return 0;
}

发现传进去的整形和字符串都不一样,显然要 patch,之前我们的模拟执行是在不干涉程序流的前提下对程序进行 hook,这个 task 显然就是要我们使用 unicorn 进行patch,在修改完对应的数据以后再运行。

照例看下程序流:

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
from unicorn import *
from unicorn.x86_const import *
from pwn import *
from capstone import *

md = Cs(CS_ARCH_X86, CS_MODE_32)
mu = Uc(UC_ARCH_X86, UC_MODE_32)

BASE_ADDR = 0x0
STACK_ADDR = 0x400000
STACK_SIZE = 1024 * 1024

mu.mem_map(BASE_ADDR, 1024 * 1024)
mu.mem_map(STACK_ADDR, STACK_SIZE)
mu.mem_write(BASE_ADDR, read("./function"))
mu.reg_write(UC_X86_REG_ESP, STACK_ADDR + STACK_SIZE - 12)

def hook_code(mu, address, size, user_data):

machine_code = mu.mem_read(address, size)
for code in md.disasm(machine_code,address):
print(" 0x%x:\t%s\t%s" % (code.address, code.mnemonic, code.op_str))

mu.hook_add(UC_HOOK_CODE, hook_code)
mu.emu_start(0x57B, 0x5B1)

1675440200104

通过动态调试可以发现,比较的数据都是存放在 ebp 寄存器里的,也就是在栈空间里,起初我以为这两个比较函数访问的地址是主存中的地址,然后用 hook 函数在执行到比较指令时进行 patch 寄存器,后来发现由于里面存的是栈地址根本找不到寄存器指向的数据到底在哪遂放弃。

1675440281782

修改栈的高地址进行 patch

根据 stdcall的传参特性 ,也就是下面这幅图

img

也就是说我们传入的两个参数是在比栈底还要高的地址,访问 arg0arg1 只要分别加上 4 和 8 即可,同时我们选定一段未被使用的地址存储字符串 batman 进行间接寻址,进而实现 super_fuction 这个函数返回 1

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
from unicorn import *
from unicorn.x86_const import *
from pwn import *
from capstone import *

md = Cs(CS_ARCH_X86, CS_MODE_32)
mu = Uc(UC_ARCH_X86, UC_MODE_32)

BASE_ADDR = 0x0
STACK_ADDR = 0x400000
STACK_SIZE = 1024 * 1024

mu.mem_map(BASE_ADDR, 1024 * 1024)
mu.mem_map(STACK_ADDR, STACK_SIZE)
mu.mem_write(BASE_ADDR, read("./function"))

r_esp = STACK_ADDR + (STACK_SIZE - 12) # 留空间放参数
mu.reg_write(UC_X86_REG_ESP, r_esp)

STRING_ADDR = BASE_ADDR + 1024
mu.mem_write(STRING_ADDR, b"batman\x00") # 在没用的空间写上目标字符串
mu.mem_write(r_esp + 4, p32(5)) # 第一个参数是 5
mu.mem_write(r_esp + 8, p32(STRING_ADDR)) # 第二个参数是STRING_ADDR对应的数据

def hook_code(mu, address, size, user_data):
machine_code = mu.mem_read(address, size)
for code in md.disasm(machine_code, address):
print(" 0x%x:\t%s\t%s" % (code.address, code.mnemonic, code.op_str))

mu.hook_add(UC_HOOK_CODE, hook_code)
mu.emu_start(0x57B, 0x5B1)
return_value = mu.reg_read(UC_X86_REG_EAX)
print("The returned value is: %d" % return_value)

最后的输出流如下:

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
     0x57b:    push    ebp
0x57c: mov ebp, esp
0x57e: call 0x5d6
0x5d6: mov eax, dword ptr [esp]
0x5d9: ret
0x583: add eax, 0x1a7d
0x588: cmp dword ptr [ebp + 8], 5
0x58c: jne 0x5ab
0x58e: lea eax, [eax - 0x19a0]
0x594: push eax
0x595: push dword ptr [ebp + 0xc]
0x598: call 0x50d
0x50d: push ebp
0x50e: mov ebp, esp
0x510: sub esp, 0x10
0x513: call 0x5d6
0x5d6: mov eax, dword ptr [esp]
0x5d9: ret
0x518: add eax, 0x1ae8
0x51d: mov dword ptr [ebp - 4], 0
0x524: mov eax, dword ptr [ebp + 8]
0x527: mov dword ptr [ebp - 8], eax
0x52a: jmp 0x534
0x534: mov eax, dword ptr [ebp - 8]
0x537: movzx eax, byte ptr [eax]
0x53a: test al, al
0x53c: jne 0x52c
0x52c: add dword ptr [ebp - 8], 1
0x530: add dword ptr [ebp - 4], 1
0x534: mov eax, dword ptr [ebp - 8]
0x537: movzx eax, byte ptr [eax]
0x53a: test al, al
0x53c: jne 0x52c
0x52c: add dword ptr [ebp - 8], 1
0x530: add dword ptr [ebp - 4], 1
0x534: mov eax, dword ptr [ebp - 8]
0x537: movzx eax, byte ptr [eax]
0x53a: test al, al
0x53c: jne 0x52c
0x52c: add dword ptr [ebp - 8], 1
0x530: add dword ptr [ebp - 4], 1
0x534: mov eax, dword ptr [ebp - 8]
0x537: movzx eax, byte ptr [eax]
0x53a: test al, al
0x53c: jne 0x52c
0x52c: add dword ptr [ebp - 8], 1
0x530: add dword ptr [ebp - 4], 1
0x534: mov eax, dword ptr [ebp - 8]
0x537: movzx eax, byte ptr [eax]
0x53a: test al, al
0x53c: jne 0x52c
0x52c: add dword ptr [ebp - 8], 1
0x530: add dword ptr [ebp - 4], 1
0x534: mov eax, dword ptr [ebp - 8]
0x537: movzx eax, byte ptr [eax]
0x53a: test al, al
0x53c: jne 0x52c
0x52c: add dword ptr [ebp - 8], 1
0x530: add dword ptr [ebp - 4], 1
0x534: mov eax, dword ptr [ebp - 8]
0x537: movzx eax, byte ptr [eax]
0x53a: test al, al
0x53c: jne 0x52c
0x53e: mov dword ptr [ebp - 0xc], 0
0x545: jmp 0x56c
0x56c: mov eax, dword ptr [ebp - 0xc]
0x56f: cmp eax, dword ptr [ebp - 4]
0x572: jle 0x547
0x547: mov edx, dword ptr [ebp - 0xc]
0x54a: mov eax, dword ptr [ebp + 8]
0x54d: add eax, edx
0x54f: movzx edx, byte ptr [eax]
0x552: mov ecx, dword ptr [ebp - 0xc]
0x555: mov eax, dword ptr [ebp + 0xc]
0x558: add eax, ecx
0x55a: movzx eax, byte ptr [eax]
0x55d: cmp dl, al
0x55f: je 0x568
0x568: add dword ptr [ebp - 0xc], 1
0x56c: mov eax, dword ptr [ebp - 0xc]
0x56f: cmp eax, dword ptr [ebp - 4]
0x572: jle 0x547
0x547: mov edx, dword ptr [ebp - 0xc]
0x54a: mov eax, dword ptr [ebp + 8]
0x54d: add eax, edx
0x54f: movzx edx, byte ptr [eax]
0x552: mov ecx, dword ptr [ebp - 0xc]
0x555: mov eax, dword ptr [ebp + 0xc]
0x558: add eax, ecx
0x55a: movzx eax, byte ptr [eax]
0x55d: cmp dl, al
0x55f: je 0x568
0x568: add dword ptr [ebp - 0xc], 1
0x56c: mov eax, dword ptr [ebp - 0xc]
0x56f: cmp eax, dword ptr [ebp - 4]
0x572: jle 0x547
0x547: mov edx, dword ptr [ebp - 0xc]
0x54a: mov eax, dword ptr [ebp + 8]
0x54d: add eax, edx
0x54f: movzx edx, byte ptr [eax]
0x552: mov ecx, dword ptr [ebp - 0xc]
0x555: mov eax, dword ptr [ebp + 0xc]
0x558: add eax, ecx
0x55a: movzx eax, byte ptr [eax]
0x55d: cmp dl, al
0x55f: je 0x568
0x568: add dword ptr [ebp - 0xc], 1
0x56c: mov eax, dword ptr [ebp - 0xc]
0x56f: cmp eax, dword ptr [ebp - 4]
0x572: jle 0x547
0x547: mov edx, dword ptr [ebp - 0xc]
0x54a: mov eax, dword ptr [ebp + 8]
0x54d: add eax, edx
0x54f: movzx edx, byte ptr [eax]
0x552: mov ecx, dword ptr [ebp - 0xc]
0x555: mov eax, dword ptr [ebp + 0xc]
0x558: add eax, ecx
0x55a: movzx eax, byte ptr [eax]
0x55d: cmp dl, al
0x55f: je 0x568
0x568: add dword ptr [ebp - 0xc], 1
0x56c: mov eax, dword ptr [ebp - 0xc]
0x56f: cmp eax, dword ptr [ebp - 4]
0x572: jle 0x547
0x547: mov edx, dword ptr [ebp - 0xc]
0x54a: mov eax, dword ptr [ebp + 8]
0x54d: add eax, edx
0x54f: movzx edx, byte ptr [eax]
0x552: mov ecx, dword ptr [ebp - 0xc]
0x555: mov eax, dword ptr [ebp + 0xc]
0x558: add eax, ecx
0x55a: movzx eax, byte ptr [eax]
0x55d: cmp dl, al
0x55f: je 0x568
0x568: add dword ptr [ebp - 0xc], 1
0x56c: mov eax, dword ptr [ebp - 0xc]
0x56f: cmp eax, dword ptr [ebp - 4]
0x572: jle 0x547
0x547: mov edx, dword ptr [ebp - 0xc]
0x54a: mov eax, dword ptr [ebp + 8]
0x54d: add eax, edx
0x54f: movzx edx, byte ptr [eax]
0x552: mov ecx, dword ptr [ebp - 0xc]
0x555: mov eax, dword ptr [ebp + 0xc]
0x558: add eax, ecx
0x55a: movzx eax, byte ptr [eax]
0x55d: cmp dl, al
0x55f: je 0x568
0x568: add dword ptr [ebp - 0xc], 1
0x56c: mov eax, dword ptr [ebp - 0xc]
0x56f: cmp eax, dword ptr [ebp - 4]
0x572: jle 0x547
0x547: mov edx, dword ptr [ebp - 0xc]
0x54a: mov eax, dword ptr [ebp + 8]
0x54d: add eax, edx
0x54f: movzx edx, byte ptr [eax]
0x552: mov ecx, dword ptr [ebp - 0xc]
0x555: mov eax, dword ptr [ebp + 0xc]
0x558: add eax, ecx
0x55a: movzx eax, byte ptr [eax]
0x55d: cmp dl, al
0x55f: je 0x568
0x568: add dword ptr [ebp - 0xc], 1
0x56c: mov eax, dword ptr [ebp - 0xc]
0x56f: cmp eax, dword ptr [ebp - 4]
0x572: jle 0x547
0x574: mov eax, 0
0x579: leave
0x57a: ret
0x59d: add esp, 8
0x5a0: test eax, eax
0x5a2: jne 0x5ab
0x5a4: mov eax, 1
0x5a9: jmp 0x5b0
0x5b0: leave
The returned value is: 1

有傻逼先是把 ESP 写成了 RSP,又把 CS_ARCH_X86 写成了 UC_ARCH_X86,还把 UC_MODE_X32 写成了 UC_MODE_X64 导致模拟执行了半小时输不出来正确的返回值,那么他是谁呢👉🤣

Task4

程序分析

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
int __fastcall ccc(unsigned int a1, int a2, int a3)
{
int v4; // r5
int v5; // r1
int v6; // r2
int v7; // r4
int v8; // r1
int v9; // r2

switch ( a1 )
{
case 0u:
return 5;
case 1u:
return 8;
case 2u:
return 3;
case 3u:
return 1;
}
v4 = ccc(a1 >> 1, a2, a3);
v7 = ccc(a1 - 1, v5, v6) * v4;
return v7 + ccc(a1 - 3, v8, v9);
}

int __cdecl main(int argc, const char **argv, const char **envp)
{
int v3; // r0

v3 = ccc(10000u, (int)argv, (int)envp);
printf("%d\n", v3);
return 0;
}

和 task1 差不多,也是一个递归调用,输入 10000,需要得到一个返回值。不同的是该程序是个ARM架构的ELF文件

1675492714947

同样,我们先跟踪程序流,程序跑的很欢,没有什么需要 skip 的指令,但是需要很长时间才能返回我们想知道的答案,我们同样使用unicorn来解决这个问题。

unicorn 模拟执行用 stack 优化

如图,ccc的第一个参数由 R0 传入,且返回值存在 R0 中。

1675492608887

那么我们就可以按照 task1 的套路,对 ccc 的入口和出口进行特判进行 hook 操作,最后由于输出结果在 print 的时候是存在 R1 寄存器中,我们把这个数据 dump 下来即可

1675493357373

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
from unicorn import *
from unicorn.arm_const import *
from pwn import *

mu = Uc(UC_ARCH_ARM, UC_MODE_LITTLE_ENDIAN)

BASE_ADDR = 0x10000
STACK_ADDR = 0x400000
STACK_SIZE = 1024 * 1024

mu.mem_map(BASE_ADDR, 1024 * 1024)
mu.mem_map(STACK_ADDR, STACK_SIZE)
mu.mem_write(BASE_ADDR, read("./task4"))
mu.reg_write(UC_ARM_REG_SP, STACK_ADDR + (STACK_SIZE // 2))

CCC_ENTRY = 0x104D0
CCC_RET = 0x10580
stack = []
dp = {}

def hook_code(mu, address, size, user_data):

if(address == CCC_ENTRY):
arg0 = mu.reg_read(UC_ARM_REG_R0)
if arg0 in dp:
ret_r0 = dp[arg0]
mu.reg_write(UC_ARM_REG_R0, ret_r0)
mu.reg_write(UC_ARM_REG_PC, 0x105BC)
else:
stack.append(arg0)
elif(address == CCC_RET):
arg0 = stack.pop()
ret_r0 = mu.reg_read(UC_ARM_REG_R0)
dp[arg0] = ret_r0

mu.hook_add(UC_HOOK_CODE, hook_code)
mu.emu_start(0x10584, 0x105A8)

return_value = mu.reg_read(UC_ARM_REG_R1)
print("The return value = %d" % return_value)

1675493913532

最后的答案是 2635833876

信息安全铁人三项2024 - ez_driver

是一个windows下的sys驱动文件,很难配置调试环境,主要加密逻辑如下:

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
__int64 __fastcall sub_140001510(__int64 a1, __int64 a2)
{
int j; // [rsp+20h] [rbp-B8h]
int v4; // [rsp+28h] [rbp-B0h] BYREF
int v5; // [rsp+2Ch] [rbp-ACh]
unsigned int i; // [rsp+30h] [rbp-A8h]
int k; // [rsp+34h] [rbp-A4h]
int v8; // [rsp+38h] [rbp-A0h]
int v9; // [rsp+3Ch] [rbp-9Ch]
int v10; // [rsp+40h] [rbp-98h]
unsigned int v11; // [rsp+44h] [rbp-94h]
PCSTR Format; // [rsp+48h] [rbp-90h]
int v13; // [rsp+50h] [rbp-88h]
int v14; // [rsp+54h] [rbp-84h]
int v15; // [rsp+58h] [rbp-80h]
_DWORD *v16; // [rsp+60h] [rbp-78h]
char *v17; // [rsp+68h] [rbp-70h]
int v18; // [rsp+70h] [rbp-68h]
int v19; // [rsp+74h] [rbp-64h]
PCSTR v20; // [rsp+78h] [rbp-60h]
int v21[4]; // [rsp+80h] [rbp-58h] BYREF
char v22[40]; // [rsp+90h] [rbp-48h] BYREF

v9 = 0;
v4 = 0;
v5 = 0;
v16 = (_DWORD *)sub_140001C90(a2);
v13 = v16[6];
Format = *(PCSTR *)(a2 + 24);
v11 = v16[4];
v18 = v16[2];
v10 = v13;
if ( v13 == 2236416 )
{
DbgPrint(&byte_140002380);
memset(v22, 0, sizeof(v22));
v20 = Format;
for ( i = 0; i < v11; ++i )
v22[i] = v20[i];
for ( j = 0; j < 32; j += 8 )
{
v4 = 0;
v5 = 0;
v4 = (unsigned __int8)v22[j] << 24;
v4 += (unsigned __int8)v22[j + 1] << 16;
v4 += (unsigned __int8)v22[j + 2] << 8;
v4 += (unsigned __int8)v22[j + 3];
v5 = (unsigned __int8)v22[j + 4] << 24;
v5 += (unsigned __int8)v22[j + 5] << 16;
v5 += (unsigned __int8)v22[j + 6] << 8;
v5 += (unsigned __int8)v22[j + 7];
v21[0] = 6699;
v21[1] = 14925;
v21[2] = 24175;
v21[3] = 43571;
v19 = 2;
v14 = 33;
sub_1400020E0(0x21u, (unsigned int *)&v4, (__int64)v21);
v22[j] = HIBYTE(v4);
v22[j + 1] = BYTE2(v4);
v22[j + 2] = BYTE1(v4);
v22[j + 3] = v4;
v22[j + 4] = HIBYTE(v5);
v22[j + 5] = BYTE2(v5);
v22[j + 6] = BYTE1(v5);
v22[j + 7] = v5;
}
v8 = 0;
v17 = v22;
do
{
v15 = v8;
sub_140001E70(v17, v8++);
v17 += 16;
}
while ( v8 < 2 );
for ( k = 0; k < 32; ++k )
{
if ( v22[k] == byte_140004400[k] )
++v9;
}
DbgPrint(&byte_140002390);
if ( v9 == 32 )
{
strcpy((char *)Format, "flag is you input");
*(_QWORD *)(a2 + 56) = 18i64;
DbgPrint(&byte_1400023C0);
}
else
{
strcpy((char *)Format, "wrong");
*(_QWORD *)(a2 + 56) = 6i64;
DbgPrint(&byte_1400023E0);
}
}
else if ( v10 != 2237440 )
{
goto LABEL_21;
}
DbgPrint(aIrpdevicecontr, v11);
DbgPrint("CODE_WRITE %X\n", 2237440i64);
DbgPrint(Format);
*(_QWORD *)(a2 + 56) = 0i64;
LABEL_21:
*(_QWORD *)(a2 + 56) = 65i64;
IofCompleteRequest((PIRP)a2, 0);
return 0i64;
}

我们使用unicorn对其进行模拟执行

用010editor可以知道该PE文件的文件头长度为 0x400,因此我们需要将模拟执行的基址增加 0x400,可以在idapro里用编辑—>段来重新定位基址,把基址增加0x400即可。

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
from unicorn import *
from unicorn.x86_const import *
from pwn import *
from capstone import *
BASE_OFFSET = 0x400
mu = Uc(UC_ARCH_X86, UC_MODE_64)
md = Cs(CS_ARCH_X86, CS_MODE_64)

BASE_ADDR = 0x140001000
STACK_ADDR = 0x1000
STACK_SIZE = 1024 * 1024
mu.mem_map(BASE_ADDR, 1024 * 1024)
mu.mem_map(STACK_ADDR, STACK_SIZE)
mu.mem_write(BASE_ADDR, read("./ez_driver.sys"))
mu.reg_write(UC_X86_REG_RBP, STACK_ADDR + STACK_SIZE // 2) # 分配栈底
mu.reg_write(UC_X86_REG_RSP, STACK_ADDR + STACK_SIZE // 4) # 分配栈顶,栈地址是倒序的

# 使用mem_write, mem_read, reg_write, reg_read函数,配合汇编进行hook。
def hook_code(mu, address, size, user_data):
# code = mu.mem_read(address, size)
# for instruction in md.disasm(code, address):
# print("0x%x: %s %s" % (instruction.address, instruction.mnemonic, instruction.op_str))
if address == 0x14000161D:
mu.mem_write(mu.reg_read(UC_X86_REG_RSP) + 144, b'12345678123456781234567812345678')
# print(mu.mem_read(mu.reg_read(mu.reg_read(UC_X86_REG_RSP) + 72), 32))
elif address == 0x14000180F:
tea_input = mu.mem_read(mu.reg_read(UC_X86_REG_RSP) + 40, 8)
print(f"tea_input: {bytes(tea_input)}")
elif address == 0x14000182D:
tea_output = mu.mem_read(mu.reg_read(UC_X86_REG_RSP) + 40, 8)
print(f"tea_output: {[hex(i) for i in tea_output]}")
elif address == 0x140001930:
cipher_1 = mu.mem_read(mu.reg_read(UC_X86_REG_RSP) + 144, 32)
print(f"cipher_1: {[hex(i) for i in cipher_1]}")
elif address == 0x14000197A:
cipher_2 = mu.mem_read(mu.reg_read(UC_X86_REG_RSP) + 104, 32)
print(f"cipher_2: {[hex(i) for i in cipher_2]}")

mu.hook_add(UC_HOOK_CODE, hook_code)
mu.emu_start(0x1400015D9, 0x1400019C9)

备录

全是网上抄的,个人存档用

from unicorn import * - 加载Unicorn库。包含一些函数和基本的常量。

from unicorn.x86_const import* - 加载 X86 和X64架构相关的常量

所有unicorn模块中的常量

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
UC_API_MAJOR                UC_ERR_VERSION              UC_MEM_READ                 UC_PROT_ALL
UC_API_MINOR UC_ERR_WRITE_PROT UC_MEM_READ_AFTER UC_PROT_EXEC
UC_ARCH_ARM UC_ERR_WRITE_UNALIGNED UC_MEM_READ_PROT UC_PROT_NONE
UC_ARCH_ARM64 UC_ERR_WRITE_UNMAPPED UC_MEM_READ_UNMAPPED UC_PROT_READ
UC_ARCH_M68K UC_HOOK_BLOCK UC_MEM_WRITE UC_PROT_WRITE
UC_ARCH_MAX UC_HOOK_CODE UC_MEM_WRITE_PROT UC_QUERY_MODE
UC_ARCH_MIPS UC_HOOK_INSN UC_MEM_WRITE_UNMAPPED UC_QUERY_PAGE_SIZE
UC_ARCH_PPC UC_HOOK_INTR UC_MILISECOND_SCALE UC_SECOND_SCALE
UC_ARCH_SPARC UC_HOOK_MEM_FETCH UC_MODE_16 UC_VERSION_EXTRA
UC_ARCH_X86 UC_HOOK_MEM_FETCH_INVALID UC_MODE_32 UC_VERSION_MAJOR
UC_ERR_ARCH UC_HOOK_MEM_FETCH_PROT UC_MODE_64 UC_VERSION_MINOR
UC_ERR_ARG UC_HOOK_MEM_FETCH_UNMAPPED UC_MODE_ARM Uc
UC_ERR_EXCEPTION UC_HOOK_MEM_INVALID UC_MODE_BIG_ENDIAN UcError
UC_ERR_FETCH_PROT UC_HOOK_MEM_PROT UC_MODE_LITTLE_ENDIAN arm64_const
UC_ERR_FETCH_UNALIGNED UC_HOOK_MEM_READ UC_MODE_MCLASS arm_const
UC_ERR_FETCH_UNMAPPED UC_HOOK_MEM_READ_AFTER UC_MODE_MICRO debug
UC_ERR_HANDLE UC_HOOK_MEM_READ_INVALID UC_MODE_MIPS3 m68k_const
UC_ERR_HOOK UC_HOOK_MEM_READ_PROT UC_MODE_MIPS32 mips_const
UC_ERR_HOOK_EXIST UC_HOOK_MEM_READ_UNMAPPED UC_MODE_MIPS32R6 sparc_const
UC_ERR_INSN_INVALID UC_HOOK_MEM_UNMAPPED UC_MODE_MIPS64 uc_arch_supported
UC_ERR_MAP UC_HOOK_MEM_VALID UC_MODE_PPC32 uc_version
UC_ERR_MODE UC_HOOK_MEM_WRITE UC_MODE_PPC64 unicorn
UC_ERR_NOMEM UC_HOOK_MEM_WRITE_INVALID UC_MODE_QPX unicorn_const
UC_ERR_OK UC_HOOK_MEM_WRITE_PROT UC_MODE_SPARC32 version_bind
UC_ERR_READ_PROT UC_HOOK_MEM_WRITE_UNMAPPED UC_MODE_SPARC64 x86_const
UC_ERR_READ_UNALIGNED UC_MEM_FETCH UC_MODE_THUMB
UC_ERR_READ_UNMAPPED UC_MEM_FETCH_PROT UC_MODE_V8
UC_ERR_RESOURCE UC_MEM_FETCH_UNMAPPED UC_MODE_V9

一些unicorn.x86_const中的常量

1
2
3
UC_X86_REG_EAX
UC_X86_REG_RIP
UC_X86_REG_RAX

mu = Uc(arch,mode) - 获取Uc实例。在这里指定目标架构,例如:

  • mu = Uc(UC_ARCH_X86,UC_MODE_64) - 获取X86-64架构的实例。
  • mu = Uc(UC_ARCH_X86,UC_MODE_32) - 获取X86-32架构的实例。

mu.mem_map(ADDRESS,4096) - 映射一片内存区域

mu.mem_write(ADDRESS,DATA) - 向内存中写入数据

tmp = mu.mem_read(ADDRESS,SIZE) - 从内存中读取数据

mu.reg_write(UC_X86_REG_ECX,0X0) - 设置ECX值。

r_esp = mu.reg_read(UC_X86_REG_ESP) - 读取ESP的值。

mu.emu_start(ADDRESS_START,ADDRESS_END) - 开始执行模拟。

命令追踪:

1
2
3
4
def hook_code(mu, address, size, user_data): 
print('>>> Tracing instruction at 0x%x, instruction size = 0x%x' %(address, size))

mu.hook_add(UC_HOOK_CODE, hook_code)

这段代码添加了一个HOOK(向Unicorn引擎中),我们定义的函数会在执行每一条命令之前被执行。参数含义如下:

  • Uc实例
  • 指令的地址
  • 指令的长度
  • 用户定义数据(通过hook_add()函数传递)

hook的类型

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
// All type of hooks for uc_hook_add() API.
typedef enum uc_hook_type {
// Hook all interrupt/syscall events
UC_HOOK_INTR = 1 << 0,
// Hook a particular instruction - only a very small subset of instructions supported here
UC_HOOK_INSN = 1 << 1,
// Hook a range of code
UC_HOOK_CODE = 1 << 2,
// Hook basic blocks
UC_HOOK_BLOCK = 1 << 3,
// Hook for memory read on unmapped memory
UC_HOOK_MEM_READ_UNMAPPED = 1 << 4,
// Hook for invalid memory write events
UC_HOOK_MEM_WRITE_UNMAPPED = 1 << 5,
// Hook for invalid memory fetch for execution events
UC_HOOK_MEM_FETCH_UNMAPPED = 1 << 6,
// Hook for memory read on read-protected memory
UC_HOOK_MEM_READ_PROT = 1 << 7,
// Hook for memory write on write-protected memory
UC_HOOK_MEM_WRITE_PROT = 1 << 8,
// Hook for memory fetch on non-executable memory
UC_HOOK_MEM_FETCH_PROT = 1 << 9,
// Hook memory read events.
UC_HOOK_MEM_READ = 1 << 10,
// Hook memory write events.
UC_HOOK_MEM_WRITE = 1 << 11,
// Hook memory fetch for execution events
UC_HOOK_MEM_FETCH = 1 << 12,
// Hook memory read events, but only successful access.
// The callback will be triggered after successful read.
UC_HOOK_MEM_READ_AFTER = 1 << 13,
} uc_hook_type;

关键函数的声明等

uc_open

1
2
3
4
5
6
7
8
9
10
11
12
/*
Create new instance of unicorn engine.

@arch: architecture type (UC_ARCH_*)
@mode: hardware mode. This is combined of UC_MODE_*
@uc: pointer to uc_engine, which will be updated at return time

@return UC_ERR_OK on success, or other value on failure (refer to uc_err enum
for detailed error).
*/
UNICORN_EXPORT
uc_err uc_open(uc_arch arch, uc_mode mode, uc_engine **uc);

@arch:架构类型(UC_ARCH_*)
@mode:硬件模式。 这是结合 UC_MODE_*
@uc:指向uc_engine的指针,返回时会更新
@return UC_ERR_OK 成功,或其他值失败(参考 uc_err 枚举详细错误)。

uc_arch和uc_mode的枚举值:

1
2
3
4
5
6
7
8
9
10
typedef enum uc_arch {
UC_ARCH_ARM = 1, // ARM architecture (including Thumb, Thumb-2)
UC_ARCH_ARM64, // ARM-64, also called AArch64
UC_ARCH_MIPS, // Mips architecture
UC_ARCH_X86, // X86 architecture (including x86 & x86-64)
UC_ARCH_PPC, // PowerPC architecture (currently unsupported)
UC_ARCH_SPARC, // Sparc architecture
UC_ARCH_M68K, // M68K architecture
UC_ARCH_MAX,
} uc_arch;
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
// Mode type
typedef enum uc_mode {
UC_MODE_LITTLE_ENDIAN = 0, // little-endian mode (default mode)
UC_MODE_BIG_ENDIAN = 1 << 30, // big-endian mode

// arm / arm64
UC_MODE_ARM = 0, // ARM mode
UC_MODE_THUMB = 1 << 4, // THUMB mode (including Thumb-2)
UC_MODE_MCLASS = 1 << 5, // ARM's Cortex-M series (currently unsupported)
UC_MODE_V8 = 1 << 6, // ARMv8 A32 encodings for ARM (currently unsupported)

// arm (32bit) cpu types
UC_MODE_ARM926 = 1 << 7, // ARM926 CPU type
UC_MODE_ARM946 = 1 << 8, // ARM946 CPU type
UC_MODE_ARM1176 = 1 << 9, // ARM1176 CPU type

// ARM BE8
UC_MODE_ARMBE8 = 1 << 10, // Big-endian data and Little-endian code

// mips
UC_MODE_MICRO = 1 << 4, // MicroMips mode (currently unsupported)
UC_MODE_MIPS3 = 1 << 5, // Mips III ISA (currently unsupported)
UC_MODE_MIPS32R6 = 1 << 6, // Mips32r6 ISA (currently unsupported)
UC_MODE_MIPS32 = 1 << 2, // Mips32 ISA
UC_MODE_MIPS64 = 1 << 3, // Mips64 ISA

// x86 / x64
UC_MODE_16 = 1 << 1, // 16-bit mode
UC_MODE_32 = 1 << 2, // 32-bit mode
UC_MODE_64 = 1 << 3, // 64-bit mode

// ppc
UC_MODE_PPC32 = 1 << 2, // 32-bit mode (currently unsupported)
UC_MODE_PPC64 = 1 << 3, // 64-bit mode (currently unsupported)
UC_MODE_QPX = 1 << 4, // Quad Processing eXtensions mode (currently unsupported)

// sparc
UC_MODE_SPARC32 = 1 << 2, // 32-bit mode
UC_MODE_SPARC64 = 1 << 3, // 64-bit mode
UC_MODE_V9 = 1 << 4, // SparcV9 mode (currently unsupported)

// m68k
} uc_mode;

uc_mem_map

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
/*
Map memory in for emulation.
This API adds a memory region that can be used by emulation.

@uc: handle returned by uc_open()
@address: starting address of the new memory region to be mapped in.
This address must be aligned to 4KB, or this will return with UC_ERR_ARG error.
@size: size of the new memory region to be mapped in.
This size must be a multiple of 4KB, or this will return with UC_ERR_ARG error.
@perms: Permissions for the newly mapped region.
This must be some combination of UC_PROT_READ | UC_PROT_WRITE | UC_PROT_EXEC,
or this will return with UC_ERR_ARG error.

@return UC_ERR_OK on success, or other value on failure (refer to uc_err enum
for detailed error).
*/
UNICORN_EXPORT
uc_err uc_mem_map(uc_engine *uc, uint64_t address, size_t size, uint32_t perms);

映射内存以进行仿真。
该API添加了一个可供仿真使用的内存区域。
参数:
@uc: uc_open() 返回的句柄
@address:要映射到的新内存区域的起始地址。
该地址必须与 4KB 对齐,否则将返回 UC_ERR_ARG 错误。
@size:要映射到的新内存区域的大小。
此大小必须是 4KB 的倍数,否则将返回 UC_ERR_ARG 错误。
@perms:新映射区域的权限。
这必须是 UC_PROT_READ | 的某种组合。 UC_PROT_WRITE | UC_PROT_EXEC,
否则这将返回 UC_ERR_ARG 错误。
@return UC_ERR_OK 成功,或其他值失败(参考 uc_err 枚举详细错误)。

最后一个参数是uc_prot的枚举值:

1
2
3
4
5
6
7
typedef enum uc_prot {
UC_PROT_NONE = 0,
UC_PROT_READ = 1,
UC_PROT_WRITE = 2,
UC_PROT_EXEC = 4,
UC_PROT_ALL = 7,
} uc_prot;

uc_mem_write

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
/*
Write to a range of bytes in memory.

@uc: handle returned by uc_open()
@address: starting memory address of bytes to set.
@bytes: pointer to a variable containing data to be written to memory.
@size: size of memory to write to.

NOTE: @bytes must be big enough to contain @size bytes.

@return UC_ERR_OK on success, or other value on failure (refer to uc_err enum
for detailed error).
*/
UNICORN_EXPORT
uc_err uc_mem_write(uc_engine *uc, uint64_t address, const void *bytes, size_t size);

写入内存中的字节范围。
@uc: uc_open() 返回的句柄
@address:要设置的字节的起始内存地址。
@bytes:指向包含要写入内存的数据的变量的指针。
@size:要写入的内存大小。
注意:@bytes 必须足够大以包含 @size 字节。
@return UC_ERR_OK 成功,或其他值失败(参考 uc_err 枚举详细错误)

uc_reg_write

1
2
3
4
5
6
7
8
9
10
11
12
/*
Write to register.

@uc: handle returned by uc_open()
@regid: register ID that is to be modified.
@value: pointer to the value that will set to register @regid

@return UC_ERR_OK on success, or other value on failure (refer to uc_err enum
for detailed error).
*/
UNICORN_EXPORT
uc_err uc_reg_write(uc_engine *uc, int regid, const void *value);

@uc: uc_open() 返回的句柄
@regid:要修改的注册ID。
@value:指向将设置为注册@regid 的值的指针
@return UC_ERR_OK 成功,或其他值失败(参考 uc_err 枚举详细错误)。

第二个值是unicorn规定的x86寄存器的枚举值:

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
//> X86 registers
typedef enum uc_x86_reg {
UC_X86_REG_INVALID = 0,
UC_X86_REG_AH, UC_X86_REG_AL, UC_X86_REG_AX, UC_X86_REG_BH, UC_X86_REG_BL,
UC_X86_REG_BP, UC_X86_REG_BPL, UC_X86_REG_BX, UC_X86_REG_CH, UC_X86_REG_CL,
UC_X86_REG_CS, UC_X86_REG_CX, UC_X86_REG_DH, UC_X86_REG_DI, UC_X86_REG_DIL,
UC_X86_REG_DL, UC_X86_REG_DS, UC_X86_REG_DX, UC_X86_REG_EAX, UC_X86_REG_EBP,
UC_X86_REG_EBX, UC_X86_REG_ECX, UC_X86_REG_EDI, UC_X86_REG_EDX, UC_X86_REG_EFLAGS,
UC_X86_REG_EIP, UC_X86_REG_EIZ, UC_X86_REG_ES, UC_X86_REG_ESI, UC_X86_REG_ESP,
UC_X86_REG_FPSW, UC_X86_REG_FS, UC_X86_REG_GS, UC_X86_REG_IP, UC_X86_REG_RAX,
UC_X86_REG_RBP, UC_X86_REG_RBX, UC_X86_REG_RCX, UC_X86_REG_RDI, UC_X86_REG_RDX,
UC_X86_REG_RIP, UC_X86_REG_RIZ, UC_X86_REG_RSI, UC_X86_REG_RSP, UC_X86_REG_SI,
UC_X86_REG_SIL, UC_X86_REG_SP, UC_X86_REG_SPL, UC_X86_REG_SS, UC_X86_REG_CR0,
UC_X86_REG_CR1, UC_X86_REG_CR2, UC_X86_REG_CR3, UC_X86_REG_CR4, UC_X86_REG_CR5,
UC_X86_REG_CR6, UC_X86_REG_CR7, UC_X86_REG_CR8, UC_X86_REG_CR9, UC_X86_REG_CR10,
UC_X86_REG_CR11, UC_X86_REG_CR12, UC_X86_REG_CR13, UC_X86_REG_CR14, UC_X86_REG_CR15,
UC_X86_REG_DR0, UC_X86_REG_DR1, UC_X86_REG_DR2, UC_X86_REG_DR3, UC_X86_REG_DR4,
UC_X86_REG_DR5, UC_X86_REG_DR6, UC_X86_REG_DR7, UC_X86_REG_DR8, UC_X86_REG_DR9,
UC_X86_REG_DR10, UC_X86_REG_DR11, UC_X86_REG_DR12, UC_X86_REG_DR13, UC_X86_REG_DR14,
UC_X86_REG_DR15, UC_X86_REG_FP0, UC_X86_REG_FP1, UC_X86_REG_FP2, UC_X86_REG_FP3,
UC_X86_REG_FP4, UC_X86_REG_FP5, UC_X86_REG_FP6, UC_X86_REG_FP7,
UC_X86_REG_K0, UC_X86_REG_K1, UC_X86_REG_K2, UC_X86_REG_K3, UC_X86_REG_K4,
UC_X86_REG_K5, UC_X86_REG_K6, UC_X86_REG_K7, UC_X86_REG_MM0, UC_X86_REG_MM1,
UC_X86_REG_MM2, UC_X86_REG_MM3, UC_X86_REG_MM4, UC_X86_REG_MM5, UC_X86_REG_MM6,
UC_X86_REG_MM7, UC_X86_REG_R8, UC_X86_REG_R9, UC_X86_REG_R10, UC_X86_REG_R11,
UC_X86_REG_R12, UC_X86_REG_R13, UC_X86_REG_R14, UC_X86_REG_R15,
UC_X86_REG_ST0, UC_X86_REG_ST1, UC_X86_REG_ST2, UC_X86_REG_ST3,
UC_X86_REG_ST4, UC_X86_REG_ST5, UC_X86_REG_ST6, UC_X86_REG_ST7,
UC_X86_REG_XMM0, UC_X86_REG_XMM1, UC_X86_REG_XMM2, UC_X86_REG_XMM3, UC_X86_REG_XMM4,
UC_X86_REG_XMM5, UC_X86_REG_XMM6, UC_X86_REG_XMM7, UC_X86_REG_XMM8, UC_X86_REG_XMM9,
UC_X86_REG_XMM10, UC_X86_REG_XMM11, UC_X86_REG_XMM12, UC_X86_REG_XMM13, UC_X86_REG_XMM14,
UC_X86_REG_XMM15, UC_X86_REG_XMM16, UC_X86_REG_XMM17, UC_X86_REG_XMM18, UC_X86_REG_XMM19,
UC_X86_REG_XMM20, UC_X86_REG_XMM21, UC_X86_REG_XMM22, UC_X86_REG_XMM23, UC_X86_REG_XMM24,
UC_X86_REG_XMM25, UC_X86_REG_XMM26, UC_X86_REG_XMM27, UC_X86_REG_XMM28, UC_X86_REG_XMM29,
UC_X86_REG_XMM30, UC_X86_REG_XMM31, UC_X86_REG_YMM0, UC_X86_REG_YMM1, UC_X86_REG_YMM2,
UC_X86_REG_YMM3, UC_X86_REG_YMM4, UC_X86_REG_YMM5, UC_X86_REG_YMM6, UC_X86_REG_YMM7,
UC_X86_REG_YMM8, UC_X86_REG_YMM9, UC_X86_REG_YMM10, UC_X86_REG_YMM11, UC_X86_REG_YMM12,
UC_X86_REG_YMM13, UC_X86_REG_YMM14, UC_X86_REG_YMM15, UC_X86_REG_YMM16, UC_X86_REG_YMM17,
UC_X86_REG_YMM18, UC_X86_REG_YMM19, UC_X86_REG_YMM20, UC_X86_REG_YMM21, UC_X86_REG_YMM22,
UC_X86_REG_YMM23, UC_X86_REG_YMM24, UC_X86_REG_YMM25, UC_X86_REG_YMM26, UC_X86_REG_YMM27,
UC_X86_REG_YMM28, UC_X86_REG_YMM29, UC_X86_REG_YMM30, UC_X86_REG_YMM31, UC_X86_REG_ZMM0,
UC_X86_REG_ZMM1, UC_X86_REG_ZMM2, UC_X86_REG_ZMM3, UC_X86_REG_ZMM4, UC_X86_REG_ZMM5,
UC_X86_REG_ZMM6, UC_X86_REG_ZMM7, UC_X86_REG_ZMM8, UC_X86_REG_ZMM9, UC_X86_REG_ZMM10,
UC_X86_REG_ZMM11, UC_X86_REG_ZMM12, UC_X86_REG_ZMM13, UC_X86_REG_ZMM14, UC_X86_REG_ZMM15,
UC_X86_REG_ZMM16, UC_X86_REG_ZMM17, UC_X86_REG_ZMM18, UC_X86_REG_ZMM19, UC_X86_REG_ZMM20,
UC_X86_REG_ZMM21, UC_X86_REG_ZMM22, UC_X86_REG_ZMM23, UC_X86_REG_ZMM24, UC_X86_REG_ZMM25,
UC_X86_REG_ZMM26, UC_X86_REG_ZMM27, UC_X86_REG_ZMM28, UC_X86_REG_ZMM29, UC_X86_REG_ZMM30,
UC_X86_REG_ZMM31, UC_X86_REG_R8B, UC_X86_REG_R9B, UC_X86_REG_R10B, UC_X86_REG_R11B,
UC_X86_REG_R12B, UC_X86_REG_R13B, UC_X86_REG_R14B, UC_X86_REG_R15B, UC_X86_REG_R8D,
UC_X86_REG_R9D, UC_X86_REG_R10D, UC_X86_REG_R11D, UC_X86_REG_R12D, UC_X86_REG_R13D,
UC_X86_REG_R14D, UC_X86_REG_R15D, UC_X86_REG_R8W, UC_X86_REG_R9W, UC_X86_REG_R10W,
UC_X86_REG_R11W, UC_X86_REG_R12W, UC_X86_REG_R13W, UC_X86_REG_R14W, UC_X86_REG_R15W,
UC_X86_REG_IDTR, UC_X86_REG_GDTR, UC_X86_REG_LDTR, UC_X86_REG_TR, UC_X86_REG_FPCW,
UC_X86_REG_FPTAG,
UC_X86_REG_MSR, // Model-Specific Register
UC_X86_REG_MXCSR,
UC_X86_REG_FS_BASE, // Base regs for x86_64
UC_X86_REG_GS_BASE,
UC_X86_REG_ENDING // <-- mark the end of the list of registers
} uc_x86_reg;

uc_hook_add

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
/*
Register callback for a hook event.
The callback will be run when the hook event is hit.

@uc: handle returned by uc_open()
@hh: hook handle returned from this registration. To be used in uc_hook_del() API
@type: hook type, refer to uc_hook_type enum
@callback: callback to be run when instruction is hit
@user_data: user-defined data. This will be passed to callback function in its
last argument @user_data
@begin: start address of the area where the callback is in effect (inclusive)
@end: end address of the area where the callback is in effect (inclusive)
NOTE 1: the callback is called only if related address is in range [@begin, @end]
NOTE 2: if @begin > @end, callback is called whenever this hook type is triggered
@...: variable arguments (depending on @type)
NOTE: if @type = UC_HOOK_INSN, this is the instruction ID (ex: UC_X86_INS_OUT)

@return UC_ERR_OK on success, or other value on failure (refer to uc_err enum
for detailed error).
*/
UNICORN_EXPORT
uc_err uc_hook_add(uc_engine *uc, uc_hook *hh, int type, void *callback,
void *user_data, uint64_t begin, uint64_t end, ...);

为钩子事件注册回调
当钩子事件被命中时,回调将运行

@uc: uc_open() 返回的句柄
@hh:从这个注册函数返回的钩子句柄。用于 uc_hook_del() API
@type:钩子类型,参考uc_hook_type枚举
@callback:当指令被命中时运行的回调
@user_data:用户定义的数据。这将传递给回调函数的最后一个参数@user_data
@begin:回调生效区域的起始地址(含)
@end:回调生效区域的结束地址(含)
注意 1:仅当相关地址在 [@begin, @end] 范围内时才会调用回调
注意 2:如果 @begin > @end,每当触发此钩子类型时都会调用回调
@…:可变参数(取决于@type)
注意:如果@type = UC_HOOK_INSN,这是指令ID(例如:UC_X86_INS_OUT)
@return UC_ERR_OK 成功,或其他值失败(参考 uc_err 枚举详细错误)。

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
// All type of hooks for uc_hook_add() API.
typedef enum uc_hook_type {
// Hook all interrupt/syscall events
UC_HOOK_INTR = 1 << 0,
**// Hook a particular instruction - only a very small subset of instructions supported here
UC_HOOK_INSN = 1 << 1,**
// Hook a range of code
UC_HOOK_CODE = 1 << 2,
// Hook basic blocks
UC_HOOK_BLOCK = 1 << 3,
// Hook for memory read on unmapped memory
UC_HOOK_MEM_READ_UNMAPPED = 1 << 4,
// Hook for invalid memory write events
UC_HOOK_MEM_WRITE_UNMAPPED = 1 << 5,
// Hook for invalid memory fetch for execution events
UC_HOOK_MEM_FETCH_UNMAPPED = 1 << 6,
// Hook for memory read on read-protected memory
UC_HOOK_MEM_READ_PROT = 1 << 7,
// Hook for memory write on write-protected memory
UC_HOOK_MEM_WRITE_PROT = 1 << 8,
// Hook for memory fetch on non-executable memory
UC_HOOK_MEM_FETCH_PROT = 1 << 9,
**// Hook memory read events.
UC_HOOK_MEM_READ = 1 << 10,**
// Hook memory write events.
UC_HOOK_MEM_WRITE = 1 << 11,
// Hook memory fetch for execution events
UC_HOOK_MEM_FETCH = 1 << 12,
// Hook memory read events, but only successful access.
// The callback will be triggered after successful read.
UC_HOOK_MEM_READ_AFTER = 1 << 13,
// Hook invalid instructions exceptions.
UC_HOOK_INSN_INVALID = 1 << 14,
} uc_hook_type;

uc_hook_add的第三个参数的值是2,即(uc_hook_type)UC_HOOK_INSN, 钩住一个特定的指令——这里只支持非常小的指令子集

如果第三个参数的值是0x400,说明这是钩取的内存读 // Hook memory read events.

反正这个函数的关键就在第三个参数

最后一个参数,就像函数声明中说的一样,如果@type = UC_HOOK_INSN,这是指令ID(例如:UC_X86_INS_OUT,就是一些X86的指令,枚举值如下:

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
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
1086
1087
1088
1089
1090
1091
1092
1093
1094
1095
1096
1097
1098
1099
1100
1101
1102
1103
1104
1105
1106
1107
1108
1109
1110
1111
1112
1113
1114
1115
1116
1117
1118
1119
1120
1121
1122
1123
1124
1125
1126
1127
1128
1129
1130
1131
1132
1133
1134
1135
1136
1137
1138
1139
1140
1141
1142
1143
1144
1145
1146
1147
1148
1149
1150
1151
1152
1153
1154
1155
1156
1157
1158
1159
1160
1161
1162
1163
1164
1165
1166
1167
1168
1169
1170
1171
1172
1173
1174
1175
1176
1177
1178
1179
1180
1181
1182
1183
1184
1185
1186
1187
1188
1189
1190
1191
1192
1193
1194
1195
1196
1197
1198
1199
1200
1201
1202
1203
1204
1205
1206
1207
1208
1209
1210
1211
1212
1213
1214
1215
1216
1217
1218
1219
1220
1221
1222
1223
1224
1225
1226
1227
1228
1229
1230
1231
1232
1233
1234
1235
1236
1237
1238
1239
1240
1241
1242
1243
1244
1245
1246
1247
1248
1249
1250
1251
1252
1253
1254
1255
1256
1257
1258
1259
1260
1261
1262
1263
1264
1265
1266
1267
1268
1269
1270
1271
1272
1273
1274
1275
1276
1277
1278
1279
1280
1281
1282
1283
1284
1285
1286
1287
1288
1289
1290
1291
1292
1293
1294
1295
1296
1297
1298
1299
1300
1301
1302
1303
1304
1305
1306
1307
1308
1309
1310
1311
1312
1313
1314
1315
1316
1317
1318
1319
1320
1321
1322
1323
1324
1325
1326
1327
1328
1329
1330
1331
1332
1333
1334
1335
1336
1337
1338
1339
1340
1341
1342
//> X86 instructions
typedef enum uc_x86_insn {
UC_X86_INS_INVALID = 0,
UC_X86_INS_AAA,
UC_X86_INS_AAD,
UC_X86_INS_AAM,
UC_X86_INS_AAS,
UC_X86_INS_FABS,
UC_X86_INS_ADC,
UC_X86_INS_ADCX,
UC_X86_INS_ADD,
UC_X86_INS_ADDPD,
UC_X86_INS_ADDPS,
UC_X86_INS_ADDSD,
UC_X86_INS_ADDSS,
UC_X86_INS_ADDSUBPD,
UC_X86_INS_ADDSUBPS,
UC_X86_INS_FADD,
UC_X86_INS_FIADD,
UC_X86_INS_FADDP,
UC_X86_INS_ADOX,
UC_X86_INS_AESDECLAST,
UC_X86_INS_AESDEC,
UC_X86_INS_AESENCLAST,
UC_X86_INS_AESENC,
UC_X86_INS_AESIMC,
UC_X86_INS_AESKEYGENASSIST,
UC_X86_INS_AND,
UC_X86_INS_ANDN,
UC_X86_INS_ANDNPD,
UC_X86_INS_ANDNPS,
UC_X86_INS_ANDPD,
UC_X86_INS_ANDPS,
UC_X86_INS_ARPL,
UC_X86_INS_BEXTR,
UC_X86_INS_BLCFILL,
UC_X86_INS_BLCI,
UC_X86_INS_BLCIC,
UC_X86_INS_BLCMSK,
UC_X86_INS_BLCS,
UC_X86_INS_BLENDPD,
UC_X86_INS_BLENDPS,
UC_X86_INS_BLENDVPD,
UC_X86_INS_BLENDVPS,
UC_X86_INS_BLSFILL,
UC_X86_INS_BLSI,
UC_X86_INS_BLSIC,
UC_X86_INS_BLSMSK,
UC_X86_INS_BLSR,
UC_X86_INS_BOUND,
UC_X86_INS_BSF,
UC_X86_INS_BSR,
UC_X86_INS_BSWAP,
UC_X86_INS_BT,
UC_X86_INS_BTC,
UC_X86_INS_BTR,
UC_X86_INS_BTS,
UC_X86_INS_BZHI,
UC_X86_INS_CALL,
UC_X86_INS_CBW,
UC_X86_INS_CDQ,
UC_X86_INS_CDQE,
UC_X86_INS_FCHS,
UC_X86_INS_CLAC,
UC_X86_INS_CLC,
UC_X86_INS_CLD,
UC_X86_INS_CLFLUSH,
UC_X86_INS_CLFLUSHOPT,
UC_X86_INS_CLGI,
UC_X86_INS_CLI,
UC_X86_INS_CLTS,
UC_X86_INS_CLWB,
UC_X86_INS_CMC,
UC_X86_INS_CMOVA,
UC_X86_INS_CMOVAE,
UC_X86_INS_CMOVB,
UC_X86_INS_CMOVBE,
UC_X86_INS_FCMOVBE,
UC_X86_INS_FCMOVB,
UC_X86_INS_CMOVE,
UC_X86_INS_FCMOVE,
UC_X86_INS_CMOVG,
UC_X86_INS_CMOVGE,
UC_X86_INS_CMOVL,
UC_X86_INS_CMOVLE,
UC_X86_INS_FCMOVNBE,
UC_X86_INS_FCMOVNB,
UC_X86_INS_CMOVNE,
UC_X86_INS_FCMOVNE,
UC_X86_INS_CMOVNO,
UC_X86_INS_CMOVNP,
UC_X86_INS_FCMOVNU,
UC_X86_INS_CMOVNS,
UC_X86_INS_CMOVO,
UC_X86_INS_CMOVP,
UC_X86_INS_FCMOVU,
UC_X86_INS_CMOVS,
UC_X86_INS_CMP,
UC_X86_INS_CMPPD,
UC_X86_INS_CMPPS,
UC_X86_INS_CMPSB,
UC_X86_INS_CMPSD,
UC_X86_INS_CMPSQ,
UC_X86_INS_CMPSS,
UC_X86_INS_CMPSW,
UC_X86_INS_CMPXCHG16B,
UC_X86_INS_CMPXCHG,
UC_X86_INS_CMPXCHG8B,
UC_X86_INS_COMISD,
UC_X86_INS_COMISS,
UC_X86_INS_FCOMP,
UC_X86_INS_FCOMPI,
UC_X86_INS_FCOMI,
UC_X86_INS_FCOM,
UC_X86_INS_FCOS,
UC_X86_INS_CPUID,
UC_X86_INS_CQO,
UC_X86_INS_CRC32,
UC_X86_INS_CVTDQ2PD,
UC_X86_INS_CVTDQ2PS,
UC_X86_INS_CVTPD2DQ,
UC_X86_INS_CVTPD2PS,
UC_X86_INS_CVTPS2DQ,
UC_X86_INS_CVTPS2PD,
UC_X86_INS_CVTSD2SI,
UC_X86_INS_CVTSD2SS,
UC_X86_INS_CVTSI2SD,
UC_X86_INS_CVTSI2SS,
UC_X86_INS_CVTSS2SD,
UC_X86_INS_CVTSS2SI,
UC_X86_INS_CVTTPD2DQ,
UC_X86_INS_CVTTPS2DQ,
UC_X86_INS_CVTTSD2SI,
UC_X86_INS_CVTTSS2SI,
UC_X86_INS_CWD,
UC_X86_INS_CWDE,
UC_X86_INS_DAA,
UC_X86_INS_DAS,
UC_X86_INS_DATA16,
UC_X86_INS_DEC,
UC_X86_INS_DIV,
UC_X86_INS_DIVPD,
UC_X86_INS_DIVPS,
UC_X86_INS_FDIVR,
UC_X86_INS_FIDIVR,
UC_X86_INS_FDIVRP,
UC_X86_INS_DIVSD,
UC_X86_INS_DIVSS,
UC_X86_INS_FDIV,
UC_X86_INS_FIDIV,
UC_X86_INS_FDIVP,
UC_X86_INS_DPPD,
UC_X86_INS_DPPS,
UC_X86_INS_RET,
UC_X86_INS_ENCLS,
UC_X86_INS_ENCLU,
UC_X86_INS_ENTER,
UC_X86_INS_EXTRACTPS,
UC_X86_INS_EXTRQ,
UC_X86_INS_F2XM1,
UC_X86_INS_LCALL,
UC_X86_INS_LJMP,
UC_X86_INS_FBLD,
UC_X86_INS_FBSTP,
UC_X86_INS_FCOMPP,
UC_X86_INS_FDECSTP,
UC_X86_INS_FEMMS,
UC_X86_INS_FFREE,
UC_X86_INS_FICOM,
UC_X86_INS_FICOMP,
UC_X86_INS_FINCSTP,
UC_X86_INS_FLDCW,
UC_X86_INS_FLDENV,
UC_X86_INS_FLDL2E,
UC_X86_INS_FLDL2T,
UC_X86_INS_FLDLG2,
UC_X86_INS_FLDLN2,
UC_X86_INS_FLDPI,
UC_X86_INS_FNCLEX,
UC_X86_INS_FNINIT,
UC_X86_INS_FNOP,
UC_X86_INS_FNSTCW,
UC_X86_INS_FNSTSW,
UC_X86_INS_FPATAN,
UC_X86_INS_FPREM,
UC_X86_INS_FPREM1,
UC_X86_INS_FPTAN,
UC_X86_INS_FFREEP,
UC_X86_INS_FRNDINT,
UC_X86_INS_FRSTOR,
UC_X86_INS_FNSAVE,
UC_X86_INS_FSCALE,
UC_X86_INS_FSETPM,
UC_X86_INS_FSINCOS,
UC_X86_INS_FNSTENV,
UC_X86_INS_FXAM,
UC_X86_INS_FXRSTOR,
UC_X86_INS_FXRSTOR64,
UC_X86_INS_FXSAVE,
UC_X86_INS_FXSAVE64,
UC_X86_INS_FXTRACT,
UC_X86_INS_FYL2X,
UC_X86_INS_FYL2XP1,
UC_X86_INS_MOVAPD,
UC_X86_INS_MOVAPS,
UC_X86_INS_ORPD,
UC_X86_INS_ORPS,
UC_X86_INS_VMOVAPD,
UC_X86_INS_VMOVAPS,
UC_X86_INS_XORPD,
UC_X86_INS_XORPS,
UC_X86_INS_GETSEC,
UC_X86_INS_HADDPD,
UC_X86_INS_HADDPS,
UC_X86_INS_HLT,
UC_X86_INS_HSUBPD,
UC_X86_INS_HSUBPS,
UC_X86_INS_IDIV,
UC_X86_INS_FILD,
UC_X86_INS_IMUL,
UC_X86_INS_IN,
UC_X86_INS_INC,
UC_X86_INS_INSB,
UC_X86_INS_INSERTPS,
UC_X86_INS_INSERTQ,
UC_X86_INS_INSD,
UC_X86_INS_INSW,
UC_X86_INS_INT,
UC_X86_INS_INT1,
UC_X86_INS_INT3,
UC_X86_INS_INTO,
UC_X86_INS_INVD,
UC_X86_INS_INVEPT,
UC_X86_INS_INVLPG,
UC_X86_INS_INVLPGA,
UC_X86_INS_INVPCID,
UC_X86_INS_INVVPID,
UC_X86_INS_IRET,
UC_X86_INS_IRETD,
UC_X86_INS_IRETQ,
UC_X86_INS_FISTTP,
UC_X86_INS_FIST,
UC_X86_INS_FISTP,
UC_X86_INS_UCOMISD,
UC_X86_INS_UCOMISS,
UC_X86_INS_VCOMISD,
UC_X86_INS_VCOMISS,
UC_X86_INS_VCVTSD2SS,
UC_X86_INS_VCVTSI2SD,
UC_X86_INS_VCVTSI2SS,
UC_X86_INS_VCVTSS2SD,
UC_X86_INS_VCVTTSD2SI,
UC_X86_INS_VCVTTSD2USI,
UC_X86_INS_VCVTTSS2SI,
UC_X86_INS_VCVTTSS2USI,
UC_X86_INS_VCVTUSI2SD,
UC_X86_INS_VCVTUSI2SS,
UC_X86_INS_VUCOMISD,
UC_X86_INS_VUCOMISS,
UC_X86_INS_JAE,
UC_X86_INS_JA,
UC_X86_INS_JBE,
UC_X86_INS_JB,
UC_X86_INS_JCXZ,
UC_X86_INS_JECXZ,
UC_X86_INS_JE,
UC_X86_INS_JGE,
UC_X86_INS_JG,
UC_X86_INS_JLE,
UC_X86_INS_JL,
UC_X86_INS_JMP,
UC_X86_INS_JNE,
UC_X86_INS_JNO,
UC_X86_INS_JNP,
UC_X86_INS_JNS,
UC_X86_INS_JO,
UC_X86_INS_JP,
UC_X86_INS_JRCXZ,
UC_X86_INS_JS,
UC_X86_INS_KANDB,
UC_X86_INS_KANDD,
UC_X86_INS_KANDNB,
UC_X86_INS_KANDND,
UC_X86_INS_KANDNQ,
UC_X86_INS_KANDNW,
UC_X86_INS_KANDQ,
UC_X86_INS_KANDW,
UC_X86_INS_KMOVB,
UC_X86_INS_KMOVD,
UC_X86_INS_KMOVQ,
UC_X86_INS_KMOVW,
UC_X86_INS_KNOTB,
UC_X86_INS_KNOTD,
UC_X86_INS_KNOTQ,
UC_X86_INS_KNOTW,
UC_X86_INS_KORB,
UC_X86_INS_KORD,
UC_X86_INS_KORQ,
UC_X86_INS_KORTESTB,
UC_X86_INS_KORTESTD,
UC_X86_INS_KORTESTQ,
UC_X86_INS_KORTESTW,
UC_X86_INS_KORW,
UC_X86_INS_KSHIFTLB,
UC_X86_INS_KSHIFTLD,
UC_X86_INS_KSHIFTLQ,
UC_X86_INS_KSHIFTLW,
UC_X86_INS_KSHIFTRB,
UC_X86_INS_KSHIFTRD,
UC_X86_INS_KSHIFTRQ,
UC_X86_INS_KSHIFTRW,
UC_X86_INS_KUNPCKBW,
UC_X86_INS_KXNORB,
UC_X86_INS_KXNORD,
UC_X86_INS_KXNORQ,
UC_X86_INS_KXNORW,
UC_X86_INS_KXORB,
UC_X86_INS_KXORD,
UC_X86_INS_KXORQ,
UC_X86_INS_KXORW,
UC_X86_INS_LAHF,
UC_X86_INS_LAR,
UC_X86_INS_LDDQU,
UC_X86_INS_LDMXCSR,
UC_X86_INS_LDS,
UC_X86_INS_FLDZ,
UC_X86_INS_FLD1,
UC_X86_INS_FLD,
UC_X86_INS_LEA,
UC_X86_INS_LEAVE,
UC_X86_INS_LES,
UC_X86_INS_LFENCE,
UC_X86_INS_LFS,
UC_X86_INS_LGDT,
UC_X86_INS_LGS,
UC_X86_INS_LIDT,
UC_X86_INS_LLDT,
UC_X86_INS_LMSW,
UC_X86_INS_OR,
UC_X86_INS_SUB,
UC_X86_INS_XOR,
UC_X86_INS_LODSB,
UC_X86_INS_LODSD,
UC_X86_INS_LODSQ,
UC_X86_INS_LODSW,
UC_X86_INS_LOOP,
UC_X86_INS_LOOPE,
UC_X86_INS_LOOPNE,
UC_X86_INS_RETF,
UC_X86_INS_RETFQ,
UC_X86_INS_LSL,
UC_X86_INS_LSS,
UC_X86_INS_LTR,
UC_X86_INS_XADD,
UC_X86_INS_LZCNT,
UC_X86_INS_MASKMOVDQU,
UC_X86_INS_MAXPD,
UC_X86_INS_MAXPS,
UC_X86_INS_MAXSD,
UC_X86_INS_MAXSS,
UC_X86_INS_MFENCE,
UC_X86_INS_MINPD,
UC_X86_INS_MINPS,
UC_X86_INS_MINSD,
UC_X86_INS_MINSS,
UC_X86_INS_CVTPD2PI,
UC_X86_INS_CVTPI2PD,
UC_X86_INS_CVTPI2PS,
UC_X86_INS_CVTPS2PI,
UC_X86_INS_CVTTPD2PI,
UC_X86_INS_CVTTPS2PI,
UC_X86_INS_EMMS,
UC_X86_INS_MASKMOVQ,
UC_X86_INS_MOVD,
UC_X86_INS_MOVDQ2Q,
UC_X86_INS_MOVNTQ,
UC_X86_INS_MOVQ2DQ,
UC_X86_INS_MOVQ,
UC_X86_INS_PABSB,
UC_X86_INS_PABSD,
UC_X86_INS_PABSW,
UC_X86_INS_PACKSSDW,
UC_X86_INS_PACKSSWB,
UC_X86_INS_PACKUSWB,
UC_X86_INS_PADDB,
UC_X86_INS_PADDD,
UC_X86_INS_PADDQ,
UC_X86_INS_PADDSB,
UC_X86_INS_PADDSW,
UC_X86_INS_PADDUSB,
UC_X86_INS_PADDUSW,
UC_X86_INS_PADDW,
UC_X86_INS_PALIGNR,
UC_X86_INS_PANDN,
UC_X86_INS_PAND,
UC_X86_INS_PAVGB,
UC_X86_INS_PAVGW,
UC_X86_INS_PCMPEQB,
UC_X86_INS_PCMPEQD,
UC_X86_INS_PCMPEQW,
UC_X86_INS_PCMPGTB,
UC_X86_INS_PCMPGTD,
UC_X86_INS_PCMPGTW,
UC_X86_INS_PEXTRW,
UC_X86_INS_PHADDSW,
UC_X86_INS_PHADDW,
UC_X86_INS_PHADDD,
UC_X86_INS_PHSUBD,
UC_X86_INS_PHSUBSW,
UC_X86_INS_PHSUBW,
UC_X86_INS_PINSRW,
UC_X86_INS_PMADDUBSW,
UC_X86_INS_PMADDWD,
UC_X86_INS_PMAXSW,
UC_X86_INS_PMAXUB,
UC_X86_INS_PMINSW,
UC_X86_INS_PMINUB,
UC_X86_INS_PMOVMSKB,
UC_X86_INS_PMULHRSW,
UC_X86_INS_PMULHUW,
UC_X86_INS_PMULHW,
UC_X86_INS_PMULLW,
UC_X86_INS_PMULUDQ,
UC_X86_INS_POR,
UC_X86_INS_PSADBW,
UC_X86_INS_PSHUFB,
UC_X86_INS_PSHUFW,
UC_X86_INS_PSIGNB,
UC_X86_INS_PSIGND,
UC_X86_INS_PSIGNW,
UC_X86_INS_PSLLD,
UC_X86_INS_PSLLQ,
UC_X86_INS_PSLLW,
UC_X86_INS_PSRAD,
UC_X86_INS_PSRAW,
UC_X86_INS_PSRLD,
UC_X86_INS_PSRLQ,
UC_X86_INS_PSRLW,
UC_X86_INS_PSUBB,
UC_X86_INS_PSUBD,
UC_X86_INS_PSUBQ,
UC_X86_INS_PSUBSB,
UC_X86_INS_PSUBSW,
UC_X86_INS_PSUBUSB,
UC_X86_INS_PSUBUSW,
UC_X86_INS_PSUBW,
UC_X86_INS_PUNPCKHBW,
UC_X86_INS_PUNPCKHDQ,
UC_X86_INS_PUNPCKHWD,
UC_X86_INS_PUNPCKLBW,
UC_X86_INS_PUNPCKLDQ,
UC_X86_INS_PUNPCKLWD,
UC_X86_INS_PXOR,
UC_X86_INS_MONITOR,
UC_X86_INS_MONTMUL,
UC_X86_INS_MOV,
UC_X86_INS_MOVABS,
UC_X86_INS_MOVBE,
UC_X86_INS_MOVDDUP,
UC_X86_INS_MOVDQA,
UC_X86_INS_MOVDQU,
UC_X86_INS_MOVHLPS,
UC_X86_INS_MOVHPD,
UC_X86_INS_MOVHPS,
UC_X86_INS_MOVLHPS,
UC_X86_INS_MOVLPD,
UC_X86_INS_MOVLPS,
UC_X86_INS_MOVMSKPD,
UC_X86_INS_MOVMSKPS,
UC_X86_INS_MOVNTDQA,
UC_X86_INS_MOVNTDQ,
UC_X86_INS_MOVNTI,
UC_X86_INS_MOVNTPD,
UC_X86_INS_MOVNTPS,
UC_X86_INS_MOVNTSD,
UC_X86_INS_MOVNTSS,
UC_X86_INS_MOVSB,
UC_X86_INS_MOVSD,
UC_X86_INS_MOVSHDUP,
UC_X86_INS_MOVSLDUP,
UC_X86_INS_MOVSQ,
UC_X86_INS_MOVSS,
UC_X86_INS_MOVSW,
UC_X86_INS_MOVSX,
UC_X86_INS_MOVSXD,
UC_X86_INS_MOVUPD,
UC_X86_INS_MOVUPS,
UC_X86_INS_MOVZX,
UC_X86_INS_MPSADBW,
UC_X86_INS_MUL,
UC_X86_INS_MULPD,
UC_X86_INS_MULPS,
UC_X86_INS_MULSD,
UC_X86_INS_MULSS,
UC_X86_INS_MULX,
UC_X86_INS_FMUL,
UC_X86_INS_FIMUL,
UC_X86_INS_FMULP,
UC_X86_INS_MWAIT,
UC_X86_INS_NEG,
UC_X86_INS_NOP,
UC_X86_INS_NOT,
UC_X86_INS_OUT,
UC_X86_INS_OUTSB,
UC_X86_INS_OUTSD,
UC_X86_INS_OUTSW,
UC_X86_INS_PACKUSDW,
UC_X86_INS_PAUSE,
UC_X86_INS_PAVGUSB,
UC_X86_INS_PBLENDVB,
UC_X86_INS_PBLENDW,
UC_X86_INS_PCLMULQDQ,
UC_X86_INS_PCMPEQQ,
UC_X86_INS_PCMPESTRI,
UC_X86_INS_PCMPESTRM,
UC_X86_INS_PCMPGTQ,
UC_X86_INS_PCMPISTRI,
UC_X86_INS_PCMPISTRM,
UC_X86_INS_PCOMMIT,
UC_X86_INS_PDEP,
UC_X86_INS_PEXT,
UC_X86_INS_PEXTRB,
UC_X86_INS_PEXTRD,
UC_X86_INS_PEXTRQ,
UC_X86_INS_PF2ID,
UC_X86_INS_PF2IW,
UC_X86_INS_PFACC,
UC_X86_INS_PFADD,
UC_X86_INS_PFCMPEQ,
UC_X86_INS_PFCMPGE,
UC_X86_INS_PFCMPGT,
UC_X86_INS_PFMAX,
UC_X86_INS_PFMIN,
UC_X86_INS_PFMUL,
UC_X86_INS_PFNACC,
UC_X86_INS_PFPNACC,
UC_X86_INS_PFRCPIT1,
UC_X86_INS_PFRCPIT2,
UC_X86_INS_PFRCP,
UC_X86_INS_PFRSQIT1,
UC_X86_INS_PFRSQRT,
UC_X86_INS_PFSUBR,
UC_X86_INS_PFSUB,
UC_X86_INS_PHMINPOSUW,
UC_X86_INS_PI2FD,
UC_X86_INS_PI2FW,
UC_X86_INS_PINSRB,
UC_X86_INS_PINSRD,
UC_X86_INS_PINSRQ,
UC_X86_INS_PMAXSB,
UC_X86_INS_PMAXSD,
UC_X86_INS_PMAXUD,
UC_X86_INS_PMAXUW,
UC_X86_INS_PMINSB,
UC_X86_INS_PMINSD,
UC_X86_INS_PMINUD,
UC_X86_INS_PMINUW,
UC_X86_INS_PMOVSXBD,
UC_X86_INS_PMOVSXBQ,
UC_X86_INS_PMOVSXBW,
UC_X86_INS_PMOVSXDQ,
UC_X86_INS_PMOVSXWD,
UC_X86_INS_PMOVSXWQ,
UC_X86_INS_PMOVZXBD,
UC_X86_INS_PMOVZXBQ,
UC_X86_INS_PMOVZXBW,
UC_X86_INS_PMOVZXDQ,
UC_X86_INS_PMOVZXWD,
UC_X86_INS_PMOVZXWQ,
UC_X86_INS_PMULDQ,
UC_X86_INS_PMULHRW,
UC_X86_INS_PMULLD,
UC_X86_INS_POP,
UC_X86_INS_POPAW,
UC_X86_INS_POPAL,
UC_X86_INS_POPCNT,
UC_X86_INS_POPF,
UC_X86_INS_POPFD,
UC_X86_INS_POPFQ,
UC_X86_INS_PREFETCH,
UC_X86_INS_PREFETCHNTA,
UC_X86_INS_PREFETCHT0,
UC_X86_INS_PREFETCHT1,
UC_X86_INS_PREFETCHT2,
UC_X86_INS_PREFETCHW,
UC_X86_INS_PSHUFD,
UC_X86_INS_PSHUFHW,
UC_X86_INS_PSHUFLW,
UC_X86_INS_PSLLDQ,
UC_X86_INS_PSRLDQ,
UC_X86_INS_PSWAPD,
UC_X86_INS_PTEST,
UC_X86_INS_PUNPCKHQDQ,
UC_X86_INS_PUNPCKLQDQ,
UC_X86_INS_PUSH,
UC_X86_INS_PUSHAW,
UC_X86_INS_PUSHAL,
UC_X86_INS_PUSHF,
UC_X86_INS_PUSHFD,
UC_X86_INS_PUSHFQ,
UC_X86_INS_RCL,
UC_X86_INS_RCPPS,
UC_X86_INS_RCPSS,
UC_X86_INS_RCR,
UC_X86_INS_RDFSBASE,
UC_X86_INS_RDGSBASE,
UC_X86_INS_RDMSR,
UC_X86_INS_RDPMC,
UC_X86_INS_RDRAND,
UC_X86_INS_RDSEED,
UC_X86_INS_RDTSC,
UC_X86_INS_RDTSCP,
UC_X86_INS_ROL,
UC_X86_INS_ROR,
UC_X86_INS_RORX,
UC_X86_INS_ROUNDPD,
UC_X86_INS_ROUNDPS,
UC_X86_INS_ROUNDSD,
UC_X86_INS_ROUNDSS,
UC_X86_INS_RSM,
UC_X86_INS_RSQRTPS,
UC_X86_INS_RSQRTSS,
UC_X86_INS_SAHF,
UC_X86_INS_SAL,
UC_X86_INS_SALC,
UC_X86_INS_SAR,
UC_X86_INS_SARX,
UC_X86_INS_SBB,
UC_X86_INS_SCASB,
UC_X86_INS_SCASD,
UC_X86_INS_SCASQ,
UC_X86_INS_SCASW,
UC_X86_INS_SETAE,
UC_X86_INS_SETA,
UC_X86_INS_SETBE,
UC_X86_INS_SETB,
UC_X86_INS_SETE,
UC_X86_INS_SETGE,
UC_X86_INS_SETG,
UC_X86_INS_SETLE,
UC_X86_INS_SETL,
UC_X86_INS_SETNE,
UC_X86_INS_SETNO,
UC_X86_INS_SETNP,
UC_X86_INS_SETNS,
UC_X86_INS_SETO,
UC_X86_INS_SETP,
UC_X86_INS_SETS,
UC_X86_INS_SFENCE,
UC_X86_INS_SGDT,
UC_X86_INS_SHA1MSG1,
UC_X86_INS_SHA1MSG2,
UC_X86_INS_SHA1NEXTE,
UC_X86_INS_SHA1RNDS4,
UC_X86_INS_SHA256MSG1,
UC_X86_INS_SHA256MSG2,
UC_X86_INS_SHA256RNDS2,
UC_X86_INS_SHL,
UC_X86_INS_SHLD,
UC_X86_INS_SHLX,
UC_X86_INS_SHR,
UC_X86_INS_SHRD,
UC_X86_INS_SHRX,
UC_X86_INS_SHUFPD,
UC_X86_INS_SHUFPS,
UC_X86_INS_SIDT,
UC_X86_INS_FSIN,
UC_X86_INS_SKINIT,
UC_X86_INS_SLDT,
UC_X86_INS_SMSW,
UC_X86_INS_SQRTPD,
UC_X86_INS_SQRTPS,
UC_X86_INS_SQRTSD,
UC_X86_INS_SQRTSS,
UC_X86_INS_FSQRT,
UC_X86_INS_STAC,
UC_X86_INS_STC,
UC_X86_INS_STD,
UC_X86_INS_STGI,
UC_X86_INS_STI,
UC_X86_INS_STMXCSR,
UC_X86_INS_STOSB,
UC_X86_INS_STOSD,
UC_X86_INS_STOSQ,
UC_X86_INS_STOSW,
UC_X86_INS_STR,
UC_X86_INS_FST,
UC_X86_INS_FSTP,
UC_X86_INS_FSTPNCE,
UC_X86_INS_FXCH,
UC_X86_INS_SUBPD,
UC_X86_INS_SUBPS,
UC_X86_INS_FSUBR,
UC_X86_INS_FISUBR,
UC_X86_INS_FSUBRP,
UC_X86_INS_SUBSD,
UC_X86_INS_SUBSS,
UC_X86_INS_FSUB,
UC_X86_INS_FISUB,
UC_X86_INS_FSUBP,
UC_X86_INS_SWAPGS,
UC_X86_INS_SYSCALL,
UC_X86_INS_SYSENTER,
UC_X86_INS_SYSEXIT,
UC_X86_INS_SYSRET,
UC_X86_INS_T1MSKC,
UC_X86_INS_TEST,
UC_X86_INS_UD2,
UC_X86_INS_FTST,
UC_X86_INS_TZCNT,
UC_X86_INS_TZMSK,
UC_X86_INS_FUCOMPI,
UC_X86_INS_FUCOMI,
UC_X86_INS_FUCOMPP,
UC_X86_INS_FUCOMP,
UC_X86_INS_FUCOM,
UC_X86_INS_UD2B,
UC_X86_INS_UNPCKHPD,
UC_X86_INS_UNPCKHPS,
UC_X86_INS_UNPCKLPD,
UC_X86_INS_UNPCKLPS,
UC_X86_INS_VADDPD,
UC_X86_INS_VADDPS,
UC_X86_INS_VADDSD,
UC_X86_INS_VADDSS,
UC_X86_INS_VADDSUBPD,
UC_X86_INS_VADDSUBPS,
UC_X86_INS_VAESDECLAST,
UC_X86_INS_VAESDEC,
UC_X86_INS_VAESENCLAST,
UC_X86_INS_VAESENC,
UC_X86_INS_VAESIMC,
UC_X86_INS_VAESKEYGENASSIST,
UC_X86_INS_VALIGND,
UC_X86_INS_VALIGNQ,
UC_X86_INS_VANDNPD,
UC_X86_INS_VANDNPS,
UC_X86_INS_VANDPD,
UC_X86_INS_VANDPS,
UC_X86_INS_VBLENDMPD,
UC_X86_INS_VBLENDMPS,
UC_X86_INS_VBLENDPD,
UC_X86_INS_VBLENDPS,
UC_X86_INS_VBLENDVPD,
UC_X86_INS_VBLENDVPS,
UC_X86_INS_VBROADCASTF128,
UC_X86_INS_VBROADCASTI32X4,
UC_X86_INS_VBROADCASTI64X4,
UC_X86_INS_VBROADCASTSD,
UC_X86_INS_VBROADCASTSS,
UC_X86_INS_VCMPPD,
UC_X86_INS_VCMPPS,
UC_X86_INS_VCMPSD,
UC_X86_INS_VCMPSS,
UC_X86_INS_VCOMPRESSPD,
UC_X86_INS_VCOMPRESSPS,
UC_X86_INS_VCVTDQ2PD,
UC_X86_INS_VCVTDQ2PS,
UC_X86_INS_VCVTPD2DQX,
UC_X86_INS_VCVTPD2DQ,
UC_X86_INS_VCVTPD2PSX,
UC_X86_INS_VCVTPD2PS,
UC_X86_INS_VCVTPD2UDQ,
UC_X86_INS_VCVTPH2PS,
UC_X86_INS_VCVTPS2DQ,
UC_X86_INS_VCVTPS2PD,
UC_X86_INS_VCVTPS2PH,
UC_X86_INS_VCVTPS2UDQ,
UC_X86_INS_VCVTSD2SI,
UC_X86_INS_VCVTSD2USI,
UC_X86_INS_VCVTSS2SI,
UC_X86_INS_VCVTSS2USI,
UC_X86_INS_VCVTTPD2DQX,
UC_X86_INS_VCVTTPD2DQ,
UC_X86_INS_VCVTTPD2UDQ,
UC_X86_INS_VCVTTPS2DQ,
UC_X86_INS_VCVTTPS2UDQ,
UC_X86_INS_VCVTUDQ2PD,
UC_X86_INS_VCVTUDQ2PS,
UC_X86_INS_VDIVPD,
UC_X86_INS_VDIVPS,
UC_X86_INS_VDIVSD,
UC_X86_INS_VDIVSS,
UC_X86_INS_VDPPD,
UC_X86_INS_VDPPS,
UC_X86_INS_VERR,
UC_X86_INS_VERW,
UC_X86_INS_VEXP2PD,
UC_X86_INS_VEXP2PS,
UC_X86_INS_VEXPANDPD,
UC_X86_INS_VEXPANDPS,
UC_X86_INS_VEXTRACTF128,
UC_X86_INS_VEXTRACTF32X4,
UC_X86_INS_VEXTRACTF64X4,
UC_X86_INS_VEXTRACTI128,
UC_X86_INS_VEXTRACTI32X4,
UC_X86_INS_VEXTRACTI64X4,
UC_X86_INS_VEXTRACTPS,
UC_X86_INS_VFMADD132PD,
UC_X86_INS_VFMADD132PS,
UC_X86_INS_VFMADDPD,
UC_X86_INS_VFMADD213PD,
UC_X86_INS_VFMADD231PD,
UC_X86_INS_VFMADDPS,
UC_X86_INS_VFMADD213PS,
UC_X86_INS_VFMADD231PS,
UC_X86_INS_VFMADDSD,
UC_X86_INS_VFMADD213SD,
UC_X86_INS_VFMADD132SD,
UC_X86_INS_VFMADD231SD,
UC_X86_INS_VFMADDSS,
UC_X86_INS_VFMADD213SS,
UC_X86_INS_VFMADD132SS,
UC_X86_INS_VFMADD231SS,
UC_X86_INS_VFMADDSUB132PD,
UC_X86_INS_VFMADDSUB132PS,
UC_X86_INS_VFMADDSUBPD,
UC_X86_INS_VFMADDSUB213PD,
UC_X86_INS_VFMADDSUB231PD,
UC_X86_INS_VFMADDSUBPS,
UC_X86_INS_VFMADDSUB213PS,
UC_X86_INS_VFMADDSUB231PS,
UC_X86_INS_VFMSUB132PD,
UC_X86_INS_VFMSUB132PS,
UC_X86_INS_VFMSUBADD132PD,
UC_X86_INS_VFMSUBADD132PS,
UC_X86_INS_VFMSUBADDPD,
UC_X86_INS_VFMSUBADD213PD,
UC_X86_INS_VFMSUBADD231PD,
UC_X86_INS_VFMSUBADDPS,
UC_X86_INS_VFMSUBADD213PS,
UC_X86_INS_VFMSUBADD231PS,
UC_X86_INS_VFMSUBPD,
UC_X86_INS_VFMSUB213PD,
UC_X86_INS_VFMSUB231PD,
UC_X86_INS_VFMSUBPS,
UC_X86_INS_VFMSUB213PS,
UC_X86_INS_VFMSUB231PS,
UC_X86_INS_VFMSUBSD,
UC_X86_INS_VFMSUB213SD,
UC_X86_INS_VFMSUB132SD,
UC_X86_INS_VFMSUB231SD,
UC_X86_INS_VFMSUBSS,
UC_X86_INS_VFMSUB213SS,
UC_X86_INS_VFMSUB132SS,
UC_X86_INS_VFMSUB231SS,
UC_X86_INS_VFNMADD132PD,
UC_X86_INS_VFNMADD132PS,
UC_X86_INS_VFNMADDPD,
UC_X86_INS_VFNMADD213PD,
UC_X86_INS_VFNMADD231PD,
UC_X86_INS_VFNMADDPS,
UC_X86_INS_VFNMADD213PS,
UC_X86_INS_VFNMADD231PS,
UC_X86_INS_VFNMADDSD,
UC_X86_INS_VFNMADD213SD,
UC_X86_INS_VFNMADD132SD,
UC_X86_INS_VFNMADD231SD,
UC_X86_INS_VFNMADDSS,
UC_X86_INS_VFNMADD213SS,
UC_X86_INS_VFNMADD132SS,
UC_X86_INS_VFNMADD231SS,
UC_X86_INS_VFNMSUB132PD,
UC_X86_INS_VFNMSUB132PS,
UC_X86_INS_VFNMSUBPD,
UC_X86_INS_VFNMSUB213PD,
UC_X86_INS_VFNMSUB231PD,
UC_X86_INS_VFNMSUBPS,
UC_X86_INS_VFNMSUB213PS,
UC_X86_INS_VFNMSUB231PS,
UC_X86_INS_VFNMSUBSD,
UC_X86_INS_VFNMSUB213SD,
UC_X86_INS_VFNMSUB132SD,
UC_X86_INS_VFNMSUB231SD,
UC_X86_INS_VFNMSUBSS,
UC_X86_INS_VFNMSUB213SS,
UC_X86_INS_VFNMSUB132SS,
UC_X86_INS_VFNMSUB231SS,
UC_X86_INS_VFRCZPD,
UC_X86_INS_VFRCZPS,
UC_X86_INS_VFRCZSD,
UC_X86_INS_VFRCZSS,
UC_X86_INS_VORPD,
UC_X86_INS_VORPS,
UC_X86_INS_VXORPD,
UC_X86_INS_VXORPS,
UC_X86_INS_VGATHERDPD,
UC_X86_INS_VGATHERDPS,
UC_X86_INS_VGATHERPF0DPD,
UC_X86_INS_VGATHERPF0DPS,
UC_X86_INS_VGATHERPF0QPD,
UC_X86_INS_VGATHERPF0QPS,
UC_X86_INS_VGATHERPF1DPD,
UC_X86_INS_VGATHERPF1DPS,
UC_X86_INS_VGATHERPF1QPD,
UC_X86_INS_VGATHERPF1QPS,
UC_X86_INS_VGATHERQPD,
UC_X86_INS_VGATHERQPS,
UC_X86_INS_VHADDPD,
UC_X86_INS_VHADDPS,
UC_X86_INS_VHSUBPD,
UC_X86_INS_VHSUBPS,
UC_X86_INS_VINSERTF128,
UC_X86_INS_VINSERTF32X4,
UC_X86_INS_VINSERTF32X8,
UC_X86_INS_VINSERTF64X2,
UC_X86_INS_VINSERTF64X4,
UC_X86_INS_VINSERTI128,
UC_X86_INS_VINSERTI32X4,
UC_X86_INS_VINSERTI32X8,
UC_X86_INS_VINSERTI64X2,
UC_X86_INS_VINSERTI64X4,
UC_X86_INS_VINSERTPS,
UC_X86_INS_VLDDQU,
UC_X86_INS_VLDMXCSR,
UC_X86_INS_VMASKMOVDQU,
UC_X86_INS_VMASKMOVPD,
UC_X86_INS_VMASKMOVPS,
UC_X86_INS_VMAXPD,
UC_X86_INS_VMAXPS,
UC_X86_INS_VMAXSD,
UC_X86_INS_VMAXSS,
UC_X86_INS_VMCALL,
UC_X86_INS_VMCLEAR,
UC_X86_INS_VMFUNC,
UC_X86_INS_VMINPD,
UC_X86_INS_VMINPS,
UC_X86_INS_VMINSD,
UC_X86_INS_VMINSS,
UC_X86_INS_VMLAUNCH,
UC_X86_INS_VMLOAD,
UC_X86_INS_VMMCALL,
UC_X86_INS_VMOVQ,
UC_X86_INS_VMOVDDUP,
UC_X86_INS_VMOVD,
UC_X86_INS_VMOVDQA32,
UC_X86_INS_VMOVDQA64,
UC_X86_INS_VMOVDQA,
UC_X86_INS_VMOVDQU16,
UC_X86_INS_VMOVDQU32,
UC_X86_INS_VMOVDQU64,
UC_X86_INS_VMOVDQU8,
UC_X86_INS_VMOVDQU,
UC_X86_INS_VMOVHLPS,
UC_X86_INS_VMOVHPD,
UC_X86_INS_VMOVHPS,
UC_X86_INS_VMOVLHPS,
UC_X86_INS_VMOVLPD,
UC_X86_INS_VMOVLPS,
UC_X86_INS_VMOVMSKPD,
UC_X86_INS_VMOVMSKPS,
UC_X86_INS_VMOVNTDQA,
UC_X86_INS_VMOVNTDQ,
UC_X86_INS_VMOVNTPD,
UC_X86_INS_VMOVNTPS,
UC_X86_INS_VMOVSD,
UC_X86_INS_VMOVSHDUP,
UC_X86_INS_VMOVSLDUP,
UC_X86_INS_VMOVSS,
UC_X86_INS_VMOVUPD,
UC_X86_INS_VMOVUPS,
UC_X86_INS_VMPSADBW,
UC_X86_INS_VMPTRLD,
UC_X86_INS_VMPTRST,
UC_X86_INS_VMREAD,
UC_X86_INS_VMRESUME,
UC_X86_INS_VMRUN,
UC_X86_INS_VMSAVE,
UC_X86_INS_VMULPD,
UC_X86_INS_VMULPS,
UC_X86_INS_VMULSD,
UC_X86_INS_VMULSS,
UC_X86_INS_VMWRITE,
UC_X86_INS_VMXOFF,
UC_X86_INS_VMXON,
UC_X86_INS_VPABSB,
UC_X86_INS_VPABSD,
UC_X86_INS_VPABSQ,
UC_X86_INS_VPABSW,
UC_X86_INS_VPACKSSDW,
UC_X86_INS_VPACKSSWB,
UC_X86_INS_VPACKUSDW,
UC_X86_INS_VPACKUSWB,
UC_X86_INS_VPADDB,
UC_X86_INS_VPADDD,
UC_X86_INS_VPADDQ,
UC_X86_INS_VPADDSB,
UC_X86_INS_VPADDSW,
UC_X86_INS_VPADDUSB,
UC_X86_INS_VPADDUSW,
UC_X86_INS_VPADDW,
UC_X86_INS_VPALIGNR,
UC_X86_INS_VPANDD,
UC_X86_INS_VPANDND,
UC_X86_INS_VPANDNQ,
UC_X86_INS_VPANDN,
UC_X86_INS_VPANDQ,
UC_X86_INS_VPAND,
UC_X86_INS_VPAVGB,
UC_X86_INS_VPAVGW,
UC_X86_INS_VPBLENDD,
UC_X86_INS_VPBLENDMB,
UC_X86_INS_VPBLENDMD,
UC_X86_INS_VPBLENDMQ,
UC_X86_INS_VPBLENDMW,
UC_X86_INS_VPBLENDVB,
UC_X86_INS_VPBLENDW,
UC_X86_INS_VPBROADCASTB,
UC_X86_INS_VPBROADCASTD,
UC_X86_INS_VPBROADCASTMB2Q,
UC_X86_INS_VPBROADCASTMW2D,
UC_X86_INS_VPBROADCASTQ,
UC_X86_INS_VPBROADCASTW,
UC_X86_INS_VPCLMULQDQ,
UC_X86_INS_VPCMOV,
UC_X86_INS_VPCMPB,
UC_X86_INS_VPCMPD,
UC_X86_INS_VPCMPEQB,
UC_X86_INS_VPCMPEQD,
UC_X86_INS_VPCMPEQQ,
UC_X86_INS_VPCMPEQW,
UC_X86_INS_VPCMPESTRI,
UC_X86_INS_VPCMPESTRM,
UC_X86_INS_VPCMPGTB,
UC_X86_INS_VPCMPGTD,
UC_X86_INS_VPCMPGTQ,
UC_X86_INS_VPCMPGTW,
UC_X86_INS_VPCMPISTRI,
UC_X86_INS_VPCMPISTRM,
UC_X86_INS_VPCMPQ,
UC_X86_INS_VPCMPUB,
UC_X86_INS_VPCMPUD,
UC_X86_INS_VPCMPUQ,
UC_X86_INS_VPCMPUW,
UC_X86_INS_VPCMPW,
UC_X86_INS_VPCOMB,
UC_X86_INS_VPCOMD,
UC_X86_INS_VPCOMPRESSD,
UC_X86_INS_VPCOMPRESSQ,
UC_X86_INS_VPCOMQ,
UC_X86_INS_VPCOMUB,
UC_X86_INS_VPCOMUD,
UC_X86_INS_VPCOMUQ,
UC_X86_INS_VPCOMUW,
UC_X86_INS_VPCOMW,
UC_X86_INS_VPCONFLICTD,
UC_X86_INS_VPCONFLICTQ,
UC_X86_INS_VPERM2F128,
UC_X86_INS_VPERM2I128,
UC_X86_INS_VPERMD,
UC_X86_INS_VPERMI2D,
UC_X86_INS_VPERMI2PD,
UC_X86_INS_VPERMI2PS,
UC_X86_INS_VPERMI2Q,
UC_X86_INS_VPERMIL2PD,
UC_X86_INS_VPERMIL2PS,
UC_X86_INS_VPERMILPD,
UC_X86_INS_VPERMILPS,
UC_X86_INS_VPERMPD,
UC_X86_INS_VPERMPS,
UC_X86_INS_VPERMQ,
UC_X86_INS_VPERMT2D,
UC_X86_INS_VPERMT2PD,
UC_X86_INS_VPERMT2PS,
UC_X86_INS_VPERMT2Q,
UC_X86_INS_VPEXPANDD,
UC_X86_INS_VPEXPANDQ,
UC_X86_INS_VPEXTRB,
UC_X86_INS_VPEXTRD,
UC_X86_INS_VPEXTRQ,
UC_X86_INS_VPEXTRW,
UC_X86_INS_VPGATHERDD,
UC_X86_INS_VPGATHERDQ,
UC_X86_INS_VPGATHERQD,
UC_X86_INS_VPGATHERQQ,
UC_X86_INS_VPHADDBD,
UC_X86_INS_VPHADDBQ,
UC_X86_INS_VPHADDBW,
UC_X86_INS_VPHADDDQ,
UC_X86_INS_VPHADDD,
UC_X86_INS_VPHADDSW,
UC_X86_INS_VPHADDUBD,
UC_X86_INS_VPHADDUBQ,
UC_X86_INS_VPHADDUBW,
UC_X86_INS_VPHADDUDQ,
UC_X86_INS_VPHADDUWD,
UC_X86_INS_VPHADDUWQ,
UC_X86_INS_VPHADDWD,
UC_X86_INS_VPHADDWQ,
UC_X86_INS_VPHADDW,
UC_X86_INS_VPHMINPOSUW,
UC_X86_INS_VPHSUBBW,
UC_X86_INS_VPHSUBDQ,
UC_X86_INS_VPHSUBD,
UC_X86_INS_VPHSUBSW,
UC_X86_INS_VPHSUBWD,
UC_X86_INS_VPHSUBW,
UC_X86_INS_VPINSRB,
UC_X86_INS_VPINSRD,
UC_X86_INS_VPINSRQ,
UC_X86_INS_VPINSRW,
UC_X86_INS_VPLZCNTD,
UC_X86_INS_VPLZCNTQ,
UC_X86_INS_VPMACSDD,
UC_X86_INS_VPMACSDQH,
UC_X86_INS_VPMACSDQL,
UC_X86_INS_VPMACSSDD,
UC_X86_INS_VPMACSSDQH,
UC_X86_INS_VPMACSSDQL,
UC_X86_INS_VPMACSSWD,
UC_X86_INS_VPMACSSWW,
UC_X86_INS_VPMACSWD,
UC_X86_INS_VPMACSWW,
UC_X86_INS_VPMADCSSWD,
UC_X86_INS_VPMADCSWD,
UC_X86_INS_VPMADDUBSW,
UC_X86_INS_VPMADDWD,
UC_X86_INS_VPMASKMOVD,
UC_X86_INS_VPMASKMOVQ,
UC_X86_INS_VPMAXSB,
UC_X86_INS_VPMAXSD,
UC_X86_INS_VPMAXSQ,
UC_X86_INS_VPMAXSW,
UC_X86_INS_VPMAXUB,
UC_X86_INS_VPMAXUD,
UC_X86_INS_VPMAXUQ,
UC_X86_INS_VPMAXUW,
UC_X86_INS_VPMINSB,
UC_X86_INS_VPMINSD,
UC_X86_INS_VPMINSQ,
UC_X86_INS_VPMINSW,
UC_X86_INS_VPMINUB,
UC_X86_INS_VPMINUD,
UC_X86_INS_VPMINUQ,
UC_X86_INS_VPMINUW,
UC_X86_INS_VPMOVDB,
UC_X86_INS_VPMOVDW,
UC_X86_INS_VPMOVM2B,
UC_X86_INS_VPMOVM2D,
UC_X86_INS_VPMOVM2Q,
UC_X86_INS_VPMOVM2W,
UC_X86_INS_VPMOVMSKB,
UC_X86_INS_VPMOVQB,
UC_X86_INS_VPMOVQD,
UC_X86_INS_VPMOVQW,
UC_X86_INS_VPMOVSDB,
UC_X86_INS_VPMOVSDW,
UC_X86_INS_VPMOVSQB,
UC_X86_INS_VPMOVSQD,
UC_X86_INS_VPMOVSQW,
UC_X86_INS_VPMOVSXBD,
UC_X86_INS_VPMOVSXBQ,
UC_X86_INS_VPMOVSXBW,
UC_X86_INS_VPMOVSXDQ,
UC_X86_INS_VPMOVSXWD,
UC_X86_INS_VPMOVSXWQ,
UC_X86_INS_VPMOVUSDB,
UC_X86_INS_VPMOVUSDW,
UC_X86_INS_VPMOVUSQB,
UC_X86_INS_VPMOVUSQD,
UC_X86_INS_VPMOVUSQW,
UC_X86_INS_VPMOVZXBD,
UC_X86_INS_VPMOVZXBQ,
UC_X86_INS_VPMOVZXBW,
UC_X86_INS_VPMOVZXDQ,
UC_X86_INS_VPMOVZXWD,
UC_X86_INS_VPMOVZXWQ,
UC_X86_INS_VPMULDQ,
UC_X86_INS_VPMULHRSW,
UC_X86_INS_VPMULHUW,
UC_X86_INS_VPMULHW,
UC_X86_INS_VPMULLD,
UC_X86_INS_VPMULLQ,
UC_X86_INS_VPMULLW,
UC_X86_INS_VPMULUDQ,
UC_X86_INS_VPORD,
UC_X86_INS_VPORQ,
UC_X86_INS_VPOR,
UC_X86_INS_VPPERM,
UC_X86_INS_VPROTB,
UC_X86_INS_VPROTD,
UC_X86_INS_VPROTQ,
UC_X86_INS_VPROTW,
UC_X86_INS_VPSADBW,
UC_X86_INS_VPSCATTERDD,
UC_X86_INS_VPSCATTERDQ,
UC_X86_INS_VPSCATTERQD,
UC_X86_INS_VPSCATTERQQ,
UC_X86_INS_VPSHAB,
UC_X86_INS_VPSHAD,
UC_X86_INS_VPSHAQ,
UC_X86_INS_VPSHAW,
UC_X86_INS_VPSHLB,
UC_X86_INS_VPSHLD,
UC_X86_INS_VPSHLQ,
UC_X86_INS_VPSHLW,
UC_X86_INS_VPSHUFB,
UC_X86_INS_VPSHUFD,
UC_X86_INS_VPSHUFHW,
UC_X86_INS_VPSHUFLW,
UC_X86_INS_VPSIGNB,
UC_X86_INS_VPSIGND,
UC_X86_INS_VPSIGNW,
UC_X86_INS_VPSLLDQ,
UC_X86_INS_VPSLLD,
UC_X86_INS_VPSLLQ,
UC_X86_INS_VPSLLVD,
UC_X86_INS_VPSLLVQ,
UC_X86_INS_VPSLLW,
UC_X86_INS_VPSRAD,
UC_X86_INS_VPSRAQ,
UC_X86_INS_VPSRAVD,
UC_X86_INS_VPSRAVQ,
UC_X86_INS_VPSRAW,
UC_X86_INS_VPSRLDQ,
UC_X86_INS_VPSRLD,
UC_X86_INS_VPSRLQ,
UC_X86_INS_VPSRLVD,
UC_X86_INS_VPSRLVQ,
UC_X86_INS_VPSRLW,
UC_X86_INS_VPSUBB,
UC_X86_INS_VPSUBD,
UC_X86_INS_VPSUBQ,
UC_X86_INS_VPSUBSB,
UC_X86_INS_VPSUBSW,
UC_X86_INS_VPSUBUSB,
UC_X86_INS_VPSUBUSW,
UC_X86_INS_VPSUBW,
UC_X86_INS_VPTESTMD,
UC_X86_INS_VPTESTMQ,
UC_X86_INS_VPTESTNMD,
UC_X86_INS_VPTESTNMQ,
UC_X86_INS_VPTEST,
UC_X86_INS_VPUNPCKHBW,
UC_X86_INS_VPUNPCKHDQ,
UC_X86_INS_VPUNPCKHQDQ,
UC_X86_INS_VPUNPCKHWD,
UC_X86_INS_VPUNPCKLBW,
UC_X86_INS_VPUNPCKLDQ,
UC_X86_INS_VPUNPCKLQDQ,
UC_X86_INS_VPUNPCKLWD,
UC_X86_INS_VPXORD,
UC_X86_INS_VPXORQ,
UC_X86_INS_VPXOR,
UC_X86_INS_VRCP14PD,
UC_X86_INS_VRCP14PS,
UC_X86_INS_VRCP14SD,
UC_X86_INS_VRCP14SS,
UC_X86_INS_VRCP28PD,
UC_X86_INS_VRCP28PS,
UC_X86_INS_VRCP28SD,
UC_X86_INS_VRCP28SS,
UC_X86_INS_VRCPPS,
UC_X86_INS_VRCPSS,
UC_X86_INS_VRNDSCALEPD,
UC_X86_INS_VRNDSCALEPS,
UC_X86_INS_VRNDSCALESD,
UC_X86_INS_VRNDSCALESS,
UC_X86_INS_VROUNDPD,
UC_X86_INS_VROUNDPS,
UC_X86_INS_VROUNDSD,
UC_X86_INS_VROUNDSS,
UC_X86_INS_VRSQRT14PD,
UC_X86_INS_VRSQRT14PS,
UC_X86_INS_VRSQRT14SD,
UC_X86_INS_VRSQRT14SS,
UC_X86_INS_VRSQRT28PD,
UC_X86_INS_VRSQRT28PS,
UC_X86_INS_VRSQRT28SD,
UC_X86_INS_VRSQRT28SS,
UC_X86_INS_VRSQRTPS,
UC_X86_INS_VRSQRTSS,
UC_X86_INS_VSCATTERDPD,
UC_X86_INS_VSCATTERDPS,
UC_X86_INS_VSCATTERPF0DPD,
UC_X86_INS_VSCATTERPF0DPS,
UC_X86_INS_VSCATTERPF0QPD,
UC_X86_INS_VSCATTERPF0QPS,
UC_X86_INS_VSCATTERPF1DPD,
UC_X86_INS_VSCATTERPF1DPS,
UC_X86_INS_VSCATTERPF1QPD,
UC_X86_INS_VSCATTERPF1QPS,
UC_X86_INS_VSCATTERQPD,
UC_X86_INS_VSCATTERQPS,
UC_X86_INS_VSHUFPD,
UC_X86_INS_VSHUFPS,
UC_X86_INS_VSQRTPD,
UC_X86_INS_VSQRTPS,
UC_X86_INS_VSQRTSD,
UC_X86_INS_VSQRTSS,
UC_X86_INS_VSTMXCSR,
UC_X86_INS_VSUBPD,
UC_X86_INS_VSUBPS,
UC_X86_INS_VSUBSD,
UC_X86_INS_VSUBSS,
UC_X86_INS_VTESTPD,
UC_X86_INS_VTESTPS,
UC_X86_INS_VUNPCKHPD,
UC_X86_INS_VUNPCKHPS,
UC_X86_INS_VUNPCKLPD,
UC_X86_INS_VUNPCKLPS,
UC_X86_INS_VZEROALL,
UC_X86_INS_VZEROUPPER,
UC_X86_INS_WAIT,
UC_X86_INS_WBINVD,
UC_X86_INS_WRFSBASE,
UC_X86_INS_WRGSBASE,
UC_X86_INS_WRMSR,
UC_X86_INS_XABORT,
UC_X86_INS_XACQUIRE,
UC_X86_INS_XBEGIN,
UC_X86_INS_XCHG,
UC_X86_INS_XCRYPTCBC,
UC_X86_INS_XCRYPTCFB,
UC_X86_INS_XCRYPTCTR,
UC_X86_INS_XCRYPTECB,
UC_X86_INS_XCRYPTOFB,
UC_X86_INS_XEND,
UC_X86_INS_XGETBV,
UC_X86_INS_XLATB,
UC_X86_INS_XRELEASE,
UC_X86_INS_XRSTOR,
UC_X86_INS_XRSTOR64,
UC_X86_INS_XRSTORS,
UC_X86_INS_XRSTORS64,
UC_X86_INS_XSAVE,
UC_X86_INS_XSAVE64,
UC_X86_INS_XSAVEC,
UC_X86_INS_XSAVEC64,
UC_X86_INS_XSAVEOPT,
UC_X86_INS_XSAVEOPT64,
UC_X86_INS_XSAVES,
UC_X86_INS_XSAVES64,
UC_X86_INS_XSETBV,
UC_X86_INS_XSHA1,
UC_X86_INS_XSHA256,
UC_X86_INS_XSTORE,
UC_X86_INS_XTEST,
UC_X86_INS_FDISI8087_NOP,
UC_X86_INS_FENI8087_NOP,
UC_X86_INS_ENDING, // mark the end of the list of insn
} uc_x86_insn;