# angr vexir 研究
binary translator 也是蠻感興趣的,當我要檢測一個漏洞又沒有編譯器這種情形要怎麼分析呢。
在angr裡面有用到了vexir ,
angr 為了適應不同平台好像把不同指令集架構的轉成ir再去做分析,他用的是Valgrind's 記憶體洩漏分析器開源的 VEX IR.
https://zhuanlan.zhihu.com/p/347706328
https://github.com/angr/pyvex
https://api.angr.io/pyvex
https://api.angr.io/archinfo.html
https://docs.angr.io/advanced-topics/ir
,這樣我就能對不同指令集去做統一的操作了。
這是Pyvex的readme
https://github.com/angr/pyvex/blob/38af62047b8a7785feeee6b5f243ad1dbd7db1f6/README.md
中間的
`\x90\x90\x90\x90\x90`
對應的就是binary 依序就是程式加載位置,與指令集架構等等
```python=
import pyvex
import archinfo
# translate an AMD64 basic block (of nops) at 0x400400 into VEX
irsb = pyvex.lift(b"\x90\x90\x90\x90\x90", 0x400400, archinfo.ArchAMD64())
# pretty-print the basic block
irsb.pp()
# this is the IR Expression of the jump target of the unconditional exit at the end of the basic block
print(irsb.next)
# this is the type of the unconditional exit (i.e., a call, ret, syscall, etc)
print(irsb.jumpkind)
# you can also pretty-print it
irsb.next.pp()
# iterate through each statement and print all the statements
for stmt in irsb.statements:
stmt.pp()
# pretty-print the IR expression representing the data, and the *type* of that IR expression written by every store statement
import pyvex
for stmt in irsb.statements:
if isinstance(stmt, pyvex.IRStmt.Store):
print("Data:", end="")
stmt.data.pp()
print("")
print("Type:", end="")
print(stmt.data.result_type)
print("")
# pretty-print the condition and jump target of every conditional exit from the basic block
for stmt in irsb.statements:
if isinstance(stmt, pyvex.IRStmt.Exit):
print("Condition:", end="")
stmt.guard.pp()
print("")
print("Target:", end="")
stmt.dst.pp()
print("")
# these are the types of every temp in the IRSB
print(irsb.tyenv.types)
# here is one way to get the type of temp 0
print(irsb.tyenv.types[0])
```
有了這些我們就可以來開始分析我們得程式碼了,就以我在compiler分析的經驗,我大概會想看一個有沒有control-flow-graph 可以使用,再來就是program slcing等等,在網路找了一會資料太少,我們來補充一下這塊。
以github 這兩個issue都沒人回,他們的程式大概都不能動,可能是版本的問題,大致上改了一些東西與換上新的fucntion name
https://github.com/angr/angr/issues/1361
```c=
// compile with: gcc -O0 -o test test.c
#include <iostream>
#include <stdio.h>
using namespace std;
// int *foo(){
// return (int*)malloc(10);
// }
int main (){
int t= 1222;
int p= 123;
// int c = p-t;
// int d = c-t;
int *z = (int*)malloc(10);
z[0]=1;
// z[1]=2;
// z[2]=3;
// z[3]=4;
cout << p << endl;
cout << t << endl;
z[1]=2;
cout << z[0] << endl;
cout << z[1] << endl;
// cout << z[2] << endl;
// cout << z[3] << endl;
return 0;
}
```
這是修改後可以探測的並進行找到可能相依的程式碼片段的python 腳本
```python=
# An unconstrained state occurs when there are too many
# possible branches from a single instruction. This occurs, among other ways,
# when the instruction pointer (on x86, eip) is completely symbolic, meaning
# that user input can control the address of code the computer executes.
# For example, imagine the following pseudo assembly:
#
# mov user_input, eax
# jmp eax
#
# The value of what the user entered dictates the next instruction. This
# is an unconstrained state. It wouldn't usually make sense for the execution
# engine to continue. (Where should the program jump to if eax could be
# anything?) Normally, when Angr encounters an unconstrained state, it throws
# it out. In our case, we want to exploit the unconstrained state to jump to
# a location of our choosing. We will get to how to disable Angr's default
# behavior later.
#
# This challenge represents a classic stack-based buffer overflow attack to
# overwrite the return address and jump to a function that prints "Good Job."
# Our strategy for solving the challenge is as follows:
# 1. Initialize the simulation and ask Angr to record unconstrained states.
# 2. Step through the simulation until we have found a state where eip is
# symbolic.
# 3. Constrain eip to equal the address of the "print_good" function.
import pyvex
import angr
import claripy
from angr import sim_options as so
from angrutils import plot_cfg
import sys
def main(argv):
path_to_binary = "/home/angr/angr-dev/test/a.out"
project = angr.Project(path_to_binary, auto_load_libs=False , use_sim_procedures=True,default_analysis_mode='symbolic')
print (type(project.entry))
print (hex(project.entry))
bb = project.factory.block(project.entry)
print (type(bb.capstone))
print (type(bb.vex))
print(bb.vex.next)
for stmt in bb.vex.statements:
print(stmt.pp())
print(bb.vex)
print(bb.pp)
# print(bb.vex._exit_statements)
# print(bb.vex.jumpkind)
# print(bb.vex.next)
# print(bb.vex.next)
# print((bb.vex.expressions))
for x in bb.vex.expressions:
print(type(x))
print(bb.vex.pp())
for stmt in bb.vex.statements:
if isinstance(stmt, pyvex.IRStmt.Store):
print("Data:", end="")
stmt.data.pp()
print("")
print("Type:", end="")
print(stmt.data)
print(stmt.data.result_type)
print(stmt.data.__hash__)
print(type(stmt.data))
# print(pyvex.IRExpr.RdTmp.tmp(stmt.data))
# a = stmt.tmp
# b = pyvex.IRExpr.RdTmp.get_instance(stmt.data)
# print(a)
# print(b)
print("")
for stmt in bb.vex.statements:
if isinstance(stmt, pyvex.IRStmt.Exit):
print("Condition:", end="")
stmt.guard.pp()
print("")
print("Target:", end="")
stmt.dst.pp()
print("")
print(bb.pp())
# print(bb.vex._pp_str)
# Make a symbolic input that has a decent size to trigger overflow
# (!)
cfg = project.analyses.CFGFast()
# cfg.normalize()
print("This is the graph:", cfg.graph)
# print("It has %d nodes and %d edges" % (len(cfg.graph.nodes()), len(cfg.graph.edges()))
for func_node in cfg.functions.values():
if func_node.name.startswith("__"):
continue
else:
for block in func_node.blocks:
block.pp()
print("-----")
dict(project.kb.functions.items())
idfer = project.analyses.Identifier()
for funcInfo in idfer.func_info:
print(hex(funcInfo.addr), funcInfo.name)
cfg = project.analyses.CFGEmulated(keep_state=True,
state_add_options=angr.sim_options.refs,
context_sensitivity_level=2)
cdg = project.analyses.CDG(cfg)
ddg = project.analyses.DDG(cfg)
main = project.loader.main_object.get_symbol("main")
# main_func = cfg.kb.functions[main.rebased_addr]
# print(ain)
target_func = cfg.kb.functions.function(name="main")
print(target_func)
# print(main_func[0])
target_node = cfg.get_any_node(0x40119a)
target_stmt = cfg.get_any_node(0x40119b)
bs = project.analyses.BackwardSlice(cfg, cdg=cdg, ddg=ddg, targets=[ (target_node, target_stmt) ],control_flow_slice=True)
anno_cfg = bs.annotated_cfg()
print(bs)
# print()
# print(anno_cfg.dbg_print_irsb(0x40119b))
# print(anno_cfg.dbg_print_irsb(0x40121c))
print(anno_cfg.dbg_repr())
# print(anno_cfg.get_run(0x40119b))
# print(anno_cfg.__getstate__())
initial_state = project.factory.blank_state(
addr=0x40119a,
add_options = { angr.options.SYMBOL_FILL_UNCONSTRAINED_MEMORY,
angr.options.SYMBOL_FILL_UNCONSTRAINED_REGISTERS}
)
simgr = project.factory.simgr(initial_state)
simgr.use_technique(angr.exploration_techniques.slicecutor.Slicecutor(anno_cfg))
simgr.run()
plot_cfg(cfg, "ais3_cfg",format="dot", asminst=True, remove_imports=True, remove_path_terminator=True)
if len(simgr.stashes['found']) == 0:
print("Could not find target.")
else:
print("Could not find target.")
# print("--------")
# print(bs._construct_default(0x40121c))
if __name__ == '__main__':
main(sys.argv)
```
就以上述程式我們可以透過如果想直接用angr轉成binary 的資料再丟給vexir 進行轉換這部分該如何轉換呢。
# binary to vex ir
該篇文章有更細緻的追蹤近anrg,這邊就不贅述
https://zhuanlan.zhihu.com/p/347706328
當我完成編譯應該會有下列程式碼可以取得入口點的vex 也就是objdump asm
```pyhton
path_to_binary = "/home/angr/angr-dev/test/a.out"
project = angr.Project(path_to_binary, auto_load_libs=False , use_sim_procedures=True,default_analysis_mode='symbolic')
print (type(project.entry))
print (hex(project.entry))
bb = project.factory.block(project.entry)
print()
print (type(bb.capstone))
print (type(bb.vex))
print(bb.vex.next)
for stmt in bb.vex.statements:
print(stmt.pp())
print(bb.pp())
print(bb.vex)
print(bb.vex._exit_statements)
print(bb.vex.jumpkind)
```
` bb = project.factory.block(project.entry)`
意味者獲取該obj檔案的 起始點,project.entry也有可能是一個位置
```python=
for stmt in bb.vex.statements:
print(stmt.pp())
print(bb.pp())
```
多虧angr我就可以直接從bianry 去取得 該basic block 的stmt
```python
print(bb.vex)
```
也可以取得較為漂亮的輸出,這會輸出這個basic block 相對應的程式碼vex ir
```bash
IRSB {
t0:Ity_I32 t1:Ity_I32 t2:Ity_I32 t3:Ity_I64 t4:Ity_I64 t5:Ity_I64 t6:Ity_I64 t7:Ity_I64 t8:Ity_I64 t9:Ity_I64 t10:Ity_I64 t11:Ity_I64 t12:Ity_I64 t13:Ity_I64 t14:Ity_I64 t15:Ity_I32 t16:Ity_I64 t17:Ity_I64 t18:Ity_I64 t19:Ity_I64 t20:Ity_I32 t21:Ity_I64 t22:Ity_I32 t23:Ity_I64 t24:Ity_I64 t25:Ity_I64 t26:Ity_I64 t27:Ity_I64 t28:Ity_I64 t29:Ity_I64 t30:Ity_I64 t31:Ity_I64 t32:Ity_I64 t33:Ity_I64 t34:Ity_I64 t35:Ity_I64 t36:Ity_I64
00 | ------ IMark(0x401090, 4, 0) ------
01 | ------ IMark(0x401094, 2, 0) ------
02 | PUT(rbp) = 0x0000000000000000
03 | ------ IMark(0x401096, 3, 0) ------
04 | t26 = GET:I64(rdx)
05 | PUT(r9) = t26
06 | PUT(rip) = 0x0000000000401099
07 | ------ IMark(0x401099, 1, 0) ------
08 | t4 = GET:I64(rsp)
09 | t3 = LDle:I64(t4)
10 | t27 = Add64(t4,0x0000000000000008)
11 | PUT(rsi) = t3
12 | ------ IMark(0x40109a, 3, 0) ------
13 | PUT(rdx) = t27
14 | ------ IMark(0x40109d, 4, 0) ------
15 | t5 = And64(t27,0xfffffffffffffff0)
16 | PUT(cc_op) = 0x0000000000000014
17 | PUT(cc_dep1) = t5
18 | PUT(cc_dep2) = 0x0000000000000000
19 | PUT(rip) = 0x00000000004010a1
20 | ------ IMark(0x4010a1, 1, 0) ------
21 | t8 = GET:I64(rax)
22 | t29 = Sub64(t5,0x0000000000000008)
23 | PUT(rsp) = t29
24 | STle(t29) = t8
25 | PUT(rip) = 0x00000000004010a2
26 | ------ IMark(0x4010a2, 1, 0) ------
27 | t31 = Sub64(t29,0x0000000000000008)
28 | PUT(rsp) = t31
29 | STle(t31) = t29
30 | ------ IMark(0x4010a3, 7, 0) ------
31 | PUT(r8) = 0x0000000000401350
32 | ------ IMark(0x4010aa, 7, 0) ------
33 | PUT(rcx) = 0x00000000004012e0
34 | ------ IMark(0x4010b1, 7, 0) ------
35 | PUT(rdi) = 0x000000000040119a
36 | PUT(rip) = 0x00000000004010b8
37 | ------ IMark(0x4010b8, 6, 0) ------
38 | t17 = LDle:I64(0x0000000000403fe0)
39 | t33 = Sub64(t31,0x0000000000000008)
40 | PUT(rsp) = t33
41 | STle(t33) = 0x00000000004010be
42 | t35 = Sub64(t33,0x0000000000000080)
43 | ====== AbiHint(0xt35, 128, t17) ======
NEXT: PUT(rip) = t17; Ijk_Call
}
```
```python=
print(bb.vex.pp())
```
```bash=
0x401090: endbr64
0x401094: xor ebp, ebp
0x401096: mov r9, rdx
0x401099: pop rsi
0x40109a: mov rdx, rsp
0x40109d: and rsp, 0xfffffffffffffff0
0x4010a1: push rax
0x4010a2: push rsp
0x4010a3: lea r8, [rip + 0x2a6]
0x4010aa: lea rcx, [rip + 0x22f]
0x4010b1: lea rdi, [rip + 0xe2]
0x4010b8: call qword ptr [rip + 0x2f22]
None
```
這邊其實就可以很容易看到
------ IMark(0x4010b8, 6, 0) ------
對應到
0x4010b8
```python=
for stmt in bb.vex.statements:
if isinstance(stmt, pyvex.IRStmt.LLSC):
print("Data:", end="")
stmt.data.pp()
print("")
print("Type:", end="")
print(stmt.data)
print(stmt.data.result_type)
print(stmt.data.__hash__)
print(type(stmt.data))
```
```bahs
<class 'pyvex.expr.Const'>
<class 'pyvex.expr.Get'>
<class 'pyvex.expr.RdTmp'>
<class 'pyvex.expr.Const'>
<class 'pyvex.expr.Get'>
<class 'pyvex.expr.Load'>
<class 'pyvex.expr.RdTmp'>
<class 'pyvex.expr.Binop'>
<class 'pyvex.expr.RdTmp'>
<class 'pyvex.expr.Const'>
<class 'pyvex.expr.RdTmp'>
<class 'pyvex.expr.RdTmp'>
<class 'pyvex.expr.Binop'>
<class 'pyvex.expr.RdTmp'>
<class 'pyvex.expr.Const'>
<class 'pyvex.expr.Const'>
<class 'pyvex.expr.RdTmp'>
<class 'pyvex.expr.Const'>
<class 'pyvex.expr.Const'>
<class 'pyvex.expr.Get'>
<class 'pyvex.expr.Binop'>
<class 'pyvex.expr.RdTmp'>
<class 'pyvex.expr.Const'>
<class 'pyvex.expr.RdTmp'>
<class 'pyvex.expr.RdTmp'>
<class 'pyvex.expr.RdTmp'>
<class 'pyvex.expr.Const'>
<class 'pyvex.expr.Binop'>
<class 'pyvex.expr.RdTmp'>
<class 'pyvex.expr.Const'>
<class 'pyvex.expr.RdTmp'>
<class 'pyvex.expr.RdTmp'>
<class 'pyvex.expr.RdTmp'>
<class 'pyvex.expr.Const'>
<class 'pyvex.expr.Const'>
<class 'pyvex.expr.Const'>
<class 'pyvex.expr.Const'>
<class 'pyvex.expr.Load'>
<class 'pyvex.expr.Const'>
<class 'pyvex.expr.Binop'>
<class 'pyvex.expr.RdTmp'>
<class 'pyvex.expr.Const'>
<class 'pyvex.expr.RdTmp'>
<class 'pyvex.expr.RdTmp'>
<class 'pyvex.expr.Const'>
<class 'pyvex.expr.Binop'>
<class 'pyvex.expr.RdTmp'>
<class 'pyvex.expr.Const'>
<class 'pyvex.expr.RdTmp'>
<class 'pyvex.expr.RdTmp'>
<class 'pyvex.expr.RdTmp'>
```
包括要取得每個 vex ir 的 各種不同型態也可以 各種不同的可以在進一步往https://github.com/angr/pyvex/tree/master/pyvex
進行分析這些stmt都是可以展開的
那麼在這些vex ir 還可以怎麼分析要過濾呢
於上一個腳本可以看到if isinstance(stmt, pyvex.IRStmt.Store):我們在對stmt進行過濾
```pyhton
for stmt in bb.vex.statements:
if isinstance(stmt, pyvex.IRStmt.Store):
print("Data:", end="")
stmt.data.pp()
print("")
print("Type:", end="")
print(stmt.data)
print(stmt.data.result_type)
print(stmt.data.__hash__)
print(type(stmt.data))
```
```bash=
Data:t8
Type:t8
<bound method RdTmp.result_type of <pyvex.expr.RdTmp object at 0x7fd67861baf0>>
<bound method VEXObject.__hash__ of <pyvex.expr.RdTmp object at 0x7fd67861baf0>>
<class 'pyvex.expr.RdTmp'>
Data:t29
Type:t29
<bound method RdTmp.result_type of <pyvex.expr.RdTmp object at 0x7fd67861bf40>>
<bound method VEXObject.__hash__ of <pyvex.expr.RdTmp object at 0x7fd67861bf40>>
<class 'pyvex.expr.RdTmp'>
Data:0x00000000004010be
Type:0x00000000004010be
<bound method Const.result_type of <pyvex.expr.Const object at 0x7fd6731eaa60>>
<bound method VEXObject.__hash__ of <pyvex.expr.Const object at 0x7fd6731eaa60>>
<class 'pyvex.expr.Const'>
```
依序我們還可以過濾這些stmt的型態分析時去取得個別ir的register
左子樹,右子樹等等
剛剛針對basic bloc 我們只是帶過
```pyhton
cfg = project.analyses.CFGFast()
# cfg.normalize()
print("This is the graph:", cfg.graph)
print("It has %d nodes and %d edges" % (len(cfg.graph.nodes()), len(cfg.graph.edges()))
for func_node in cfg.functions.values():
if func_node.name.startswith("__"):
continue
else:
for block in func_node.blocks:
block.pp()
print("-----")
```
這一行是展開任意obj所有的basic block
`cfg = project.analyses.CFGFast()`
```bash=
WARNING | 2022-05-14 00:48:35,369 | angr.analyses.cfg.cfg_base | _is_region_extremely_sparse: The given region 0x401358-0x401365 is not a continuous memory region in the memory space. Only the first 13 bytes (0x401358-0x401364) are processed.
This is the graph:
0x401000: endbr64
0x401004: sub rsp, 8
0x401008: mov rax, qword ptr [rip + 0x2fd9]
0x40100f: test rax, rax
0x401012: je 0x401016
-----
0x401016: add rsp, 8
0x40101a: ret
-----
0x401014: call rax
-----
0x401020: push qword ptr [rip + 0x2f6a]
0x401026: jmp qword ptr [rip + 0x2f6c]
-----
0x40102c: nop dword ptr [rax]
-----
0x401040: jmp qword ptr [rip + 0x2f62]
-----
0x401050: jmp qword ptr [rip + 0x2f5a]
-----
0x401060: jmp qword ptr [rip + 0x2f52]
-----
0x401070: jmp qword ptr [rip + 0x2f4a]
-----
0x401090: endbr64
0x401094: xor ebp, ebp
0x401096: mov r9, rdx
0x401099: pop rsi
0x40109a: mov rdx, rsp
0x40109d: and rsp, 0xfffffffffffffff0
0x4010a1: push rax
0x4010a2: push rsp
0x4010a3: lea r8, [rip + 0x2a6]
0x4010aa: lea rcx, [rip + 0x22f]
0x4010b1: lea rdi, [rip + 0xe2]
0x4010b8: call qword ptr [rip + 0x2f22]
-----
0x4010be: hlt
-----
0x4010bf: nop
-----
0x4010c0: lea rdi, [rip + 0x2f49]
0x4010c7: push rbp
0x4010c8: lea rax, [rip + 0x2f41]
0x4010cf: cmp rax, rdi
0x4010d2: mov rbp, rsp
0x4010d5: je 0x4010f0
-----
0x4010f0: pop rbp
0x4010f1: ret
-----
0x4010d7: mov rax, qword ptr [rip + 0x2efa]
0x4010de: test rax, rax
0x4010e1: je 0x4010f0
-----
0x4010e3: pop rbp
0x4010e4: jmp rax
-----
0x4010e6: nop word ptr cs:[rax + rax]
-----
0x4010f2: nop word ptr cs:[rax + rax]
0x4010fd: nop dword ptr [rax]
-----
0x401100: lea rdi, [rip + 0x2f09]
0x401107: lea rsi, [rip + 0x2f02]
0x40110e: push rbp
0x40110f: sub rsi, rdi
0x401112: mov rbp, rsp
0x401115: sar rsi, 3
0x401119: mov rax, rsi
0x40111c: shr rax, 0x3f
0x401120: add rsi, rax
0x401123: sar rsi, 1
0x401126: je 0x401140
-----
0x401140: pop rbp
0x401141: ret
-----
0x401128: mov rax, qword ptr [rip + 0x2ec1]
0x40112f: test rax, rax
0x401132: je 0x401140
-----
0x401134: pop rbp
0x401135: jmp rax
-----
0x401137: nop word ptr [rax + rax]
-----
0x401142: nop word ptr cs:[rax + rax]
0x40114d: nop dword ptr [rax]
-----
0x401181: nop dword ptr [rax]
-----
0x40118a: nop word ptr [rax + rax]
-----
0x401190: push rbp
0x401191: mov rbp, rsp
0x401194: pop rbp
0x401195: jmp 0x401100
-----
0x40119a: push rbp
0x40119b: mov rbp, rsp
0x40119e: sub rsp, 0x10
0x4011a2: mov dword ptr [rbp - 0x10], 0x4c6
0x4011a9: mov dword ptr [rbp - 0xc], 0x7b
0x4011b0: mov edi, 0xa
0x4011b5: call 0x401050
-----
0x4011ba: mov qword ptr [rbp - 8], rax
0x4011be: mov rax, qword ptr [rbp - 8]
0x4011c2: mov dword ptr [rax], 1
0x4011c8: mov eax, dword ptr [rbp - 0xc]
0x4011cb: mov esi, eax
0x4011cd: lea rdi, [rip + 0x2e6c]
0x4011d4: call 0x401070
-----
0x4011d9: mov rdx, rax
0x4011dc: mov rax, qword ptr [rip + 0x2ded]
0x4011e3: mov rsi, rax
0x4011e6: mov rdi, rdx
0x4011e9: call 0x401040
-----
0x4011ee: mov eax, dword ptr [rbp - 0x10]
0x4011f1: mov esi, eax
0x4011f3: lea rdi, [rip + 0x2e46]
0x4011fa: call 0x401070
-----
0x4011ff: mov rdx, rax
0x401202: mov rax, qword ptr [rip + 0x2dc7]
0x401209: mov rsi, rax
0x40120c: mov rdi, rdx
0x40120f: call 0x401040
-----
0x401214: mov rax, qword ptr [rbp - 8]
0x401218: add rax, 4
0x40121c: mov dword ptr [rax], 2
0x401222: mov rax, qword ptr [rbp - 8]
0x401226: mov eax, dword ptr [rax]
0x401228: mov esi, eax
0x40122a: lea rdi, [rip + 0x2e0f]
0x401231: call 0x401070
-----
0x401236: mov rdx, rax
0x401239: mov rax, qword ptr [rip + 0x2d90]
0x401240: mov rsi, rax
0x401243: mov rdi, rdx
0x401246: call 0x401040
-----
0x40124b: mov rax, qword ptr [rbp - 8]
0x40124f: add rax, 4
0x401253: mov eax, dword ptr [rax]
0x401255: mov esi, eax
0x401257: lea rdi, [rip + 0x2de2]
0x40125e: call 0x401070
-----
0x401263: mov rdx, rax
0x401266: mov rax, qword ptr [rip + 0x2d63]
0x40126d: mov rsi, rax
0x401270: mov rdi, rdx
0x401273: call 0x401040
-----
0x401278: mov eax, 0
0x40127d: leave
0x40127e: ret
-----
0x40127f: push rbp
0x401280: mov rbp, rsp
0x401283: sub rsp, 0x10
0x401287: mov dword ptr [rbp - 4], edi
0x40128a: mov dword ptr [rbp - 8], esi
0x40128d: cmp dword ptr [rbp - 4], 1
0x401291: jne 0x4012c5
-----
0x401293: cmp dword ptr [rbp - 8], 0xffff
0x40129a: jne 0x4012c5
-----
0x4012c5: nop
0x4012c6: leave
0x4012c7: ret
-----
0x40129c: lea rdi, [rip + 0x2eae]
0x4012a3: call 0x401060
-----
0x4012a8: lea rdx, [rip + 0x2d59]
0x4012af: lea rsi, [rip + 0x2e9b]
0x4012b6: mov rax, qword ptr [rip + 0x2d3b]
0x4012bd: mov rdi, rax
0x4012c0: call 0x401030
-----
0x4012c8: push rbp
0x4012c9: mov rbp, rsp
0x4012cc: mov esi, 0xffff
0x4012d1: mov edi, 1
0x4012d6: call 0x40127f
-----
0x4012db: pop rbp
0x4012dc: ret
-----
0x4012dd: nop dword ptr [rax]
-----
0x401345: nop word ptr cs:[rax + rax]
-----
0x401358: endbr64
0x40135c: sub rsp, 8
0x401360: add rsp, 8
0x401364: ret
-----
-----
-----
-----
-----
-----
-----
```
可以看到被拆成斷斷續續的,真實的vex ir 我們可以再透過
https://ble55ing.github.io/2019/06/18/angr-cfg/
將我們的control-flow-graph再轉為dot
由於我的環境是在docker,再裝graphiz 蠻麻煩,退出又要重裝了
```
vim /home/angr/.virtualenvs/angr/lib/python3.8/site-packages/pydot.py
```
裝完環境後我們直接修改
![](https://i.imgur.com/yF54jNx.png)
```
print(tmp_dir+tmp_name)
```
在我們的分析器加上這個
```python=
plot_cfg(cfg, "ais3_cfg",format="dot", asminst=True, remove_imports=True, remove_path_terminator=True)
```
![](https://i.imgur.com/ASwEWBQ.png)
我們直接倒出dot
![](https://i.imgur.com/tnTI7st.png)
```graphviz
digraph "" {
rankdir=TB;
newrank=true;
labeljust=l;
3 [shape=Mrecord, fontname=monospace, fontsize=8.0, label=<{ <TABLE BORDER="0" CELLPADDING="1" ALIGN="LEFT"><TR><TD >0x401000</TD><TD >(0x401000)</TD><TD ><B>_init</B></TD><TD></TD></TR></TABLE>|<TABLE BORDER="0" CELLPADDING="1" ALIGN="LEFT"><TR><TD ALIGN="LEFT">0x00401000: </TD><TD ALIGN="LEFT">endbr64</TD><TD></TD><TD></TD></TR><TR><TD ALIGN="LEFT">0x00401004: </TD><TD ALIGN="LEFT">sub</TD><TD ALIGN="LEFT">rsp, 8</TD><TD></TD></TR><TR><TD ALIGN="LEFT">0x00401008: </TD><TD ALIGN="LEFT">mov</TD><TD ALIGN="LEFT">rax, qword ptr [rip + 0x2fd9]</TD><TD></TD></TR><TR><TD ALIGN="LEFT">0x0040100f: </TD><TD ALIGN="LEFT">test</TD><TD ALIGN="LEFT">rax, rax</TD><TD></TD></TR><TR><TD ALIGN="LEFT">0x00401012: </TD><TD ALIGN="LEFT">je</TD><TD ALIGN="LEFT">0x401016</TD><TD></TD></TR></TABLE> }>]
5 [shape=Mrecord, fontname=monospace, fontsize=8.0, label=<{ <TABLE BORDER="0" CELLPADDING="1" ALIGN="LEFT"><TR><TD >0x401014</TD><TD >(0x401000)</TD><TD ><B>_init+0x14</B></TD><TD></TD></TR></TABLE>|<TABLE BORDER="0" CELLPADDING="1" ALIGN="LEFT"><TR><TD ALIGN="LEFT">0x00401014: </TD><TD ALIGN="LEFT">call</TD><TD ALIGN="LEFT">rax</TD><TD></TD></TR></TABLE> }>]
4 [shape=Mrecord, fontname=monospace, fontsize=8.0, label=<{ <TABLE BORDER="0" CELLPADDING="1" ALIGN="LEFT"><TR><TD >0x401016</TD><TD >(0x401000)</TD><TD ><B>_init+0x16</B></TD><TD></TD></TR></TABLE>|<TABLE BORDER="0" CELLPADDING="1" ALIGN="LEFT"><TR><TD ALIGN="LEFT">0x00401016: </TD><TD ALIGN="LEFT">add</TD><TD ALIGN="LEFT">rsp, 8</TD><TD></TD></TR><TR><TD ALIGN="LEFT">0x0040101a: </TD><TD ALIGN="LEFT">ret</TD><TD></TD><TD></TD></TR></TABLE> }>]
38 [shape=Mrecord, fontname=monospace, fontsize=8.0, label=<{ <TABLE BORDER="0" CELLPADDING="1" ALIGN="LEFT"><TR><TD >0x401030</TD><TD >(0x401030)</TD><TD></TD><TD></TD></TR></TABLE>|<TABLE BORDER="0" CELLPADDING="1" ALIGN="LEFT"><TR><TD ALIGN="LEFT">0x00401030: </TD><TD ALIGN="LEFT">jmp</TD><TD ALIGN="LEFT">qword ptr [rip + 0x2f6a]</TD><TD></TD></TR></TABLE> }>]
53 [shape=Mrecord, fontname=monospace, fontsize=8.0, label=<{ <TABLE BORDER="0" CELLPADDING="1" ALIGN="LEFT"><TR><TD >0x401040</TD><TD >(0x401040)</TD><TD></TD><TD></TD></TR></TABLE>|<TABLE BORDER="0" CELLPADDING="1" ALIGN="LEFT"><TR><TD ALIGN="LEFT">0x00401040: </TD><TD ALIGN="LEFT">jmp</TD><TD ALIGN="LEFT">qword ptr [rip + 0x2f62]</TD><TD></TD></TR></TABLE> }>]
28 [shape=Mrecord, fontname=monospace, fontsize=8.0, label=<{ <TABLE BORDER="0" CELLPADDING="1" ALIGN="LEFT"><TR><TD >0x401040</TD><TD >(0x401040)</TD><TD></TD><TD></TD></TR></TABLE>|<TABLE BORDER="0" CELLPADDING="1" ALIGN="LEFT"><TR><TD ALIGN="LEFT">0x00401040: </TD><TD ALIGN="LEFT">jmp</TD><TD ALIGN="LEFT">qword ptr [rip + 0x2f62]</TD><TD></TD></TR></TABLE> }>]
41 [shape=Mrecord, fontname=monospace, fontsize=8.0, label=<{ <TABLE BORDER="0" CELLPADDING="1" ALIGN="LEFT"><TR><TD >0x401040</TD><TD >(0x401040)</TD><TD></TD><TD></TD></TR></TABLE>|<TABLE BORDER="0" CELLPADDING="1" ALIGN="LEFT"><TR><TD ALIGN="LEFT">0x00401040: </TD><TD ALIGN="LEFT">jmp</TD><TD ALIGN="LEFT">qword ptr [rip + 0x2f62]</TD><TD></TD></TR></TABLE> }>]
47 [shape=Mrecord, fontname=monospace, fontsize=8.0, label=<{ <TABLE BORDER="0" CELLPADDING="1" ALIGN="LEFT"><TR><TD >0x401040</TD><TD >(0x401040)</TD><TD></TD><TD></TD></TR></TABLE>|<TABLE BORDER="0" CELLPADDING="1" ALIGN="LEFT"><TR><TD ALIGN="LEFT">0x00401040: </TD><TD ALIGN="LEFT">jmp</TD><TD ALIGN="LEFT">qword ptr [rip + 0x2f62]</TD><TD></TD></TR></TABLE> }>]
13 [shape=Mrecord, fontname=monospace, fontsize=8.0, label=<{ <TABLE BORDER="0" CELLPADDING="1" ALIGN="LEFT"><TR><TD >0x401050</TD><TD >(0x401050)</TD><TD></TD><TD></TD></TR></TABLE>|<TABLE BORDER="0" CELLPADDING="1" ALIGN="LEFT"><TR><TD ALIGN="LEFT">0x00401050: </TD><TD ALIGN="LEFT">jmp</TD><TD ALIGN="LEFT">qword ptr [rip + 0x2f5a]</TD><TD></TD></TR></TABLE> }>]
32 [shape=Mrecord, fontname=monospace, fontsize=8.0, label=<{ <TABLE BORDER="0" CELLPADDING="1" ALIGN="LEFT"><TR><TD >0x401060</TD><TD >(0x401060)</TD><TD></TD><TD></TD></TR></TABLE>|<TABLE BORDER="0" CELLPADDING="1" ALIGN="LEFT"><TR><TD ALIGN="LEFT">0x00401060: </TD><TD ALIGN="LEFT">jmp</TD><TD ALIGN="LEFT">qword ptr [rip + 0x2f52]</TD><TD></TD></TR></TABLE> }>]
50 [shape=Mrecord, fontname=monospace, fontsize=8.0, label=<{ <TABLE BORDER="0" CELLPADDING="1" ALIGN="LEFT"><TR><TD >0x401070</TD><TD >(0x401070)</TD><TD></TD><TD></TD></TR></TABLE>|<TABLE BORDER="0" CELLPADDING="1" ALIGN="LEFT"><TR><TD ALIGN="LEFT">0x00401070: </TD><TD ALIGN="LEFT">jmp</TD><TD ALIGN="LEFT">qword ptr [rip + 0x2f4a]</TD><TD></TD></TR></TABLE> }>]
44 [shape=Mrecord, fontname=monospace, fontsize=8.0, label=<{ <TABLE BORDER="0" CELLPADDING="1" ALIGN="LEFT"><TR><TD >0x401070</TD><TD >(0x401070)</TD><TD></TD><TD></TD></TR></TABLE>|<TABLE BORDER="0" CELLPADDING="1" ALIGN="LEFT"><TR><TD ALIGN="LEFT">0x00401070: </TD><TD ALIGN="LEFT">jmp</TD><TD ALIGN="LEFT">qword ptr [rip + 0x2f4a]</TD><TD></TD></TR></TABLE> }>]
35 [shape=Mrecord, fontname=monospace, fontsize=8.0, label=<{ <TABLE BORDER="0" CELLPADDING="1" ALIGN="LEFT"><TR><TD >0x401070</TD><TD >(0x401070)</TD><TD></TD><TD></TD></TR></TABLE>|<TABLE BORDER="0" CELLPADDING="1" ALIGN="LEFT"><TR><TD ALIGN="LEFT">0x00401070: </TD><TD ALIGN="LEFT">jmp</TD><TD ALIGN="LEFT">qword ptr [rip + 0x2f4a]</TD><TD></TD></TR></TABLE> }>]
21 [shape=Mrecord, fontname=monospace, fontsize=8.0, label=<{ <TABLE BORDER="0" CELLPADDING="1" ALIGN="LEFT"><TR><TD >0x401070</TD><TD >(0x401070)</TD><TD></TD><TD></TD></TR></TABLE>|<TABLE BORDER="0" CELLPADDING="1" ALIGN="LEFT"><TR><TD ALIGN="LEFT">0x00401070: </TD><TD ALIGN="LEFT">jmp</TD><TD ALIGN="LEFT">qword ptr [rip + 0x2f4a]</TD><TD></TD></TR></TABLE> }>]
0 [shape=Mrecord, fontname=monospace, fontsize=8.0, label=<{ <TABLE BORDER="0" CELLPADDING="1" ALIGN="LEFT"><TR><TD >0x401090</TD><TD >(0x401090)</TD><TD ><B>_start</B></TD><TD></TD></TR></TABLE>|<TABLE BORDER="0" CELLPADDING="1" ALIGN="LEFT"><TR><TD ALIGN="LEFT">0x00401090: </TD><TD ALIGN="LEFT">endbr64</TD><TD></TD><TD></TD></TR><TR><TD ALIGN="LEFT">0x00401094: </TD><TD ALIGN="LEFT">xor</TD><TD ALIGN="LEFT">ebp, ebp</TD><TD></TD></TR><TR><TD ALIGN="LEFT">0x00401096: </TD><TD ALIGN="LEFT">mov</TD><TD ALIGN="LEFT">r9, rdx</TD><TD></TD></TR><TR><TD ALIGN="LEFT">0x00401099: </TD><TD ALIGN="LEFT">pop</TD><TD ALIGN="LEFT">rsi</TD><TD></TD></TR><TR><TD ALIGN="LEFT">0x0040109a: </TD><TD ALIGN="LEFT">mov</TD><TD ALIGN="LEFT">rdx, rsp</TD><TD></TD></TR><TR><TD ALIGN="LEFT">0x0040109d: </TD><TD ALIGN="LEFT">and</TD><TD ALIGN="LEFT">rsp, 0xfffffffffffffff0</TD><TD></TD></TR><TR><TD ALIGN="LEFT">0x004010a1: </TD><TD ALIGN="LEFT">push</TD><TD ALIGN="LEFT">rax</TD><TD></TD></TR><TR><TD ALIGN="LEFT">0x004010a2: </TD><TD ALIGN="LEFT">push</TD><TD ALIGN="LEFT">rsp</TD><TD></TD></TR><TR><TD ALIGN="LEFT">0x004010a3: </TD><TD ALIGN="LEFT">lea</TD><TD ALIGN="LEFT">r8, [rip + 0x2a6]</TD><TD></TD></TR><TR><TD ALIGN="LEFT">0x004010aa: </TD><TD ALIGN="LEFT">lea</TD><TD ALIGN="LEFT">rcx, [rip + 0x22f]</TD><TD></TD></TR><TR><TD ALIGN="LEFT">0x004010b1: </TD><TD ALIGN="LEFT">lea</TD><TD ALIGN="LEFT">rdi, [rip + 0xe2]</TD><TD></TD></TR><TR><TD ALIGN="LEFT">0x004010b8: </TD><TD ALIGN="LEFT">call</TD><TD ALIGN="LEFT">qword ptr [rip + 0x2f22]</TD><TD></TD></TR></TABLE> }>]
12 [shape=Mrecord, fontname=monospace, fontsize=8.0, label=<{ <TABLE BORDER="0" CELLPADDING="1" ALIGN="LEFT"><TR><TD >0x401100</TD><TD >(0x401100)</TD><TD ><B>register_tm_clones</B></TD><TD></TD></TR></TABLE>|<TABLE BORDER="0" CELLPADDING="1" ALIGN="LEFT"><TR><TD ALIGN="LEFT">0x00401100: </TD><TD ALIGN="LEFT">lea</TD><TD ALIGN="LEFT">rdi, [rip + 0x2f09]</TD><TD></TD></TR><TR><TD ALIGN="LEFT">0x00401107: </TD><TD ALIGN="LEFT">lea</TD><TD ALIGN="LEFT">rsi, [rip + 0x2f02]</TD><TD></TD></TR><TR><TD ALIGN="LEFT">0x0040110e: </TD><TD ALIGN="LEFT">push</TD><TD ALIGN="LEFT">rbp</TD><TD></TD></TR><TR><TD ALIGN="LEFT">0x0040110f: </TD><TD ALIGN="LEFT">sub</TD><TD ALIGN="LEFT">rsi, rdi</TD><TD></TD></TR><TR><TD ALIGN="LEFT">0x00401112: </TD><TD ALIGN="LEFT">mov</TD><TD ALIGN="LEFT">rbp, rsp</TD><TD></TD></TR><TR><TD ALIGN="LEFT">0x00401115: </TD><TD ALIGN="LEFT">sar</TD><TD ALIGN="LEFT">rsi, 3</TD><TD></TD></TR><TR><TD ALIGN="LEFT">0x00401119: </TD><TD ALIGN="LEFT">mov</TD><TD ALIGN="LEFT">rax, rsi</TD><TD></TD></TR><TR><TD ALIGN="LEFT">0x0040111c: </TD><TD ALIGN="LEFT">shr</TD><TD ALIGN="LEFT">rax, 0x3f</TD><TD></TD></TR><TR><TD ALIGN="LEFT">0x00401120: </TD><TD ALIGN="LEFT">add</TD><TD ALIGN="LEFT">rsi, rax</TD><TD></TD></TR><TR><TD ALIGN="LEFT">0x00401123: </TD><TD ALIGN="LEFT">sar</TD><TD ALIGN="LEFT">rsi, 1</TD><TD></TD></TR><TR><TD ALIGN="LEFT">0x00401126: </TD><TD ALIGN="LEFT">je</TD><TD ALIGN="LEFT">0x401140</TD><TD></TD></TR></TABLE> }>]
15 [shape=Mrecord, fontname=monospace, fontsize=8.0, label=<{ <TABLE BORDER="0" CELLPADDING="1" ALIGN="LEFT"><TR><TD >0x401128</TD><TD >(0x401100)</TD><TD ><B>register_tm_clones+0x28</B></TD><TD></TD></TR></TABLE>|<TABLE BORDER="0" CELLPADDING="1" ALIGN="LEFT"><TR><TD ALIGN="LEFT">0x00401128: </TD><TD ALIGN="LEFT">mov</TD><TD ALIGN="LEFT">rax, qword ptr [rip + 0x2ec1]</TD><TD></TD></TR><TR><TD ALIGN="LEFT">0x0040112f: </TD><TD ALIGN="LEFT">test</TD><TD ALIGN="LEFT">rax, rax</TD><TD></TD></TR><TR><TD ALIGN="LEFT">0x00401132: </TD><TD ALIGN="LEFT">je</TD><TD ALIGN="LEFT">0x401140</TD><TD></TD></TR></TABLE> }>]
18 [shape=Mrecord, fontname=monospace, fontsize=8.0, label=<{ <TABLE BORDER="0" CELLPADDING="1" ALIGN="LEFT"><TR><TD >0x401134</TD><TD >(0x401100)</TD><TD ><B>register_tm_clones+0x34</B></TD><TD></TD></TR></TABLE>|<TABLE BORDER="0" CELLPADDING="1" ALIGN="LEFT"><TR><TD ALIGN="LEFT">0x00401134: </TD><TD ALIGN="LEFT">pop</TD><TD ALIGN="LEFT">rbp</TD><TD></TD></TR><TR><TD ALIGN="LEFT">0x00401135: </TD><TD ALIGN="LEFT">jmp</TD><TD ALIGN="LEFT">rax</TD><TD></TD></TR></TABLE> }>]
14 [shape=Mrecord, fontname=monospace, fontsize=8.0, label=<{ <TABLE BORDER="0" CELLPADDING="1" ALIGN="LEFT"><TR><TD >0x401140</TD><TD >(0x401100)</TD><TD ><B>register_tm_clones+0x40</B></TD><TD></TD></TR></TABLE>|<TABLE BORDER="0" CELLPADDING="1" ALIGN="LEFT"><TR><TD ALIGN="LEFT">0x00401140: </TD><TD ALIGN="LEFT">pop</TD><TD ALIGN="LEFT">rbp</TD><TD></TD></TR><TR><TD ALIGN="LEFT">0x00401141: </TD><TD ALIGN="LEFT">ret</TD><TD></TD><TD></TD></TR></TABLE> }>]
10 [shape=Mrecord, fontname=monospace, fontsize=8.0, label=<{ <TABLE BORDER="0" CELLPADDING="1" ALIGN="LEFT"><TR><TD >0x401190</TD><TD >(0x401190)</TD><TD ><B>frame_dummy</B></TD><TD></TD></TR></TABLE>|<TABLE BORDER="0" CELLPADDING="1" ALIGN="LEFT"><TR><TD ALIGN="LEFT">0x00401190: </TD><TD ALIGN="LEFT">push</TD><TD ALIGN="LEFT">rbp</TD><TD></TD></TR><TR><TD ALIGN="LEFT">0x00401191: </TD><TD ALIGN="LEFT">mov</TD><TD ALIGN="LEFT">rbp, rsp</TD><TD></TD></TR><TR><TD ALIGN="LEFT">0x00401194: </TD><TD ALIGN="LEFT">pop</TD><TD ALIGN="LEFT">rbp</TD><TD></TD></TR><TR><TD ALIGN="LEFT">0x00401195: </TD><TD ALIGN="LEFT">jmp</TD><TD ALIGN="LEFT">0x401100</TD><TD></TD></TR></TABLE> }>]
11 [shape=Mrecord, fontname=monospace, fontsize=8.0, label=<{ <TABLE BORDER="0" CELLPADDING="1" ALIGN="LEFT"><TR><TD >0x40119a</TD><TD >(0x40119a)</TD><TD ><B>main</B></TD><TD></TD></TR></TABLE>|<TABLE BORDER="0" CELLPADDING="1" ALIGN="LEFT"><TR><TD ALIGN="LEFT">0x0040119a: </TD><TD ALIGN="LEFT">push</TD><TD ALIGN="LEFT">rbp</TD><TD></TD></TR><TR><TD ALIGN="LEFT">0x0040119b: </TD><TD ALIGN="LEFT">mov</TD><TD ALIGN="LEFT">rbp, rsp</TD><TD></TD></TR><TR><TD ALIGN="LEFT">0x0040119e: </TD><TD ALIGN="LEFT">sub</TD><TD ALIGN="LEFT">rsp, 0x10</TD><TD></TD></TR><TR><TD ALIGN="LEFT">0x004011a2: </TD><TD ALIGN="LEFT">mov</TD><TD ALIGN="LEFT">dword ptr [rbp - 0x10], 0x4c6</TD><TD></TD></TR><TR><TD ALIGN="LEFT">0x004011a9: </TD><TD ALIGN="LEFT">mov</TD><TD ALIGN="LEFT">dword ptr [rbp - 0xc], 0x7b</TD><TD></TD></TR><TR><TD ALIGN="LEFT">0x004011b0: </TD><TD ALIGN="LEFT">mov</TD><TD ALIGN="LEFT">edi, 0xa</TD><TD></TD></TR><TR><TD ALIGN="LEFT">0x004011b5: </TD><TD ALIGN="LEFT">call</TD><TD ALIGN="LEFT">0x401050</TD><TD></TD></TR></TABLE> }>]
19 [shape=Mrecord, fontname=monospace, fontsize=8.0, label=<{ <TABLE BORDER="0" CELLPADDING="1" ALIGN="LEFT"><TR><TD >0x4011ba</TD><TD >(0x40119a)</TD><TD ><B>main+0x20</B></TD><TD></TD></TR></TABLE>|<TABLE BORDER="0" CELLPADDING="1" ALIGN="LEFT"><TR><TD ALIGN="LEFT">0x004011ba: </TD><TD ALIGN="LEFT">mov</TD><TD ALIGN="LEFT">qword ptr [rbp - 8], rax</TD><TD></TD></TR><TR><TD ALIGN="LEFT">0x004011be: </TD><TD ALIGN="LEFT">mov</TD><TD ALIGN="LEFT">rax, qword ptr [rbp - 8]</TD><TD></TD></TR><TR><TD ALIGN="LEFT">0x004011c2: </TD><TD ALIGN="LEFT">mov</TD><TD ALIGN="LEFT">dword ptr [rax], 1</TD><TD></TD></TR><TR><TD ALIGN="LEFT">0x004011c8: </TD><TD ALIGN="LEFT">mov</TD><TD ALIGN="LEFT">eax, dword ptr [rbp - 0xc]</TD><TD></TD></TR><TR><TD ALIGN="LEFT">0x004011cb: </TD><TD ALIGN="LEFT">mov</TD><TD ALIGN="LEFT">esi, eax</TD><TD></TD></TR><TR><TD ALIGN="LEFT">0x004011cd: </TD><TD ALIGN="LEFT">lea</TD><TD ALIGN="LEFT">rdi, [rip + 0x2e6c]</TD><TD></TD></TR><TR><TD ALIGN="LEFT">0x004011d4: </TD><TD ALIGN="LEFT">call</TD><TD ALIGN="LEFT">0x401070</TD><TD></TD></TR></TABLE> }>]
25 [shape=Mrecord, fontname=monospace, fontsize=8.0, label=<{ <TABLE BORDER="0" CELLPADDING="1" ALIGN="LEFT"><TR><TD >0x4011d9</TD><TD >(0x40119a)</TD><TD ><B>main+0x3f</B></TD><TD></TD></TR></TABLE>|<TABLE BORDER="0" CELLPADDING="1" ALIGN="LEFT"><TR><TD ALIGN="LEFT">0x004011d9: </TD><TD ALIGN="LEFT">mov</TD><TD ALIGN="LEFT">rdx, rax</TD><TD></TD></TR><TR><TD ALIGN="LEFT">0x004011dc: </TD><TD ALIGN="LEFT">mov</TD><TD ALIGN="LEFT">rax, qword ptr [rip + 0x2ded]</TD><TD></TD></TR><TR><TD ALIGN="LEFT">0x004011e3: </TD><TD ALIGN="LEFT">mov</TD><TD ALIGN="LEFT">rsi, rax</TD><TD></TD></TR><TR><TD ALIGN="LEFT">0x004011e6: </TD><TD ALIGN="LEFT">mov</TD><TD ALIGN="LEFT">rdi, rdx</TD><TD></TD></TR><TR><TD ALIGN="LEFT">0x004011e9: </TD><TD ALIGN="LEFT">call</TD><TD ALIGN="LEFT">0x401040</TD><TD></TD></TR></TABLE> }>]
33 [shape=Mrecord, fontname=monospace, fontsize=8.0, label=<{ <TABLE BORDER="0" CELLPADDING="1" ALIGN="LEFT"><TR><TD >0x4011ee</TD><TD >(0x40119a)</TD><TD ><B>main+0x54</B></TD><TD></TD></TR></TABLE>|<TABLE BORDER="0" CELLPADDING="1" ALIGN="LEFT"><TR><TD ALIGN="LEFT">0x004011ee: </TD><TD ALIGN="LEFT">mov</TD><TD ALIGN="LEFT">eax, dword ptr [rbp - 0x10]</TD><TD></TD></TR><TR><TD ALIGN="LEFT">0x004011f1: </TD><TD ALIGN="LEFT">mov</TD><TD ALIGN="LEFT">esi, eax</TD><TD></TD></TR><TR><TD ALIGN="LEFT">0x004011f3: </TD><TD ALIGN="LEFT">lea</TD><TD ALIGN="LEFT">rdi, [rip + 0x2e46]</TD><TD></TD></TR><TR><TD ALIGN="LEFT">0x004011fa: </TD><TD ALIGN="LEFT">call</TD><TD ALIGN="LEFT">0x401070</TD><TD></TD></TR></TABLE> }>]
39 [shape=Mrecord, fontname=monospace, fontsize=8.0, label=<{ <TABLE BORDER="0" CELLPADDING="1" ALIGN="LEFT"><TR><TD >0x4011ff</TD><TD >(0x40119a)</TD><TD ><B>main+0x65</B></TD><TD></TD></TR></TABLE>|<TABLE BORDER="0" CELLPADDING="1" ALIGN="LEFT"><TR><TD ALIGN="LEFT">0x004011ff: </TD><TD ALIGN="LEFT">mov</TD><TD ALIGN="LEFT">rdx, rax</TD><TD></TD></TR><TR><TD ALIGN="LEFT">0x00401202: </TD><TD ALIGN="LEFT">mov</TD><TD ALIGN="LEFT">rax, qword ptr [rip + 0x2dc7]</TD><TD></TD></TR><TR><TD ALIGN="LEFT">0x00401209: </TD><TD ALIGN="LEFT">mov</TD><TD ALIGN="LEFT">rsi, rax</TD><TD></TD></TR><TR><TD ALIGN="LEFT">0x0040120c: </TD><TD ALIGN="LEFT">mov</TD><TD ALIGN="LEFT">rdi, rdx</TD><TD></TD></TR><TR><TD ALIGN="LEFT">0x0040120f: </TD><TD ALIGN="LEFT">call</TD><TD ALIGN="LEFT">0x401040</TD><TD></TD></TR></TABLE> }>]
43 [shape=Mrecord, fontname=monospace, fontsize=8.0, label=<{ <TABLE BORDER="0" CELLPADDING="1" ALIGN="LEFT"><TR><TD >0x401214</TD><TD >(0x40119a)</TD><TD ><B>main+0x7a</B></TD><TD></TD></TR></TABLE>|<TABLE BORDER="0" CELLPADDING="1" ALIGN="LEFT"><TR><TD ALIGN="LEFT">0x00401214: </TD><TD ALIGN="LEFT">mov</TD><TD ALIGN="LEFT">rax, qword ptr [rbp - 8]</TD><TD></TD></TR><TR><TD ALIGN="LEFT">0x00401218: </TD><TD ALIGN="LEFT">add</TD><TD ALIGN="LEFT">rax, 4</TD><TD></TD></TR><TR><TD ALIGN="LEFT">0x0040121c: </TD><TD ALIGN="LEFT">mov</TD><TD ALIGN="LEFT">dword ptr [rax], 2</TD><TD></TD></TR><TR><TD ALIGN="LEFT">0x00401222: </TD><TD ALIGN="LEFT">mov</TD><TD ALIGN="LEFT">rax, qword ptr [rbp - 8]</TD><TD></TD></TR><TR><TD ALIGN="LEFT">0x00401226: </TD><TD ALIGN="LEFT">mov</TD><TD ALIGN="LEFT">eax, dword ptr [rax]</TD><TD></TD></TR><TR><TD ALIGN="LEFT">0x00401228: </TD><TD ALIGN="LEFT">mov</TD><TD ALIGN="LEFT">esi, eax</TD><TD></TD></TR><TR><TD ALIGN="LEFT">0x0040122a: </TD><TD ALIGN="LEFT">lea</TD><TD ALIGN="LEFT">rdi, [rip + 0x2e0f]</TD><TD></TD></TR><TR><TD ALIGN="LEFT">0x00401231: </TD><TD ALIGN="LEFT">call</TD><TD ALIGN="LEFT">0x401070</TD><TD></TD></TR></TABLE> }>]
46 [shape=Mrecord, fontname=monospace, fontsize=8.0, label=<{ <TABLE BORDER="0" CELLPADDING="1" ALIGN="LEFT"><TR><TD >0x401236</TD><TD >(0x40119a)</TD><TD ><B>main+0x9c</B></TD><TD></TD></TR></TABLE>|<TABLE BORDER="0" CELLPADDING="1" ALIGN="LEFT"><TR><TD ALIGN="LEFT">0x00401236: </TD><TD ALIGN="LEFT">mov</TD><TD ALIGN="LEFT">rdx, rax</TD><TD></TD></TR><TR><TD ALIGN="LEFT">0x00401239: </TD><TD ALIGN="LEFT">mov</TD><TD ALIGN="LEFT">rax, qword ptr [rip + 0x2d90]</TD><TD></TD></TR><TR><TD ALIGN="LEFT">0x00401240: </TD><TD ALIGN="LEFT">mov</TD><TD ALIGN="LEFT">rsi, rax</TD><TD></TD></TR><TR><TD ALIGN="LEFT">0x00401243: </TD><TD ALIGN="LEFT">mov</TD><TD ALIGN="LEFT">rdi, rdx</TD><TD></TD></TR><TR><TD ALIGN="LEFT">0x00401246: </TD><TD ALIGN="LEFT">call</TD><TD ALIGN="LEFT">0x401040</TD><TD></TD></TR></TABLE> }>]
49 [shape=Mrecord, fontname=monospace, fontsize=8.0, label=<{ <TABLE BORDER="0" CELLPADDING="1" ALIGN="LEFT"><TR><TD >0x40124b</TD><TD >(0x40119a)</TD><TD ><B>main+0xb1</B></TD><TD></TD></TR></TABLE>|<TABLE BORDER="0" CELLPADDING="1" ALIGN="LEFT"><TR><TD ALIGN="LEFT">0x0040124b: </TD><TD ALIGN="LEFT">mov</TD><TD ALIGN="LEFT">rax, qword ptr [rbp - 8]</TD><TD></TD></TR><TR><TD ALIGN="LEFT">0x0040124f: </TD><TD ALIGN="LEFT">add</TD><TD ALIGN="LEFT">rax, 4</TD><TD></TD></TR><TR><TD ALIGN="LEFT">0x00401253: </TD><TD ALIGN="LEFT">mov</TD><TD ALIGN="LEFT">eax, dword ptr [rax]</TD><TD></TD></TR><TR><TD ALIGN="LEFT">0x00401255: </TD><TD ALIGN="LEFT">mov</TD><TD ALIGN="LEFT">esi, eax</TD><TD></TD></TR><TR><TD ALIGN="LEFT">0x00401257: </TD><TD ALIGN="LEFT">lea</TD><TD ALIGN="LEFT">rdi, [rip + 0x2de2]</TD><TD></TD></TR><TR><TD ALIGN="LEFT">0x0040125e: </TD><TD ALIGN="LEFT">call</TD><TD ALIGN="LEFT">0x401070</TD><TD></TD></TR></TABLE> }>]
52 [shape=Mrecord, fontname=monospace, fontsize=8.0, label=<{ <TABLE BORDER="0" CELLPADDING="1" ALIGN="LEFT"><TR><TD >0x401263</TD><TD >(0x40119a)</TD><TD ><B>main+0xc9</B></TD><TD></TD></TR></TABLE>|<TABLE BORDER="0" CELLPADDING="1" ALIGN="LEFT"><TR><TD ALIGN="LEFT">0x00401263: </TD><TD ALIGN="LEFT">mov</TD><TD ALIGN="LEFT">rdx, rax</TD><TD></TD></TR><TR><TD ALIGN="LEFT">0x00401266: </TD><TD ALIGN="LEFT">mov</TD><TD ALIGN="LEFT">rax, qword ptr [rip + 0x2d63]</TD><TD></TD></TR><TR><TD ALIGN="LEFT">0x0040126d: </TD><TD ALIGN="LEFT">mov</TD><TD ALIGN="LEFT">rsi, rax</TD><TD></TD></TR><TR><TD ALIGN="LEFT">0x00401270: </TD><TD ALIGN="LEFT">mov</TD><TD ALIGN="LEFT">rdi, rdx</TD><TD></TD></TR><TR><TD ALIGN="LEFT">0x00401273: </TD><TD ALIGN="LEFT">call</TD><TD ALIGN="LEFT">0x401040</TD><TD></TD></TR></TABLE> }>]
55 [shape=Mrecord, fontname=monospace, fontsize=8.0, label=<{ <TABLE BORDER="0" CELLPADDING="1" ALIGN="LEFT"><TR><TD >0x401278</TD><TD >(0x40119a)</TD><TD ><B>main+0xde</B></TD><TD></TD></TR></TABLE>|<TABLE BORDER="0" CELLPADDING="1" ALIGN="LEFT"><TR><TD ALIGN="LEFT">0x00401278: </TD><TD ALIGN="LEFT">mov</TD><TD ALIGN="LEFT">eax, 0</TD><TD></TD></TR><TR><TD ALIGN="LEFT">0x0040127d: </TD><TD ALIGN="LEFT">leave</TD><TD></TD><TD></TD></TR><TR><TD ALIGN="LEFT">0x0040127e: </TD><TD ALIGN="LEFT">ret</TD><TD></TD><TD></TD></TR></TABLE> }>]
24 [shape=Mrecord, fontname=monospace, fontsize=8.0, label=<{ <TABLE BORDER="0" CELLPADDING="1" ALIGN="LEFT"><TR><TD >0x40127f</TD><TD >(0x40127f)</TD><TD ><B>_Z41__static_initialization_and_destruction_0ii</B></TD><TD></TD></TR></TABLE>|<TABLE BORDER="0" CELLPADDING="1" ALIGN="LEFT"><TR><TD ALIGN="LEFT">0x0040127f: </TD><TD ALIGN="LEFT">push</TD><TD ALIGN="LEFT">rbp</TD><TD></TD></TR><TR><TD ALIGN="LEFT">0x00401280: </TD><TD ALIGN="LEFT">mov</TD><TD ALIGN="LEFT">rbp, rsp</TD><TD></TD></TR><TR><TD ALIGN="LEFT">0x00401283: </TD><TD ALIGN="LEFT">sub</TD><TD ALIGN="LEFT">rsp, 0x10</TD><TD></TD></TR><TR><TD ALIGN="LEFT">0x00401287: </TD><TD ALIGN="LEFT">mov</TD><TD ALIGN="LEFT">dword ptr [rbp - 4], edi</TD><TD></TD></TR><TR><TD ALIGN="LEFT">0x0040128a: </TD><TD ALIGN="LEFT">mov</TD><TD ALIGN="LEFT">dword ptr [rbp - 8], esi</TD><TD></TD></TR><TR><TD ALIGN="LEFT">0x0040128d: </TD><TD ALIGN="LEFT">cmp</TD><TD ALIGN="LEFT">dword ptr [rbp - 4], 1</TD><TD></TD></TR><TR><TD ALIGN="LEFT">0x00401291: </TD><TD ALIGN="LEFT">jne</TD><TD ALIGN="LEFT">0x4012c5</TD><TD></TD></TR></TABLE> }>]
26 [shape=Mrecord, fontname=monospace, fontsize=8.0, label=<{ <TABLE BORDER="0" CELLPADDING="1" ALIGN="LEFT"><TR><TD >0x401293</TD><TD >(0x40127f)</TD><TD ><B>_Z41__static_initialization_and_destruction_0ii+0x14</B></TD><TD></TD></TR></TABLE>|<TABLE BORDER="0" CELLPADDING="1" ALIGN="LEFT"><TR><TD ALIGN="LEFT">0x00401293: </TD><TD ALIGN="LEFT">cmp</TD><TD ALIGN="LEFT">dword ptr [rbp - 8], 0xffff</TD><TD></TD></TR><TR><TD ALIGN="LEFT">0x0040129a: </TD><TD ALIGN="LEFT">jne</TD><TD ALIGN="LEFT">0x4012c5</TD><TD></TD></TR></TABLE> }>]
29 [shape=Mrecord, fontname=monospace, fontsize=8.0, label=<{ <TABLE BORDER="0" CELLPADDING="1" ALIGN="LEFT"><TR><TD >0x40129c</TD><TD >(0x40127f)</TD><TD ><B>_Z41__static_initialization_and_destruction_0ii+0x1d</B></TD><TD></TD></TR></TABLE>|<TABLE BORDER="0" CELLPADDING="1" ALIGN="LEFT"><TR><TD ALIGN="LEFT">0x0040129c: </TD><TD ALIGN="LEFT">lea</TD><TD ALIGN="LEFT">rdi, [rip + 0x2eae]</TD><TD></TD></TR><TR><TD ALIGN="LEFT">0x004012a3: </TD><TD ALIGN="LEFT">call</TD><TD ALIGN="LEFT">0x401060</TD><TD></TD></TR></TABLE> }>]
36 [shape=Mrecord, fontname=monospace, fontsize=8.0, label=<{ <TABLE BORDER="0" CELLPADDING="1" ALIGN="LEFT"><TR><TD >0x4012a8</TD><TD >(0x40127f)</TD><TD ><B>_Z41__static_initialization_and_destruction_0ii+0x29</B></TD><TD></TD></TR></TABLE>|<TABLE BORDER="0" CELLPADDING="1" ALIGN="LEFT"><TR><TD ALIGN="LEFT">0x004012a8: </TD><TD ALIGN="LEFT">lea</TD><TD ALIGN="LEFT">rdx, [rip + 0x2d59]</TD><TD></TD></TR><TR><TD ALIGN="LEFT">0x004012af: </TD><TD ALIGN="LEFT">lea</TD><TD ALIGN="LEFT">rsi, [rip + 0x2e9b]</TD><TD></TD></TR><TR><TD ALIGN="LEFT">0x004012b6: </TD><TD ALIGN="LEFT">mov</TD><TD ALIGN="LEFT">rax, qword ptr [rip + 0x2d3b]</TD><TD></TD></TR><TR><TD ALIGN="LEFT">0x004012bd: </TD><TD ALIGN="LEFT">mov</TD><TD ALIGN="LEFT">rdi, rax</TD><TD></TD></TR><TR><TD ALIGN="LEFT">0x004012c0: </TD><TD ALIGN="LEFT">call</TD><TD ALIGN="LEFT">0x401030</TD><TD></TD></TR></TABLE> }>]
27 [shape=Mrecord, fontname=monospace, fontsize=8.0, label=<{ <TABLE BORDER="0" CELLPADDING="1" ALIGN="LEFT"><TR><TD >0x4012c5</TD><TD >(0x40127f)</TD><TD ><B>_Z41__static_initialization_and_destruction_0ii+0x46</B></TD><TD></TD></TR></TABLE>|<TABLE BORDER="0" CELLPADDING="1" ALIGN="LEFT"><TR><TD ALIGN="LEFT">0x004012c5: </TD><TD ALIGN="LEFT">nop</TD><TD></TD><TD></TD></TR><TR><TD ALIGN="LEFT">0x004012c6: </TD><TD ALIGN="LEFT">leave</TD><TD></TD><TD></TD></TR><TR><TD ALIGN="LEFT">0x004012c7: </TD><TD ALIGN="LEFT">ret</TD><TD></TD><TD></TD></TR></TABLE> }>]
22 [shape=Mrecord, fontname=monospace, fontsize=8.0, label=<{ <TABLE BORDER="0" CELLPADDING="1" ALIGN="LEFT"><TR><TD >0x4012c8</TD><TD >(0x4012c8)</TD><TD ><B>_GLOBAL__sub_I_main</B></TD><TD></TD></TR></TABLE>|<TABLE BORDER="0" CELLPADDING="1" ALIGN="LEFT"><TR><TD ALIGN="LEFT">0x004012c8: </TD><TD ALIGN="LEFT">push</TD><TD ALIGN="LEFT">rbp</TD><TD></TD></TR><TR><TD ALIGN="LEFT">0x004012c9: </TD><TD ALIGN="LEFT">mov</TD><TD ALIGN="LEFT">rbp, rsp</TD><TD></TD></TR><TR><TD ALIGN="LEFT">0x004012cc: </TD><TD ALIGN="LEFT">mov</TD><TD ALIGN="LEFT">esi, 0xffff</TD><TD></TD></TR><TR><TD ALIGN="LEFT">0x004012d1: </TD><TD ALIGN="LEFT">mov</TD><TD ALIGN="LEFT">edi, 1</TD><TD></TD></TR><TR><TD ALIGN="LEFT">0x004012d6: </TD><TD ALIGN="LEFT">call</TD><TD ALIGN="LEFT">0x40127f</TD><TD></TD></TR></TABLE> }>]
30 [shape=Mrecord, fontname=monospace, fontsize=8.0, label=<{ <TABLE BORDER="0" CELLPADDING="1" ALIGN="LEFT"><TR><TD >0x4012db</TD><TD >(0x4012c8)</TD><TD ><B>_GLOBAL__sub_I_main+0x13</B></TD><TD></TD></TR></TABLE>|<TABLE BORDER="0" CELLPADDING="1" ALIGN="LEFT"><TR><TD ALIGN="LEFT">0x004012db: </TD><TD ALIGN="LEFT">pop</TD><TD ALIGN="LEFT">rbp</TD><TD></TD></TR><TR><TD ALIGN="LEFT">0x004012dc: </TD><TD ALIGN="LEFT">ret</TD><TD></TD><TD></TD></TR></TABLE> }>]
2 [shape=Mrecord, fontname=monospace, fontsize=8.0, label=<{ <TABLE BORDER="0" CELLPADDING="1" ALIGN="LEFT"><TR><TD >0x4012e0</TD><TD >(0x4012e0)</TD><TD ><B>__libc_csu_init</B></TD><TD></TD></TR></TABLE>|<TABLE BORDER="0" CELLPADDING="1" ALIGN="LEFT"><TR><TD ALIGN="LEFT">0x004012e0: </TD><TD ALIGN="LEFT">endbr64</TD><TD></TD><TD></TD></TR><TR><TD ALIGN="LEFT">0x004012e4: </TD><TD ALIGN="LEFT">push</TD><TD ALIGN="LEFT">r15</TD><TD></TD></TR><TR><TD ALIGN="LEFT">0x004012e6: </TD><TD ALIGN="LEFT">lea</TD><TD ALIGN="LEFT">r15, [rip + 0x2a83]</TD><TD></TD></TR><TR><TD ALIGN="LEFT">0x004012ed: </TD><TD ALIGN="LEFT">push</TD><TD ALIGN="LEFT">r14</TD><TD></TD></TR><TR><TD ALIGN="LEFT">0x004012ef: </TD><TD ALIGN="LEFT">mov</TD><TD ALIGN="LEFT">r14, rdx</TD><TD></TD></TR><TR><TD ALIGN="LEFT">0x004012f2: </TD><TD ALIGN="LEFT">push</TD><TD ALIGN="LEFT">r13</TD><TD></TD></TR><TR><TD ALIGN="LEFT">0x004012f4: </TD><TD ALIGN="LEFT">mov</TD><TD ALIGN="LEFT">r13, rsi</TD><TD></TD></TR><TR><TD ALIGN="LEFT">0x004012f7: </TD><TD ALIGN="LEFT">push</TD><TD ALIGN="LEFT">r12</TD><TD></TD></TR><TR><TD ALIGN="LEFT">0x004012f9: </TD><TD ALIGN="LEFT">mov</TD><TD ALIGN="LEFT">r12d, edi</TD><TD></TD></TR><TR><TD ALIGN="LEFT">0x004012fc: </TD><TD ALIGN="LEFT">push</TD><TD ALIGN="LEFT">rbp</TD><TD></TD></TR><TR><TD ALIGN="LEFT">0x004012fd: </TD><TD ALIGN="LEFT">lea</TD><TD ALIGN="LEFT">rbp, [rip + 0x2a7c]</TD><TD></TD></TR><TR><TD ALIGN="LEFT">0x00401304: </TD><TD ALIGN="LEFT">push</TD><TD ALIGN="LEFT">rbx</TD><TD></TD></TR><TR><TD ALIGN="LEFT">0x00401305: </TD><TD ALIGN="LEFT">sub</TD><TD ALIGN="LEFT">rbp, r15</TD><TD></TD></TR><TR><TD ALIGN="LEFT">0x00401308: </TD><TD ALIGN="LEFT">sub</TD><TD ALIGN="LEFT">rsp, 8</TD><TD></TD></TR><TR><TD ALIGN="LEFT">0x0040130c: </TD><TD ALIGN="LEFT">call</TD><TD ALIGN="LEFT">0x401000</TD><TD></TD></TR></TABLE> }>]
6 [shape=Mrecord, fontname=monospace, fontsize=8.0, label=<{ <TABLE BORDER="0" CELLPADDING="1" ALIGN="LEFT"><TR><TD >0x401311</TD><TD >(0x4012e0)</TD><TD ><B>__libc_csu_init+0x31</B></TD><TD></TD></TR></TABLE>|<TABLE BORDER="0" CELLPADDING="1" ALIGN="LEFT"><TR><TD ALIGN="LEFT">0x00401311: </TD><TD ALIGN="LEFT">sar</TD><TD ALIGN="LEFT">rbp, 3</TD><TD></TD></TR><TR><TD ALIGN="LEFT">0x00401315: </TD><TD ALIGN="LEFT">je</TD><TD ALIGN="LEFT">0x401336</TD><TD></TD></TR></TABLE> }>]
8 [shape=Mrecord, fontname=monospace, fontsize=8.0, label=<{ <TABLE BORDER="0" CELLPADDING="1" ALIGN="LEFT"><TR><TD >0x401317</TD><TD >(0x4012e0)</TD><TD ><B>__libc_csu_init+0x37</B></TD><TD></TD></TR></TABLE>|<TABLE BORDER="0" CELLPADDING="1" ALIGN="LEFT"><TR><TD ALIGN="LEFT">0x00401317: </TD><TD ALIGN="LEFT">xor</TD><TD ALIGN="LEFT">ebx, ebx</TD><TD></TD></TR><TR><TD ALIGN="LEFT">0x00401319: </TD><TD ALIGN="LEFT">nop</TD><TD ALIGN="LEFT">dword ptr [rax]</TD><TD></TD></TR><TR><TD ALIGN="LEFT">0x00401320: </TD><TD ALIGN="LEFT">mov</TD><TD ALIGN="LEFT">rdx, r14</TD><TD></TD></TR><TR><TD ALIGN="LEFT">0x00401323: </TD><TD ALIGN="LEFT">mov</TD><TD ALIGN="LEFT">rsi, r13</TD><TD></TD></TR><TR><TD ALIGN="LEFT">0x00401326: </TD><TD ALIGN="LEFT">mov</TD><TD ALIGN="LEFT">edi, r12d</TD><TD></TD></TR><TR><TD ALIGN="LEFT">0x00401329: </TD><TD ALIGN="LEFT">call</TD><TD ALIGN="LEFT">qword ptr [r15 + rbx*8]</TD><TD></TD></TR></TABLE> }>]
20 [shape=Mrecord, fontname=monospace, fontsize=8.0, label=<{ <TABLE BORDER="0" CELLPADDING="1" ALIGN="LEFT"><TR><TD >0x401320</TD><TD >(0x4012e0)</TD><TD ><B>__libc_csu_init+0x40</B></TD><TD></TD></TR></TABLE>|<TABLE BORDER="0" CELLPADDING="1" ALIGN="LEFT"><TR><TD ALIGN="LEFT">0x00401320: </TD><TD ALIGN="LEFT">mov</TD><TD ALIGN="LEFT">rdx, r14</TD><TD></TD></TR><TR><TD ALIGN="LEFT">0x00401323: </TD><TD ALIGN="LEFT">mov</TD><TD ALIGN="LEFT">rsi, r13</TD><TD></TD></TR><TR><TD ALIGN="LEFT">0x00401326: </TD><TD ALIGN="LEFT">mov</TD><TD ALIGN="LEFT">edi, r12d</TD><TD></TD></TR><TR><TD ALIGN="LEFT">0x00401329: </TD><TD ALIGN="LEFT">call</TD><TD ALIGN="LEFT">qword ptr [r15 + rbx*8]</TD><TD></TD></TR></TABLE> }>]
17 [shape=Mrecord, fontname=monospace, fontsize=8.0, label=<{ <TABLE BORDER="0" CELLPADDING="1" ALIGN="LEFT"><TR><TD >0x40132d</TD><TD >(0x4012e0)</TD><TD ><B>__libc_csu_init+0x4d</B></TD><TD></TD></TR></TABLE>|<TABLE BORDER="0" CELLPADDING="1" ALIGN="LEFT"><TR><TD ALIGN="LEFT">0x0040132d: </TD><TD ALIGN="LEFT">add</TD><TD ALIGN="LEFT">rbx, 1</TD><TD></TD></TR><TR><TD ALIGN="LEFT">0x00401331: </TD><TD ALIGN="LEFT">cmp</TD><TD ALIGN="LEFT">rbp, rbx</TD><TD></TD></TR><TR><TD ALIGN="LEFT">0x00401334: </TD><TD ALIGN="LEFT">jne</TD><TD ALIGN="LEFT">0x401320</TD><TD></TD></TR></TABLE> }>]
7 [shape=Mrecord, fontname=monospace, fontsize=8.0, label=<{ <TABLE BORDER="0" CELLPADDING="1" ALIGN="LEFT"><TR><TD >0x401336</TD><TD >(0x4012e0)</TD><TD ><B>__libc_csu_init+0x56</B></TD><TD></TD></TR></TABLE>|<TABLE BORDER="0" CELLPADDING="1" ALIGN="LEFT"><TR><TD ALIGN="LEFT">0x00401336: </TD><TD ALIGN="LEFT">add</TD><TD ALIGN="LEFT">rsp, 8</TD><TD></TD></TR><TR><TD ALIGN="LEFT">0x0040133a: </TD><TD ALIGN="LEFT">pop</TD><TD ALIGN="LEFT">rbx</TD><TD></TD></TR><TR><TD ALIGN="LEFT">0x0040133b: </TD><TD ALIGN="LEFT">pop</TD><TD ALIGN="LEFT">rbp</TD><TD></TD></TR><TR><TD ALIGN="LEFT">0x0040133c: </TD><TD ALIGN="LEFT">pop</TD><TD ALIGN="LEFT">r12</TD><TD></TD></TR><TR><TD ALIGN="LEFT">0x0040133e: </TD><TD ALIGN="LEFT">pop</TD><TD ALIGN="LEFT">r13</TD><TD></TD></TR><TR><TD ALIGN="LEFT">0x00401340: </TD><TD ALIGN="LEFT">pop</TD><TD ALIGN="LEFT">r14</TD><TD></TD></TR><TR><TD ALIGN="LEFT">0x00401342: </TD><TD ALIGN="LEFT">pop</TD><TD ALIGN="LEFT">r15</TD><TD></TD></TR><TR><TD ALIGN="LEFT">0x00401344: </TD><TD ALIGN="LEFT">ret</TD><TD></TD><TD></TD></TR></TABLE> }>]
1 [shape=Mrecord, fontname=monospace, fontsize=8.0, style=filled, fillcolor="#dddddd", label=<{ <TABLE BORDER="0" CELLPADDING="1" ALIGN="LEFT"><TR><TD >0x500008</TD><TD >(0x500008)</TD><TD ><B>__libc_start_main</B></TD><TD >SIMP</TD></TR></TABLE> }>]
40 [shape=Mrecord, fontname=monospace, fontsize=8.0, style=filled, fillcolor="#dddddd", label=<{ <TABLE BORDER="0" CELLPADDING="1" ALIGN="LEFT"><TR><TD >0x500020</TD><TD >(0x500020)</TD><TD ><B>__cxa_atexit</B></TD><TD >SIMP</TD></TR></TABLE> }>]
42 [shape=Mrecord, fontname=monospace, fontsize=8.0, style=filled, fillcolor="#dddddd", label=<{ <TABLE BORDER="0" CELLPADDING="1" ALIGN="LEFT"><TR><TD >0x500028</TD><TD >(0x500028)</TD><TD ><B>std::ostream::operator<<(std::ostream& (std::ostream)*)</B></TD><TD >SIMP</TD></TR></TABLE> }>]
54 [shape=Mrecord, fontname=monospace, fontsize=8.0, style=filled, fillcolor="#dddddd", label=<{ <TABLE BORDER="0" CELLPADDING="1" ALIGN="LEFT"><TR><TD >0x500028</TD><TD >(0x500028)</TD><TD ><B>std::ostream::operator<<(std::ostream& (std::ostream)*)</B></TD><TD >SIMP</TD></TR></TABLE> }>]
31 [shape=Mrecord, fontname=monospace, fontsize=8.0, style=filled, fillcolor="#dddddd", label=<{ <TABLE BORDER="0" CELLPADDING="1" ALIGN="LEFT"><TR><TD >0x500028</TD><TD >(0x500028)</TD><TD ><B>std::ostream::operator<<(std::ostream& (std::ostream)*)</B></TD><TD >SIMP</TD></TR></TABLE> }>]
48 [shape=Mrecord, fontname=monospace, fontsize=8.0, style=filled, fillcolor="#dddddd", label=<{ <TABLE BORDER="0" CELLPADDING="1" ALIGN="LEFT"><TR><TD >0x500028</TD><TD >(0x500028)</TD><TD ><B>std::ostream::operator<<(std::ostream& (std::ostream)*)</B></TD><TD >SIMP</TD></TR></TABLE> }>]
16 [shape=Mrecord, fontname=monospace, fontsize=8.0, style=filled, fillcolor="#dddddd", label=<{ <TABLE BORDER="0" CELLPADDING="1" ALIGN="LEFT"><TR><TD >0x500030</TD><TD >(0x500030)</TD><TD ><B>malloc</B></TD><TD >SIMP</TD></TR></TABLE> }>]
34 [shape=Mrecord, fontname=monospace, fontsize=8.0, style=filled, fillcolor="#dddddd", label=<{ <TABLE BORDER="0" CELLPADDING="1" ALIGN="LEFT"><TR><TD >0x500038</TD><TD >(0x500038)</TD><TD ><B>std::ios_base::Init::{ctor}()</B></TD><TD >SIMP</TD></TR></TABLE> }>]
37 [shape=Mrecord, fontname=monospace, fontsize=8.0, style=filled, fillcolor="#dddddd", label=<{ <TABLE BORDER="0" CELLPADDING="1" ALIGN="LEFT"><TR><TD >0x500040</TD><TD >(0x500040)</TD><TD ><B>std::ostream::operator<<(int)</B></TD><TD >SIMP</TD></TR></TABLE> }>]
23 [shape=Mrecord, fontname=monospace, fontsize=8.0, style=filled, fillcolor="#dddddd", label=<{ <TABLE BORDER="0" CELLPADDING="1" ALIGN="LEFT"><TR><TD >0x500040</TD><TD >(0x500040)</TD><TD ><B>std::ostream::operator<<(int)</B></TD><TD >SIMP</TD></TR></TABLE> }>]
45 [shape=Mrecord, fontname=monospace, fontsize=8.0, style=filled, fillcolor="#dddddd", label=<{ <TABLE BORDER="0" CELLPADDING="1" ALIGN="LEFT"><TR><TD >0x500040</TD><TD >(0x500040)</TD><TD ><B>std::ostream::operator<<(int)</B></TD><TD >SIMP</TD></TR></TABLE> }>]
51 [shape=Mrecord, fontname=monospace, fontsize=8.0, style=filled, fillcolor="#dddddd", label=<{ <TABLE BORDER="0" CELLPADDING="1" ALIGN="LEFT"><TR><TD >0x500040</TD><TD >(0x500040)</TD><TD ><B>std::ostream::operator<<(int)</B></TD><TD >SIMP</TD></TR></TABLE> }>]
9 [shape=Mrecord, fontname=monospace, fontsize=8.0, style=filled, fillcolor="#dddddd", label=<{ <TABLE BORDER="0" CELLPADDING="1" ALIGN="LEFT"><TR><TD >0x601060</TD><TD >(0x601060)</TD><TD ><B>__libc_start_main</B></TD><TD >SIMP</TD></TR></TABLE> }>]
56 [shape=Mrecord, fontname=monospace, fontsize=8.0, style=filled, fillcolor="#dddddd", label=<{ <TABLE BORDER="0" CELLPADDING="1" ALIGN="LEFT"><TR><TD >0x601068</TD><TD >(0x601068)</TD><TD ><B>__libc_start_main</B></TD><TD >SIMP</TD></TR></TABLE> }>]
0 -> 1 [fontname=monospace, fontsize=8.0, color="black"]
1 -> 2 [fontname=monospace, fontsize=8.0, color="black"]
1 -> 9 [fontname=monospace, fontsize=8.0, color="gray", style="dotted"]
2 -> 3 [fontname=monospace, fontsize=8.0, color="black"]
2 -> 6 [fontname=monospace, fontsize=8.0, color="gray", style="dotted"]
3 -> 4 [fontname=monospace, fontsize=8.0, color="green"]
3 -> 5 [fontname=monospace, fontsize=8.0, color="red"]
4 -> 6 [fontname=monospace, fontsize=8.0, color="gray"]
5 -> 4 [fontname=monospace, fontsize=8.0, color="gray", style="dotted"]
6 -> 7 [fontname=monospace, fontsize=8.0, color="green"]
6 -> 8 [fontname=monospace, fontsize=8.0, color="red"]
7 -> 9 [fontname=monospace, fontsize=8.0, color="gray"]
8 -> 10 [fontname=monospace, fontsize=8.0, color="black"]
8 -> 17 [fontname=monospace, fontsize=8.0, color="gray", style="dotted"]
9 -> 11 [fontname=monospace, fontsize=8.0, color="black"]
9 -> 56 [fontname=monospace, fontsize=8.0, color="gray", style="dotted"]
10 -> 12 [fontname=monospace, fontsize=8.0, color="blue"]
11 -> 13 [fontname=monospace, fontsize=8.0, color="black"]
11 -> 19 [fontname=monospace, fontsize=8.0, color="gray", style="dotted"]
12 -> 14 [fontname=monospace, fontsize=8.0, color="green"]
12 -> 15 [fontname=monospace, fontsize=8.0, color="red"]
13 -> 16 [fontname=monospace, fontsize=8.0, color="blue"]
14 -> 17 [fontname=monospace, fontsize=8.0, color="gray"]
15 -> 14 [fontname=monospace, fontsize=8.0, color="green"]
15 -> 18 [fontname=monospace, fontsize=8.0, color="red"]
16 -> 19 [fontname=monospace, fontsize=8.0, color="gray"]
17 -> 20 [fontname=monospace, fontsize=8.0, color="green"]
17 -> 7 [fontname=monospace, fontsize=8.0, color="red"]
19 -> 21 [fontname=monospace, fontsize=8.0, color="black"]
19 -> 25 [fontname=monospace, fontsize=8.0, color="gray", style="dotted"]
20 -> 22 [fontname=monospace, fontsize=8.0, color="black"]
20 -> 17 [fontname=monospace, fontsize=8.0, color="gray", style="dotted"]
21 -> 23 [fontname=monospace, fontsize=8.0, color="blue"]
22 -> 24 [fontname=monospace, fontsize=8.0, color="black"]
22 -> 30 [fontname=monospace, fontsize=8.0, color="gray", style="dotted"]
23 -> 25 [fontname=monospace, fontsize=8.0, color="gray"]
24 -> 26 [fontname=monospace, fontsize=8.0, color="red"]
24 -> 27 [fontname=monospace, fontsize=8.0, color="green"]
25 -> 28 [fontname=monospace, fontsize=8.0, color="black"]
25 -> 33 [fontname=monospace, fontsize=8.0, color="gray", style="dotted"]
26 -> 29 [fontname=monospace, fontsize=8.0, color="red"]
26 -> 27 [fontname=monospace, fontsize=8.0, color="green"]
27 -> 30 [fontname=monospace, fontsize=8.0, color="gray"]
28 -> 31 [fontname=monospace, fontsize=8.0, color="blue"]
29 -> 32 [fontname=monospace, fontsize=8.0, color="black"]
29 -> 36 [fontname=monospace, fontsize=8.0, color="gray", style="dotted"]
30 -> 17 [fontname=monospace, fontsize=8.0, color="gray"]
31 -> 33 [fontname=monospace, fontsize=8.0, color="gray"]
32 -> 34 [fontname=monospace, fontsize=8.0, color="blue"]
33 -> 35 [fontname=monospace, fontsize=8.0, color="black"]
33 -> 39 [fontname=monospace, fontsize=8.0, color="gray", style="dotted"]
34 -> 36 [fontname=monospace, fontsize=8.0, color="gray"]
35 -> 37 [fontname=monospace, fontsize=8.0, color="blue"]
36 -> 38 [fontname=monospace, fontsize=8.0, color="black"]
36 -> 27 [fontname=monospace, fontsize=8.0, color="gray", style="dotted"]
37 -> 39 [fontname=monospace, fontsize=8.0, color="gray"]
38 -> 40 [fontname=monospace, fontsize=8.0, color="blue"]
39 -> 41 [fontname=monospace, fontsize=8.0, color="black"]
39 -> 43 [fontname=monospace, fontsize=8.0, color="gray", style="dotted"]
40 -> 27 [fontname=monospace, fontsize=8.0, color="gray"]
41 -> 42 [fontname=monospace, fontsize=8.0, color="blue"]
42 -> 43 [fontname=monospace, fontsize=8.0, color="gray"]
43 -> 44 [fontname=monospace, fontsize=8.0, color="black"]
43 -> 46 [fontname=monospace, fontsize=8.0, color="gray", style="dotted"]
44 -> 45 [fontname=monospace, fontsize=8.0, color="blue"]
45 -> 46 [fontname=monospace, fontsize=8.0, color="gray"]
46 -> 47 [fontname=monospace, fontsize=8.0, color="black"]
46 -> 49 [fontname=monospace, fontsize=8.0, color="gray", style="dotted"]
47 -> 48 [fontname=monospace, fontsize=8.0, color="blue"]
48 -> 49 [fontname=monospace, fontsize=8.0, color="gray"]
49 -> 50 [fontname=monospace, fontsize=8.0, color="black"]
49 -> 52 [fontname=monospace, fontsize=8.0, color="gray", style="dotted"]
50 -> 51 [fontname=monospace, fontsize=8.0, color="blue"]
51 -> 52 [fontname=monospace, fontsize=8.0, color="gray"]
52 -> 53 [fontname=monospace, fontsize=8.0, color="black"]
52 -> 55 [fontname=monospace, fontsize=8.0, color="gray", style="dotted"]
53 -> 54 [fontname=monospace, fontsize=8.0, color="blue"]
54 -> 55 [fontname=monospace, fontsize=8.0, color="gray"]
55 -> 56 [fontname=monospace, fontsize=8.0, color="gray"]
}
```
![](https://i.imgur.com/HEzDLay.png)
可以實際觀察到,跟一般compiler 的cfg確實不太一樣,不過概念應該差不多,由此可以看到整個程式的call graph
那麼當今天我們假設要進行program slcing ,在一堆程式碼中切出有可能會經過的程式碼片段,再進行分析
# angr Backward Slicing
https://docs.angr.io/built-in-analyses/backward_slice
一開始以為可以靜態的去切割,實際上好像也是需要透過angr去模擬才行
那麼在讓我們程式碼在整齊一點
```c=
// compile with: gcc -O0 -o test test.c
#include <stdio.h>
void f_target(char buf[])
{
buf[0] = 'a';
// buf[2] = '\0';
printf("f_target: %s\n", buf);
}
void f2(char buf[])
{
buf[0] = 'a';
buf[1] = '\0';
// f_target(buf);
}
int main(void)
{
char buf[8];
// char buf2[8];
f2(buf);
int test = 10;
int test2 = 20;
int test3 = 20;
printf("f_target: %d\n", test);
printf("f_target: %d\n", test2);
printf("f_target: %d\n", test3);
// buf2[7] = 'b';
buf[7] = 's';
buf[0] = 's';
// buf[1] = 'a';
// buf[2] = 'd';
// buf[3] = 's';
// buf[4] = 'w';
f_target(buf);
buf[3] = 's';
return 0;
}
```
```python=
import angr
from angr import sim_options as so
from angrutils import plot_cfg
angr.exploration_techniques.slicecutor.l.setLevel('DEBUG')
def main():
extras = {so.REVERSE_MEMORY_NAME_MAP, so.TRACK_ACTION_HISTORY}
proj = angr.Project("test", auto_load_libs=False , use_sim_procedures=True,default_analysis_mode='symbolic')
cfg = proj.analyses.CFGEmulated(context_sensitivity_level=100, keep_state=True, normalize=True, state_add_options=angr.sim_options.refs)
main_func = cfg.functions.function(name='main')
main_func2 = cfg.functions.function(name='f2')
main_node = cfg.model.get_any_node(addr=main_func.addr)
# target_node = cfg.model.get_any_node(0x4011d1:)
# target_func = cfg.functions.function(name='f_target')
target_func = cfg.functions.function(name='f_target')
print(target_func)
target_call_site = get_call_site(main_func, target_func)
print(target_call_site)
print("---------------")
target_call_node = cfg.model.get_any_node(addr=target_call_site)
target_call_block = target_call_node.block
print(target_call_block.pp())
print(target_call_block.vex)
# Creating the backward slice
cdg = proj.analyses.CDG(cfg, start=main_func.addr)
ddg = proj.analyses.DDG(cfg, start=main_func.addr)
bs_targets = [] # 05 | PUT(rdi) = t3 # (moving buf into rdi as a parameter for f_target(...))
# for stmt_idx in range(len(target_call_block.vex.statements)):
# bs_targets.append((target_call_node,stmt_idx))
bs_targets.append((target_call_node,12))
bs = proj.analyses.BackwardSlice(cfg, cdg=cdg, ddg=ddg, targets=bs_targets,control_flow_slice=False)
acfg = bs.annotated_cfg()
print(target_call_site)
print(acfg.dbg_repr())
# Symbolic execution
start_state = proj.factory.blank_state(addr=main_func.addr, add_options=extras)
simgr = proj.factory.simgr(start_state)
slicecutor = angr.exploration_techniques.Slicecutor(acfg, force_taking_exit=False)
simgr.use_technique(slicecutor)
simgr.run()
# simgr.explore(find=target_call_site)
# fgets_func = cfg.functions.function(name='f2')
# print("f2 addr: 0x{:x}".format(fgets_func.addr))
f_target_func = cfg.functions.function(name='f_target')
print("f_target addr: 0x{:x}".format(f_target_func.addr))
if len(simgr.stashes['found']) == 0:
print("Could not find target.")
print("Stashes")
for stash_name in simgr.stashes:
stash = simgr.stashes[stash_name]
if len(stash) > 0:
print(" {}: {}".format(stash_name, stash))
for stash_name in simgr.stashes:
print(stash_name)
stash = simgr.stashes[stash_name]
if len(stash) > 0:
print(" {}: {}".format(stash_name, stash))
for x in stash:
for step in x.__getstate__()['history'].descriptions:
print((step))
acfg.dbg_print_irsb(0x401198)
print('================================')
acfg.dbg_print_irsb(0x4011b5)
print('================================')
acfg.dbg_print_irsb(0x4011d8)
print('================================')
acfg.dbg_print_irsb(0x401203)
print('================================')
acfg.dbg_print_irsb(0x401219)
print('================================')
acfg.dbg_print_irsb(0x40122f)
print('================================')
acfg.dbg_print_irsb(0x401243)
print('================================')
# acfg.get_whitelisted_statements(0x4011d8)
# print(a)
# print(x.__getstate__()['history'])
# for step in simgr.found[0].history.descriptions:
# print((step))
for func_node in cfg.functions.values():
if func_node.name.startswith("__"):
continue
else:
for block in func_node.blocks:
block.pp()
print("-----")
dict(proj.kb.functions.items())
idfer = proj.analyses.Identifier()
for funcInfo in idfer.func_info:
print(hex(funcInfo.addr), funcInfo.name)
plot_cfg(cfg, "ais3_cfg",format="dot", asminst=True, remove_imports=True, remove_path_terminator=True)
def get_call_site(caller_func, callee_func):
for call_site_addr in caller_func.get_call_sites():
if caller_func.get_call_target(call_site_addr) == callee_func.addr:
return call_site_addr
return None
if __name__ == "__main__":
main()
```
以github 這兩個issue都沒人回,改了第二個回復的程式碼片段
https://github.com/angr/angr/issues/1361
以這個c code來說我們可能要找到跟某些程式碼片段大概要經過哪些步驟呢
```python=
main_func = cfg.functions.function(name='main')
#main_func2 = cfg.functions.function(name='f2')
main_node = cfg.model.get_any_node(addr=main_func.addr)
# target_node = cfg.model.get_any_node(0x4011d1:)
# target_func = cfg.functions.function(name='f_target')
target_func = cfg.functions.function(name='f_target')
print(target_func)
target_call_site = get_call_site(main_func, target_func)
print(target_call_site)
print("---------------")
target_call_node = cfg.model.get_any_node(addr=target_call_site)
target_call_block = target_call_node.block
print(target_call_block.pp())
print(target_call_block.vex)
```
大概就是我們分析要有一個入口點,那這個入口點就是
` main_func = cfg.functions.function(name='main')`
` target_func = cfg.functions.function(name='f_target')`
以這個例子大概是main裡要找尋 f_target
```
# Creating the backward slice
cdg = proj.analyses.CDG(cfg, start=main_func.addr)
ddg = proj.analyses.DDG(cfg, start=main_func.addr)
bs_targets = [] # 05 | PUT(rdi) = t3 # (moving buf into rdi as a parameter for f_target(...))
# for stmt_idx in range(len(target_call_block.vex.statements)):
# bs_targets.append((target_call_node,stmt_idx))
bs_targets.append((target_call_node,12))
bs = proj.analyses.BackwardSlice(cfg, cdg=cdg, ddg=ddg, targets=bs_targets,control_flow_slice=False)
acfg = bs.annotated_cfg()
```
最近有空再去看他的stmt怎麼切的
https://blog.csdn.net/doudoudouzoule/article/details/80263141
應該類似可以選擇有f_target 的片段中,某一些參數要切割的就標註起來
```pyhton
start_state = proj.factory.blank_state(addr=main_func.addr, add_options=extras)
simgr = proj.factory.simgr(start_state)
slicecutor = angr.exploration_techniques.Slicecutor(acfg, force_taking_exit=False)
simgr.use_technique(slicecutor)
simgr.run()
```
最後呼叫我們的angr進行找尋
```python=
f_target_func = cfg.functions.function(name='f_target')
print("f_target addr: 0x{:x}".format(f_target_func.addr))
if len(simgr.stashes['found']) == 0:
print("Could not find target.")
print("Stashes")
for stash_name in simgr.stashes:
stash = simgr.stashes[stash_name]
if len(stash) > 0:
print(" {}: {}".format(stash_name, stash))
for stash_name in simgr.stashes:
print(stash_name)
stash = simgr.stashes[stash_name]
if len(stash) > 0:
print(" {}: {}".format(stash_name, stash))
for x in stash:
for step in x.__getstate__()['history'].descriptions:
print((step))
acfg.dbg_print_irsb(0x401198)
print('================================')
acfg.dbg_print_irsb(0x4011b5)
print('================================')
acfg.dbg_print_irsb(0x4011d8)
print('================================')
acfg.dbg_print_irsb(0x401203)
print('================================')
acfg.dbg_print_irsb(0x401219)
print('================================')
acfg.dbg_print_irsb(0x40122f)
print('================================')
acfg.dbg_print_irsb(0x401243)
print('================================')
```
找到了一些方法展開了history,裡面應該可以拿到相關的alias圖,這邊資料鰻少的靠是去call lib ,print呼叫看看
```
Stashes
cut: [<SimState @ 0x4011b5>]
active
stashed
pruned
unsat
errored
deadended
unconstrained
cut
cut: [<SimState @ 0x4011b5>]
<IRSB from 0x4011b5: 1 sat>
-[ 0] ------ IMark(0x401198, 1, 0) ------
+[ 1] t0 = GET:I64(offset=56)
+[ 2] t16 = GET:I64(offset=48)
+[ 3] t15 = Sub64(t16,0x0000000000000008)
-[ 4] PUT(offset=48) = t15
+[ 5] STle(t15) = t0
-[ 6] ------ IMark(0x401199, 3, 0) ------
-[ 7] PUT(offset=56) = t15
-[ 8] PUT(offset=184) = 0x000000000040119c
-[ 9] ------ IMark(0x40119c, 4, 0) ------
-[ 10] t18 = Add64(t15,0xfffffffffffffff8)
-[ 11] t20 = GET:I64(offset=72)
-[ 12] STle(t18) = t20
-[ 13] PUT(offset=184) = 0x00000000004011a0
-[ 14] ------ IMark(0x4011a0, 4, 0) ------
-[ 15] t21 = Add64(t15,0xfffffffffffffff8)
-[ 16] t23 = LDle:I64(t21)
-[ 17] PUT(offset=184) = 0x00000000004011a4
-[ 18] ------ IMark(0x4011a4, 3, 0) ------
-[ 19] STle(t23) = 0x61
-[ 20] PUT(offset=184) = 0x00000000004011a7
-[ 21] ------ IMark(0x4011a7, 4, 0) ------
-[ 22] t24 = Add64(t15,0xfffffffffffffff8)
-[ 23] t26 = LDle:I64(t24)
-[ 24] ------ IMark(0x4011ab, 4, 0) ------
-[ 25] t6 = Add64(t26,0x0000000000000001)
-[ 26] PUT(offset=144) = 0x0000000000000004
-[ 27] PUT(offset=152) = t26
-[ 28] PUT(offset=160) = 0x0000000000000001
-[ 29] PUT(offset=16) = t6
-[ 30] PUT(offset=184) = 0x00000000004011af
-[ 31] ------ IMark(0x4011af, 3, 0) ------
-[ 32] STle(t6) = 0x00
-[ 33] ------ IMark(0x4011b2, 1, 0) ------
-[ 34] PUT(offset=184) = 0x00000000004011b3
-[ 35] ------ IMark(0x4011b3, 1, 0) ------
+[ 36] t10 = LDle:I64(t15)
-[ 37] t27 = Add64(t15,0x0000000000000008)
-[ 38] PUT(offset=48) = t27
+[ 39] PUT(offset=56) = t10
-[ 40] PUT(offset=184) = 0x00000000004011b4
-[ 41] ------ IMark(0x4011b4, 1, 0) ------
-[ 42] t13 = LDle:I64(t27)
-[ 43] t14 = Add64(t27,0x0000000000000008)
-[ 44] PUT(offset=48) = t14
-[ 45] t28 = Sub64(t14,0x0000000000000080)
-[ 46] ====== AbiHint(0xt28, 128, t13) ======
================================
-[ 0] ------ IMark(0x4011b5, 1, 0) ------
-[ 1] t0 = GET:I64(offset=56)
+[ 2] t14 = GET:I64(offset=48)
+[ 3] t13 = Sub64(t14,0x0000000000000008)
-[ 4] PUT(offset=48) = t13
-[ 5] STle(t13) = t0
-[ 6] ------ IMark(0x4011b6, 3, 0) ------
+[ 7] PUT(offset=56) = t13
-[ 8] ------ IMark(0x4011b9, 4, 0) ------
+[ 9] t2 = Sub64(t13,0x0000000000000020)
-[ 10] PUT(offset=48) = t2
-[ 11] PUT(offset=184) = 0x00000000004011bd
-[ 12] ------ IMark(0x4011bd, 9, 0) ------
-[ 13] t17 = GET:I64(offset=208)
-[ 14] t16 = Add64(0x0000000000000028,t17)
-[ 15] t18 = LDle:I64(t16)
-[ 16] PUT(offset=184) = 0x00000000004011c6
-[ 17] ------ IMark(0x4011c6, 4, 0) ------
-[ 18] t19 = Add64(t13,0xfffffffffffffff8)
-[ 19] STle(t19) = t18
-[ 20] ------ IMark(0x4011ca, 2, 0) ------
-[ 21] PUT(offset=144) = 0x0000000000000013
-[ 22] PUT(offset=152) = 0x0000000000000000
-[ 23] PUT(offset=160) = 0x0000000000000000
-[ 24] ------ IMark(0x4011cc, 4, 0) ------
-[ 25] t29 = Add64(t13,0xfffffffffffffff0)
-[ 26] PUT(offset=16) = t29
-[ 27] ------ IMark(0x4011d0, 3, 0) ------
-[ 28] PUT(offset=72) = t29
-[ 29] PUT(offset=184) = 0x00000000004011d3
-[ 30] ------ IMark(0x4011d3, 5, 0) ------
+[ 31] t32 = Sub64(t2,0x0000000000000008)
+[ 32] PUT(offset=48) = t32
-[ 33] STle(t32) = 0x00000000004011d8
-[ 34] t34 = Sub64(t32,0x0000000000000080)
-[ 35] ====== AbiHint(0xt34, 128, 0x0000000000401198) ======
================================
-[ 0] ------ IMark(0x4011d8, 7, 0) ------
-[ 1] t8 = GET:I64(offset=56)
-[ 2] t7 = Add64(t8,0xffffffffffffffe4)
-[ 3] STle(t7) = 0x0000000a
-[ 4] PUT(offset=184) = 0x00000000004011df
-[ 5] ------ IMark(0x4011df, 7, 0) ------
-[ 6] t9 = Add64(t8,0xffffffffffffffe8)
-[ 7] STle(t9) = 0x00000014
-[ 8] PUT(offset=184) = 0x00000000004011e6
-[ 9] ------ IMark(0x4011e6, 7, 0) ------
-[ 10] t11 = Add64(t8,0xffffffffffffffec)
-[ 11] STle(t11) = 0x00000014
-[ 12] PUT(offset=184) = 0x00000000004011ed
-[ 13] ------ IMark(0x4011ed, 3, 0) ------
-[ 14] t13 = Add64(t8,0xffffffffffffffe4)
-[ 15] t16 = LDle:I32(t13)
-[ 16] t15 = 32Uto64(t16)
-[ 17] ------ IMark(0x4011f0, 2, 0) ------
-[ 18] t18 = 64to32(t15)
-[ 19] t17 = 32Uto64(t18)
-[ 20] PUT(offset=64) = t17
-[ 21] ------ IMark(0x4011f2, 7, 0) ------
-[ 22] PUT(offset=72) = 0x0000000000402012
-[ 23] ------ IMark(0x4011f9, 5, 0) ------
-[ 24] PUT(offset=16) = 0x0000000000000000
-[ 25] PUT(offset=184) = 0x00000000004011fe
-[ 26] ------ IMark(0x4011fe, 5, 0) ------
-[ 27] t22 = GET:I64(offset=48)
-[ 28] t21 = Sub64(t22,0x0000000000000008)
-[ 29] PUT(offset=48) = t21
-[ 30] STle(t21) = 0x0000000000401203
-[ 31] t23 = Sub64(t21,0x0000000000000080)
-[ 32] ====== AbiHint(0xt23, 128, 0x0000000000401040) ======
================================
-[ 0] ------ IMark(0x401203, 3, 0) ------
+[ 1] t5 = GET:I64(offset=56)
-[ 2] t4 = Add64(t5,0xffffffffffffffe8)
-[ 3] t7 = LDle:I32(t4)
-[ 4] t6 = 32Uto64(t7)
-[ 5] ------ IMark(0x401206, 2, 0) ------
-[ 6] t9 = 64to32(t6)
-[ 7] t8 = 32Uto64(t9)
-[ 8] PUT(offset=64) = t8
-[ 9] ------ IMark(0x401208, 7, 0) ------
-[ 10] PUT(offset=72) = 0x0000000000402012
-[ 11] ------ IMark(0x40120f, 5, 0) ------
-[ 12] PUT(offset=16) = 0x0000000000000000
-[ 13] PUT(offset=184) = 0x0000000000401214
-[ 14] ------ IMark(0x401214, 5, 0) ------
-[ 15] t13 = GET:I64(offset=48)
-[ 16] t12 = Sub64(t13,0x0000000000000008)
-[ 17] PUT(offset=48) = t12
-[ 18] STle(t12) = 0x0000000000401219
-[ 19] t14 = Sub64(t12,0x0000000000000080)
-[ 20] ====== AbiHint(0xt14, 128, 0x0000000000401040) ======
================================
-[ 0] ------ IMark(0x401219, 3, 0) ------
+[ 1] t5 = GET:I64(offset=56)
-[ 2] t4 = Add64(t5,0xffffffffffffffec)
-[ 3] t7 = LDle:I32(t4)
-[ 4] t6 = 32Uto64(t7)
-[ 5] ------ IMark(0x40121c, 2, 0) ------
-[ 6] t9 = 64to32(t6)
-[ 7] t8 = 32Uto64(t9)
-[ 8] PUT(offset=64) = t8
-[ 9] ------ IMark(0x40121e, 7, 0) ------
-[ 10] PUT(offset=72) = 0x0000000000402012
-[ 11] ------ IMark(0x401225, 5, 0) ------
-[ 12] PUT(offset=16) = 0x0000000000000000
-[ 13] PUT(offset=184) = 0x000000000040122a
-[ 14] ------ IMark(0x40122a, 5, 0) ------
-[ 15] t13 = GET:I64(offset=48)
-[ 16] t12 = Sub64(t13,0x0000000000000008)
-[ 17] PUT(offset=48) = t12
-[ 18] STle(t12) = 0x000000000040122f
-[ 19] t14 = Sub64(t12,0x0000000000000080)
-[ 20] ====== AbiHint(0xt14, 128, 0x0000000000401040) ======
================================
-[ 0] ------ IMark(0x40122f, 4, 0) ------
+[ 1] t6 = GET:I64(offset=56)
-[ 2] t5 = Add64(t6,0xfffffffffffffff7)
-[ 3] STle(t5) = 0x73
-[ 4] PUT(offset=184) = 0x0000000000401233
-[ 5] ------ IMark(0x401233, 4, 0) ------
-[ 6] t7 = Add64(t6,0xfffffffffffffff0)
-[ 7] STle(t7) = 0x73
-[ 8] ------ IMark(0x401237, 4, 0) ------
+[ 9] t9 = Add64(t6,0xfffffffffffffff0)
-[ 10] PUT(offset=16) = t9
-[ 11] ------ IMark(0x40123b, 3, 0) ------
+[ 12] PUT(offset=72) = t9
-[ 13] PUT(offset=184) = 0x000000000040123e
-[ 14] ------ IMark(0x40123e, 5, 0) ------
-[ 15] t13 = GET:I64(offset=48)
-[ 16] t12 = Sub64(t13,0x0000000000000008)
-[ 17] PUT(offset=48) = t12
-[ 18] STle(t12) = 0x0000000000401243
-[ 19] t14 = Sub64(t12,0x0000000000000080)
-[ 20] ====== AbiHint(0xt14, 128, 0x000000000040116a) ======
================================
-[ 0] ------ IMark(0x401243, 4, 0) ------
-[ 1] t7 = GET:I64(offset=56)
-[ 2] t6 = Add64(t7,0xfffffffffffffff3)
-[ 3] STle(t6) = 0x73
-[ 4] ------ IMark(0x401247, 5, 0) ------
-[ 5] PUT(offset=16) = 0x0000000000000000
-[ 6] PUT(offset=184) = 0x000000000040124c
-[ 7] ------ IMark(0x40124c, 4, 0) ------
-[ 8] t9 = Add64(t7,0xfffffffffffffff8)
-[ 9] t11 = LDle:I64(t9)
-[ 10] PUT(offset=184) = 0x0000000000401250
-[ 11] ------ IMark(0x401250, 9, 0) ------
-[ 12] t13 = GET:I64(offset=208)
-[ 13] t12 = Add64(0x0000000000000028,t13)
-[ 14] t3 = LDle:I64(t12)
-[ 15] t2 = Xor64(t11,t3)
-[ 16] PUT(offset=144) = 0x0000000000000014
-[ 17] PUT(offset=152) = t2
-[ 18] PUT(offset=160) = 0x0000000000000000
-[ 19] PUT(offset=32) = t2
-[ 20] PUT(offset=184) = 0x0000000000401259
-[ 21] ------ IMark(0x401259, 2, 0) ------
-[ 22] t22 = CmpEQ64(t2,0x0000000000000000)
-[ 23] t21 = 1Uto64(t22)
-[ 24] t19 = t21
-[ 25] t23 = 64to1(t19)
-[ 26] t14 = t23
-[ 27] if (t14) { PUT(offset=184) = 0x401260; Ijk_Boring }
================================
```
在這邊可以看一下前面的log
```
---------------
0x40122f: mov byte ptr [rbp - 9], 0x73
0x401233: mov byte ptr [rbp - 0x10], 0x73
0x401237: lea rax, [rbp - 0x10]
0x40123b: mov rdi, rax
0x40123e: call 0x40116a
None
IRSB {
t0:Ity_I64 t1:Ity_I64 t2:Ity_I64 t3:Ity_I64 t4:Ity_I64 t5:Ity_I64 t6:Ity_I64 t7:Ity_I64 t8:Ity_I64 t9:Ity_I64 t10:Ity_I64 t11:Ity_I64 t12:Ity_I64 t13:Ity_I64 t14:Ity_I64 t15:Ity_I64
00 | ------ IMark(0x40122f, 4, 0) ------
01 | t6 = GET:I64(rbp)
02 | t5 = Add64(t6,0xfffffffffffffff7)
03 | STle(t5) = 0x73
04 | PUT(rip) = 0x0000000000401233
05 | ------ IMark(0x401233, 4, 0) ------
06 | t7 = Add64(t6,0xfffffffffffffff0)
07 | STle(t7) = 0x73
08 | ------ IMark(0x401237, 4, 0) ------
09 | t9 = Add64(t6,0xfffffffffffffff0)
10 | PUT(rax) = t9
11 | ------ IMark(0x40123b, 3, 0) ------
12 | PUT(rdi) = t9
13 | PUT(rip) = 0x000000000040123e
14 | ------ IMark(0x40123e, 5, 0) ------
15 | t13 = GET:I64(rsp)
16 | t12 = Sub64(t13,0x0000000000000008)
17 | PUT(rsp) = t12
18 | STle(t12) = 0x0000000000401243
19 | t14 = Sub64(t12,0x0000000000000080)
20 | ====== AbiHint(0xt14, 128, 0x000000000040116a) ======
NEXT: PUT(rip) = 0x000000000040116a; Ijk_Call
}
```
在這些程式碼片段真實可以對應到的程式碼片段
在這種
+[ 9] t9 = Add64(t6,0xfffffffffffffff0)
-[ 1] t7 = GET:I64(offset=56)
我想就是類似白名單切出來的,回到issue
```pyhton
bs_targets = [(target_call_node, 5)] # 05 | PUT(rdi) = t3 # (moving buf into rdi as a parameter for f_target(...))
```
如果推論的正確這些+,-將是切割出來的程式碼片段
```python
# for stmt_idx in range(len(target_call_block.vex.statements)):
# bs_targets.append((target_call_node,stmt_idx))
bs_targets.append((target_call_node,12))
```
上述這些應該是對應到我們要切割的程式碼片段。
起始位置
0x400000+123b
這些有+前綴都是有關聯的stmt
我們開ida來看下
![](https://i.imgur.com/u7686PP.png)
![](https://i.imgur.com/BNrOuuN.png)
對應 vex ir
```
-[ 11] ------ IMark(0x40123b, 3, 0) ------
+[ 12] PUT(offset=72) = t9
-[ 13] PUT(offset=184) = 0x000000000040123e
-[ 14] ------ IMark(0x40123e, 5, 0) ------
-[ 0] ------ IMark(0x40122f, 4, 0) ------
+[ 1] t6 = GET:I64(offset=56)
-[ 2] t5 = Add64(t6,0xfffffffffffffff7)
-[ 3] STle(t5) = 0x73
-[ 4] PUT(offset=184) = 0x0000000000401233
-[ 5] ------ IMark(0x401233, 4, 0) ------
```
沒意外真的被我們切成功了,在這些基礎架構上,要做一些binary 的靜態檢測應該可以,只不過在
```c=
// buf[1] = 'a';
// buf[2] = 'd';
// buf[3] = 's';
// buf[4] = 'w';
f_target(buf);
buf[3] = 's';<===檢測不到
return 0;
}
```
和
```c=
void f2(char buf[])
{
buf[0] = 'a';
buf[1] = '\0';
// f_target(buf);
}
```
這種跨fucntion,和執行順序的,靜態分析就好像就不太有辦法做切割,如果真的能切割出程式碼片段,其實我們可以得到stmt到底遍佈在那些地方,我們就可以用這些information進行更加抽象的分析,valgrind在某些程式碼片段是沒辦法進行檢測的,
![](https://i.imgur.com/RocnFoe.png)
![](https://i.imgur.com/NbQYlp2.png)
AddressSanitizer無法檢測上面這兩種,Valgrind無法偵測右邊程式碼有memory leak,不過簡單的檢測應該做得出來,如果有一個vm可以去模擬這些ir應該就蠻ok,不知道是否有vexir simulator 之類的,那我統一轉成ir在進行模擬,其他就是要看angr或者valgrind如何實作了。
# 參考
https://hitcon.org/2012/download/0721D1_Cha%26Jinsuk_PLUS_Emulation%20based%20analysis.pdf
https://www.youtube.com/watch?v=eqaddt9ssbQ&ab_channel=FOSDEM
https://blog.csdn.net/u013648063/article/details/109032370
https://ble55ing.github.io/2019/06/18/angr-cfg/
https://github.com/angr/angr/issues/1361
https://github.com/angr/angr/blob/bcd8f3a95c9858297b2fdc2697cbb5c2ef256f23/angr/annocfg.py
https://d1nn3r.github.io/2019/07/31/angr/
https://www.twblogs.net/a/5e5498cbbd9eee2117c53d82
https://brubbish.github.io/52443.html
https://www.anquanke.com/post/id/231591
https://github.com/angr/pyvex/blob/master/pyvex/block.py
double free use-after fre 漏洞查找
https://xz.aliyun.com/t/7275