前言

复现网鼎的题目的时候看到大佬用了Capstone,结果看不懂。。。。就顺便学习下。。

正文

感觉还是看官方文档更全面一点:http://www.capstone-engine.org/lang_python.html

这里就搞几个小脚本来学习下怎么用。

脚本1:基础反汇编

1
2
3
4
5
6
7
from capstone import *
cs = Cs(CS_ARCH_X86, CS_MODE_64)#设置cpu体系为64位的x86
cs.detail = True
code = '\xeb\x0b\x5b\x31\xc0\x31\xc9\x31\xd2\xb0\x0b\xcd\x80\xe8\xf0\xff\xff\xff\x2f\x62\x69\x6e\x2f\x73\x68'
discode = cs.disasm(code, 0x400800)#反汇编代码,其实地址为0x400800
for i in discode:
print "0x%x:\t%s\t%s" % (i.address,i.mnemonic,i.op_str)

直接运行,就可以得到类似ida中看到的内容:

1
2
3
4
5
6
7
8
9
$ python example1.py
0x400800: jmp 0x40080d
0x400802: pop rbx
0x400803: xor eax, eax
0x400805: xor ecx, ecx
0x400807: xor edx, edx
0x400809: mov al, 0xb
0x40080b: int 0x80
0x40080d: call 0x400802

上面for循环遍历出来的i有如下几个成员:

成员名 描述
id 汇编指令的id
address 代码地址
mnemonic 汇编指令
op_str 操作对象字符串
size 汇编指令的大小
bytes 返回对应汇编指令的机器码
operands 操作对象(后面介绍)

脚本2:operands尝试

operands也包含了很多成员,下面跟着官方文档来尝试操作下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
# -*- coding:utf-8 -*-
from capstone import *
from capstone.x86 import *
cs = Cs(CS_ARCH_X86, CS_MODE_64)
cs.detail = True
code = '\x8B\x87\x76\x98\x00\x00\xeb\x0b\x5b\x31\xc0\x31\xc9\x31\xd2\xb0\x0b\xcd\x80\xe8\xf0\xff\xff\xff\x2f\x62\x69\x6e\x2f\x73\x68'
for insn in cs.disasm(code, 0x1000):
print "0x%x:\t%s\t%s" % (insn.address,insn.mnemonic,insn.op_str)
c = 0
for i in insn.operands:
c+=1
print "\toperands[%d]:"%c
if i.type == X86_OP_REG:
print"\t\tREG=%s"%(insn.reg_name(i.value.reg))#获取寄存器的名称
if i.type == X86_OP_IMM:
print "\t\tIMM=0x%x"%(i.value.imm)#获取立即数
if i.type == X86_OP_MEM:#如[rax+0x10]或[rax+rbx]
if i.mem.base != 0:
print "\t\tREG=%s"%(insn.reg_name(i.mem.base))#获取寄存器名称,即rax
if i.mem.index != 0:
print "\t\tIMM=0x%x"%(i.mem.index)#获取第二个寄存器名称,即rbx
if i.mem.disp != 0:
print "\t\tIMM=0x%x"%(i.mem.disp)#获取偏移量,即0x10

对应的输出:

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
$ python example2.py
0x1000: mov eax, dword ptr [rdi + 0x9876]
operands[1]:
REG=eax
operands[2]:
REG=rdi
IMM=0x9876
0x1006: jmp 0x1013
operands[1]:
IMM=0x1013
0x1008: pop rbx
operands[1]:
REG=rbx
0x1009: xor eax, eax
operands[1]:
REG=eax
operands[2]:
REG=eax
0x100b: xor ecx, ecx
operands[1]:
REG=ecx
operands[2]:
REG=ecx
0x100d: xor edx, edx
operands[1]:
REG=edx
operands[2]:
REG=edx
0x100f: mov al, 0xb
operands[1]:
REG=al
operands[2]:
IMM=0xb
0x1011: int 0x80
operands[1]:
IMM=0x80
0x1013: call 0x1008
operands[1]:
IMM=0x1008

呃。。。大概就先这样吧,后面有遇到需要再补充