# 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&#58;&nbsp;</TD><TD ALIGN="LEFT">endbr64</TD><TD></TD><TD></TD></TR><TR><TD ALIGN="LEFT">0x00401004&#58;&nbsp;</TD><TD ALIGN="LEFT">sub</TD><TD ALIGN="LEFT">rsp, 8</TD><TD></TD></TR><TR><TD ALIGN="LEFT">0x00401008&#58;&nbsp;</TD><TD ALIGN="LEFT">mov</TD><TD ALIGN="LEFT">rax, qword ptr [rip + 0x2fd9]</TD><TD></TD></TR><TR><TD ALIGN="LEFT">0x0040100f&#58;&nbsp;</TD><TD ALIGN="LEFT">test</TD><TD ALIGN="LEFT">rax, rax</TD><TD></TD></TR><TR><TD ALIGN="LEFT">0x00401012&#58;&nbsp;</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&#58;&nbsp;</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&#58;&nbsp;</TD><TD ALIGN="LEFT">add</TD><TD ALIGN="LEFT">rsp, 8</TD><TD></TD></TR><TR><TD ALIGN="LEFT">0x0040101a&#58;&nbsp;</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&#58;&nbsp;</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&#58;&nbsp;</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&#58;&nbsp;</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&#58;&nbsp;</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&#58;&nbsp;</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&#58;&nbsp;</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&#58;&nbsp;</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&#58;&nbsp;</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&#58;&nbsp;</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&#58;&nbsp;</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&#58;&nbsp;</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&#58;&nbsp;</TD><TD ALIGN="LEFT">endbr64</TD><TD></TD><TD></TD></TR><TR><TD ALIGN="LEFT">0x00401094&#58;&nbsp;</TD><TD ALIGN="LEFT">xor</TD><TD ALIGN="LEFT">ebp, ebp</TD><TD></TD></TR><TR><TD ALIGN="LEFT">0x00401096&#58;&nbsp;</TD><TD ALIGN="LEFT">mov</TD><TD ALIGN="LEFT">r9, rdx</TD><TD></TD></TR><TR><TD ALIGN="LEFT">0x00401099&#58;&nbsp;</TD><TD ALIGN="LEFT">pop</TD><TD ALIGN="LEFT">rsi</TD><TD></TD></TR><TR><TD ALIGN="LEFT">0x0040109a&#58;&nbsp;</TD><TD ALIGN="LEFT">mov</TD><TD ALIGN="LEFT">rdx, rsp</TD><TD></TD></TR><TR><TD ALIGN="LEFT">0x0040109d&#58;&nbsp;</TD><TD ALIGN="LEFT">and</TD><TD ALIGN="LEFT">rsp, 0xfffffffffffffff0</TD><TD></TD></TR><TR><TD ALIGN="LEFT">0x004010a1&#58;&nbsp;</TD><TD ALIGN="LEFT">push</TD><TD ALIGN="LEFT">rax</TD><TD></TD></TR><TR><TD ALIGN="LEFT">0x004010a2&#58;&nbsp;</TD><TD ALIGN="LEFT">push</TD><TD ALIGN="LEFT">rsp</TD><TD></TD></TR><TR><TD ALIGN="LEFT">0x004010a3&#58;&nbsp;</TD><TD ALIGN="LEFT">lea</TD><TD ALIGN="LEFT">r8, [rip + 0x2a6]</TD><TD></TD></TR><TR><TD ALIGN="LEFT">0x004010aa&#58;&nbsp;</TD><TD ALIGN="LEFT">lea</TD><TD ALIGN="LEFT">rcx, [rip + 0x22f]</TD><TD></TD></TR><TR><TD ALIGN="LEFT">0x004010b1&#58;&nbsp;</TD><TD ALIGN="LEFT">lea</TD><TD ALIGN="LEFT">rdi, [rip + 0xe2]</TD><TD></TD></TR><TR><TD ALIGN="LEFT">0x004010b8&#58;&nbsp;</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&#58;&nbsp;</TD><TD ALIGN="LEFT">lea</TD><TD ALIGN="LEFT">rdi, [rip + 0x2f09]</TD><TD></TD></TR><TR><TD ALIGN="LEFT">0x00401107&#58;&nbsp;</TD><TD ALIGN="LEFT">lea</TD><TD ALIGN="LEFT">rsi, [rip + 0x2f02]</TD><TD></TD></TR><TR><TD ALIGN="LEFT">0x0040110e&#58;&nbsp;</TD><TD ALIGN="LEFT">push</TD><TD ALIGN="LEFT">rbp</TD><TD></TD></TR><TR><TD ALIGN="LEFT">0x0040110f&#58;&nbsp;</TD><TD ALIGN="LEFT">sub</TD><TD ALIGN="LEFT">rsi, rdi</TD><TD></TD></TR><TR><TD ALIGN="LEFT">0x00401112&#58;&nbsp;</TD><TD ALIGN="LEFT">mov</TD><TD ALIGN="LEFT">rbp, rsp</TD><TD></TD></TR><TR><TD ALIGN="LEFT">0x00401115&#58;&nbsp;</TD><TD ALIGN="LEFT">sar</TD><TD ALIGN="LEFT">rsi, 3</TD><TD></TD></TR><TR><TD ALIGN="LEFT">0x00401119&#58;&nbsp;</TD><TD ALIGN="LEFT">mov</TD><TD ALIGN="LEFT">rax, rsi</TD><TD></TD></TR><TR><TD ALIGN="LEFT">0x0040111c&#58;&nbsp;</TD><TD ALIGN="LEFT">shr</TD><TD ALIGN="LEFT">rax, 0x3f</TD><TD></TD></TR><TR><TD ALIGN="LEFT">0x00401120&#58;&nbsp;</TD><TD ALIGN="LEFT">add</TD><TD ALIGN="LEFT">rsi, rax</TD><TD></TD></TR><TR><TD ALIGN="LEFT">0x00401123&#58;&nbsp;</TD><TD ALIGN="LEFT">sar</TD><TD ALIGN="LEFT">rsi, 1</TD><TD></TD></TR><TR><TD ALIGN="LEFT">0x00401126&#58;&nbsp;</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&#58;&nbsp;</TD><TD ALIGN="LEFT">mov</TD><TD ALIGN="LEFT">rax, qword ptr [rip + 0x2ec1]</TD><TD></TD></TR><TR><TD ALIGN="LEFT">0x0040112f&#58;&nbsp;</TD><TD ALIGN="LEFT">test</TD><TD ALIGN="LEFT">rax, rax</TD><TD></TD></TR><TR><TD ALIGN="LEFT">0x00401132&#58;&nbsp;</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&#58;&nbsp;</TD><TD ALIGN="LEFT">pop</TD><TD ALIGN="LEFT">rbp</TD><TD></TD></TR><TR><TD ALIGN="LEFT">0x00401135&#58;&nbsp;</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&#58;&nbsp;</TD><TD ALIGN="LEFT">pop</TD><TD ALIGN="LEFT">rbp</TD><TD></TD></TR><TR><TD ALIGN="LEFT">0x00401141&#58;&nbsp;</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&#58;&nbsp;</TD><TD ALIGN="LEFT">push</TD><TD ALIGN="LEFT">rbp</TD><TD></TD></TR><TR><TD ALIGN="LEFT">0x00401191&#58;&nbsp;</TD><TD ALIGN="LEFT">mov</TD><TD ALIGN="LEFT">rbp, rsp</TD><TD></TD></TR><TR><TD ALIGN="LEFT">0x00401194&#58;&nbsp;</TD><TD ALIGN="LEFT">pop</TD><TD ALIGN="LEFT">rbp</TD><TD></TD></TR><TR><TD ALIGN="LEFT">0x00401195&#58;&nbsp;</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&#58;&nbsp;</TD><TD ALIGN="LEFT">push</TD><TD ALIGN="LEFT">rbp</TD><TD></TD></TR><TR><TD ALIGN="LEFT">0x0040119b&#58;&nbsp;</TD><TD ALIGN="LEFT">mov</TD><TD ALIGN="LEFT">rbp, rsp</TD><TD></TD></TR><TR><TD ALIGN="LEFT">0x0040119e&#58;&nbsp;</TD><TD ALIGN="LEFT">sub</TD><TD ALIGN="LEFT">rsp, 0x10</TD><TD></TD></TR><TR><TD ALIGN="LEFT">0x004011a2&#58;&nbsp;</TD><TD ALIGN="LEFT">mov</TD><TD ALIGN="LEFT">dword ptr [rbp - 0x10], 0x4c6</TD><TD></TD></TR><TR><TD ALIGN="LEFT">0x004011a9&#58;&nbsp;</TD><TD ALIGN="LEFT">mov</TD><TD ALIGN="LEFT">dword ptr [rbp - 0xc], 0x7b</TD><TD></TD></TR><TR><TD ALIGN="LEFT">0x004011b0&#58;&nbsp;</TD><TD ALIGN="LEFT">mov</TD><TD ALIGN="LEFT">edi, 0xa</TD><TD></TD></TR><TR><TD ALIGN="LEFT">0x004011b5&#58;&nbsp;</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&#58;&nbsp;</TD><TD ALIGN="LEFT">mov</TD><TD ALIGN="LEFT">qword ptr [rbp - 8], rax</TD><TD></TD></TR><TR><TD ALIGN="LEFT">0x004011be&#58;&nbsp;</TD><TD ALIGN="LEFT">mov</TD><TD ALIGN="LEFT">rax, qword ptr [rbp - 8]</TD><TD></TD></TR><TR><TD ALIGN="LEFT">0x004011c2&#58;&nbsp;</TD><TD ALIGN="LEFT">mov</TD><TD ALIGN="LEFT">dword ptr [rax], 1</TD><TD></TD></TR><TR><TD ALIGN="LEFT">0x004011c8&#58;&nbsp;</TD><TD ALIGN="LEFT">mov</TD><TD ALIGN="LEFT">eax, dword ptr [rbp - 0xc]</TD><TD></TD></TR><TR><TD ALIGN="LEFT">0x004011cb&#58;&nbsp;</TD><TD ALIGN="LEFT">mov</TD><TD ALIGN="LEFT">esi, eax</TD><TD></TD></TR><TR><TD ALIGN="LEFT">0x004011cd&#58;&nbsp;</TD><TD ALIGN="LEFT">lea</TD><TD ALIGN="LEFT">rdi, [rip + 0x2e6c]</TD><TD></TD></TR><TR><TD ALIGN="LEFT">0x004011d4&#58;&nbsp;</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&#58;&nbsp;</TD><TD ALIGN="LEFT">mov</TD><TD ALIGN="LEFT">rdx, rax</TD><TD></TD></TR><TR><TD ALIGN="LEFT">0x004011dc&#58;&nbsp;</TD><TD ALIGN="LEFT">mov</TD><TD ALIGN="LEFT">rax, qword ptr [rip + 0x2ded]</TD><TD></TD></TR><TR><TD ALIGN="LEFT">0x004011e3&#58;&nbsp;</TD><TD ALIGN="LEFT">mov</TD><TD ALIGN="LEFT">rsi, rax</TD><TD></TD></TR><TR><TD ALIGN="LEFT">0x004011e6&#58;&nbsp;</TD><TD ALIGN="LEFT">mov</TD><TD ALIGN="LEFT">rdi, rdx</TD><TD></TD></TR><TR><TD ALIGN="LEFT">0x004011e9&#58;&nbsp;</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&#58;&nbsp;</TD><TD ALIGN="LEFT">mov</TD><TD ALIGN="LEFT">eax, dword ptr [rbp - 0x10]</TD><TD></TD></TR><TR><TD ALIGN="LEFT">0x004011f1&#58;&nbsp;</TD><TD ALIGN="LEFT">mov</TD><TD ALIGN="LEFT">esi, eax</TD><TD></TD></TR><TR><TD ALIGN="LEFT">0x004011f3&#58;&nbsp;</TD><TD ALIGN="LEFT">lea</TD><TD ALIGN="LEFT">rdi, [rip + 0x2e46]</TD><TD></TD></TR><TR><TD ALIGN="LEFT">0x004011fa&#58;&nbsp;</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&#58;&nbsp;</TD><TD ALIGN="LEFT">mov</TD><TD ALIGN="LEFT">rdx, rax</TD><TD></TD></TR><TR><TD ALIGN="LEFT">0x00401202&#58;&nbsp;</TD><TD ALIGN="LEFT">mov</TD><TD ALIGN="LEFT">rax, qword ptr [rip + 0x2dc7]</TD><TD></TD></TR><TR><TD ALIGN="LEFT">0x00401209&#58;&nbsp;</TD><TD ALIGN="LEFT">mov</TD><TD ALIGN="LEFT">rsi, rax</TD><TD></TD></TR><TR><TD ALIGN="LEFT">0x0040120c&#58;&nbsp;</TD><TD ALIGN="LEFT">mov</TD><TD ALIGN="LEFT">rdi, rdx</TD><TD></TD></TR><TR><TD ALIGN="LEFT">0x0040120f&#58;&nbsp;</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&#58;&nbsp;</TD><TD ALIGN="LEFT">mov</TD><TD ALIGN="LEFT">rax, qword ptr [rbp - 8]</TD><TD></TD></TR><TR><TD ALIGN="LEFT">0x00401218&#58;&nbsp;</TD><TD ALIGN="LEFT">add</TD><TD ALIGN="LEFT">rax, 4</TD><TD></TD></TR><TR><TD ALIGN="LEFT">0x0040121c&#58;&nbsp;</TD><TD ALIGN="LEFT">mov</TD><TD ALIGN="LEFT">dword ptr [rax], 2</TD><TD></TD></TR><TR><TD ALIGN="LEFT">0x00401222&#58;&nbsp;</TD><TD ALIGN="LEFT">mov</TD><TD ALIGN="LEFT">rax, qword ptr [rbp - 8]</TD><TD></TD></TR><TR><TD ALIGN="LEFT">0x00401226&#58;&nbsp;</TD><TD ALIGN="LEFT">mov</TD><TD ALIGN="LEFT">eax, dword ptr [rax]</TD><TD></TD></TR><TR><TD ALIGN="LEFT">0x00401228&#58;&nbsp;</TD><TD ALIGN="LEFT">mov</TD><TD ALIGN="LEFT">esi, eax</TD><TD></TD></TR><TR><TD ALIGN="LEFT">0x0040122a&#58;&nbsp;</TD><TD ALIGN="LEFT">lea</TD><TD ALIGN="LEFT">rdi, [rip + 0x2e0f]</TD><TD></TD></TR><TR><TD ALIGN="LEFT">0x00401231&#58;&nbsp;</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&#58;&nbsp;</TD><TD ALIGN="LEFT">mov</TD><TD ALIGN="LEFT">rdx, rax</TD><TD></TD></TR><TR><TD ALIGN="LEFT">0x00401239&#58;&nbsp;</TD><TD ALIGN="LEFT">mov</TD><TD ALIGN="LEFT">rax, qword ptr [rip + 0x2d90]</TD><TD></TD></TR><TR><TD ALIGN="LEFT">0x00401240&#58;&nbsp;</TD><TD ALIGN="LEFT">mov</TD><TD ALIGN="LEFT">rsi, rax</TD><TD></TD></TR><TR><TD ALIGN="LEFT">0x00401243&#58;&nbsp;</TD><TD ALIGN="LEFT">mov</TD><TD ALIGN="LEFT">rdi, rdx</TD><TD></TD></TR><TR><TD ALIGN="LEFT">0x00401246&#58;&nbsp;</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&#58;&nbsp;</TD><TD ALIGN="LEFT">mov</TD><TD ALIGN="LEFT">rax, qword ptr [rbp - 8]</TD><TD></TD></TR><TR><TD ALIGN="LEFT">0x0040124f&#58;&nbsp;</TD><TD ALIGN="LEFT">add</TD><TD ALIGN="LEFT">rax, 4</TD><TD></TD></TR><TR><TD ALIGN="LEFT">0x00401253&#58;&nbsp;</TD><TD ALIGN="LEFT">mov</TD><TD ALIGN="LEFT">eax, dword ptr [rax]</TD><TD></TD></TR><TR><TD ALIGN="LEFT">0x00401255&#58;&nbsp;</TD><TD ALIGN="LEFT">mov</TD><TD ALIGN="LEFT">esi, eax</TD><TD></TD></TR><TR><TD ALIGN="LEFT">0x00401257&#58;&nbsp;</TD><TD ALIGN="LEFT">lea</TD><TD ALIGN="LEFT">rdi, [rip + 0x2de2]</TD><TD></TD></TR><TR><TD ALIGN="LEFT">0x0040125e&#58;&nbsp;</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&#58;&nbsp;</TD><TD ALIGN="LEFT">mov</TD><TD ALIGN="LEFT">rdx, rax</TD><TD></TD></TR><TR><TD ALIGN="LEFT">0x00401266&#58;&nbsp;</TD><TD ALIGN="LEFT">mov</TD><TD ALIGN="LEFT">rax, qword ptr [rip + 0x2d63]</TD><TD></TD></TR><TR><TD ALIGN="LEFT">0x0040126d&#58;&nbsp;</TD><TD ALIGN="LEFT">mov</TD><TD ALIGN="LEFT">rsi, rax</TD><TD></TD></TR><TR><TD ALIGN="LEFT">0x00401270&#58;&nbsp;</TD><TD ALIGN="LEFT">mov</TD><TD ALIGN="LEFT">rdi, rdx</TD><TD></TD></TR><TR><TD ALIGN="LEFT">0x00401273&#58;&nbsp;</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&#58;&nbsp;</TD><TD ALIGN="LEFT">mov</TD><TD ALIGN="LEFT">eax, 0</TD><TD></TD></TR><TR><TD ALIGN="LEFT">0x0040127d&#58;&nbsp;</TD><TD ALIGN="LEFT">leave</TD><TD></TD><TD></TD></TR><TR><TD ALIGN="LEFT">0x0040127e&#58;&nbsp;</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&#58;&nbsp;</TD><TD ALIGN="LEFT">push</TD><TD ALIGN="LEFT">rbp</TD><TD></TD></TR><TR><TD ALIGN="LEFT">0x00401280&#58;&nbsp;</TD><TD ALIGN="LEFT">mov</TD><TD ALIGN="LEFT">rbp, rsp</TD><TD></TD></TR><TR><TD ALIGN="LEFT">0x00401283&#58;&nbsp;</TD><TD ALIGN="LEFT">sub</TD><TD ALIGN="LEFT">rsp, 0x10</TD><TD></TD></TR><TR><TD ALIGN="LEFT">0x00401287&#58;&nbsp;</TD><TD ALIGN="LEFT">mov</TD><TD ALIGN="LEFT">dword ptr [rbp - 4], edi</TD><TD></TD></TR><TR><TD ALIGN="LEFT">0x0040128a&#58;&nbsp;</TD><TD ALIGN="LEFT">mov</TD><TD ALIGN="LEFT">dword ptr [rbp - 8], esi</TD><TD></TD></TR><TR><TD ALIGN="LEFT">0x0040128d&#58;&nbsp;</TD><TD ALIGN="LEFT">cmp</TD><TD ALIGN="LEFT">dword ptr [rbp - 4], 1</TD><TD></TD></TR><TR><TD ALIGN="LEFT">0x00401291&#58;&nbsp;</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&#58;&nbsp;</TD><TD ALIGN="LEFT">cmp</TD><TD ALIGN="LEFT">dword ptr [rbp - 8], 0xffff</TD><TD></TD></TR><TR><TD ALIGN="LEFT">0x0040129a&#58;&nbsp;</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&#58;&nbsp;</TD><TD ALIGN="LEFT">lea</TD><TD ALIGN="LEFT">rdi, [rip + 0x2eae]</TD><TD></TD></TR><TR><TD ALIGN="LEFT">0x004012a3&#58;&nbsp;</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&#58;&nbsp;</TD><TD ALIGN="LEFT">lea</TD><TD ALIGN="LEFT">rdx, [rip + 0x2d59]</TD><TD></TD></TR><TR><TD ALIGN="LEFT">0x004012af&#58;&nbsp;</TD><TD ALIGN="LEFT">lea</TD><TD ALIGN="LEFT">rsi, [rip + 0x2e9b]</TD><TD></TD></TR><TR><TD ALIGN="LEFT">0x004012b6&#58;&nbsp;</TD><TD ALIGN="LEFT">mov</TD><TD ALIGN="LEFT">rax, qword ptr [rip + 0x2d3b]</TD><TD></TD></TR><TR><TD ALIGN="LEFT">0x004012bd&#58;&nbsp;</TD><TD ALIGN="LEFT">mov</TD><TD ALIGN="LEFT">rdi, rax</TD><TD></TD></TR><TR><TD ALIGN="LEFT">0x004012c0&#58;&nbsp;</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&#58;&nbsp;</TD><TD ALIGN="LEFT">nop</TD><TD></TD><TD></TD></TR><TR><TD ALIGN="LEFT">0x004012c6&#58;&nbsp;</TD><TD ALIGN="LEFT">leave</TD><TD></TD><TD></TD></TR><TR><TD ALIGN="LEFT">0x004012c7&#58;&nbsp;</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&#58;&nbsp;</TD><TD ALIGN="LEFT">push</TD><TD ALIGN="LEFT">rbp</TD><TD></TD></TR><TR><TD ALIGN="LEFT">0x004012c9&#58;&nbsp;</TD><TD ALIGN="LEFT">mov</TD><TD ALIGN="LEFT">rbp, rsp</TD><TD></TD></TR><TR><TD ALIGN="LEFT">0x004012cc&#58;&nbsp;</TD><TD ALIGN="LEFT">mov</TD><TD ALIGN="LEFT">esi, 0xffff</TD><TD></TD></TR><TR><TD ALIGN="LEFT">0x004012d1&#58;&nbsp;</TD><TD ALIGN="LEFT">mov</TD><TD ALIGN="LEFT">edi, 1</TD><TD></TD></TR><TR><TD ALIGN="LEFT">0x004012d6&#58;&nbsp;</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&#58;&nbsp;</TD><TD ALIGN="LEFT">pop</TD><TD ALIGN="LEFT">rbp</TD><TD></TD></TR><TR><TD ALIGN="LEFT">0x004012dc&#58;&nbsp;</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&#58;&nbsp;</TD><TD ALIGN="LEFT">endbr64</TD><TD></TD><TD></TD></TR><TR><TD ALIGN="LEFT">0x004012e4&#58;&nbsp;</TD><TD ALIGN="LEFT">push</TD><TD ALIGN="LEFT">r15</TD><TD></TD></TR><TR><TD ALIGN="LEFT">0x004012e6&#58;&nbsp;</TD><TD ALIGN="LEFT">lea</TD><TD ALIGN="LEFT">r15, [rip + 0x2a83]</TD><TD></TD></TR><TR><TD ALIGN="LEFT">0x004012ed&#58;&nbsp;</TD><TD ALIGN="LEFT">push</TD><TD ALIGN="LEFT">r14</TD><TD></TD></TR><TR><TD ALIGN="LEFT">0x004012ef&#58;&nbsp;</TD><TD ALIGN="LEFT">mov</TD><TD ALIGN="LEFT">r14, rdx</TD><TD></TD></TR><TR><TD ALIGN="LEFT">0x004012f2&#58;&nbsp;</TD><TD ALIGN="LEFT">push</TD><TD ALIGN="LEFT">r13</TD><TD></TD></TR><TR><TD ALIGN="LEFT">0x004012f4&#58;&nbsp;</TD><TD ALIGN="LEFT">mov</TD><TD ALIGN="LEFT">r13, rsi</TD><TD></TD></TR><TR><TD ALIGN="LEFT">0x004012f7&#58;&nbsp;</TD><TD ALIGN="LEFT">push</TD><TD ALIGN="LEFT">r12</TD><TD></TD></TR><TR><TD ALIGN="LEFT">0x004012f9&#58;&nbsp;</TD><TD ALIGN="LEFT">mov</TD><TD ALIGN="LEFT">r12d, edi</TD><TD></TD></TR><TR><TD ALIGN="LEFT">0x004012fc&#58;&nbsp;</TD><TD ALIGN="LEFT">push</TD><TD ALIGN="LEFT">rbp</TD><TD></TD></TR><TR><TD ALIGN="LEFT">0x004012fd&#58;&nbsp;</TD><TD ALIGN="LEFT">lea</TD><TD ALIGN="LEFT">rbp, [rip + 0x2a7c]</TD><TD></TD></TR><TR><TD ALIGN="LEFT">0x00401304&#58;&nbsp;</TD><TD ALIGN="LEFT">push</TD><TD ALIGN="LEFT">rbx</TD><TD></TD></TR><TR><TD ALIGN="LEFT">0x00401305&#58;&nbsp;</TD><TD ALIGN="LEFT">sub</TD><TD ALIGN="LEFT">rbp, r15</TD><TD></TD></TR><TR><TD ALIGN="LEFT">0x00401308&#58;&nbsp;</TD><TD ALIGN="LEFT">sub</TD><TD ALIGN="LEFT">rsp, 8</TD><TD></TD></TR><TR><TD ALIGN="LEFT">0x0040130c&#58;&nbsp;</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&#58;&nbsp;</TD><TD ALIGN="LEFT">sar</TD><TD ALIGN="LEFT">rbp, 3</TD><TD></TD></TR><TR><TD ALIGN="LEFT">0x00401315&#58;&nbsp;</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&#58;&nbsp;</TD><TD ALIGN="LEFT">xor</TD><TD ALIGN="LEFT">ebx, ebx</TD><TD></TD></TR><TR><TD ALIGN="LEFT">0x00401319&#58;&nbsp;</TD><TD ALIGN="LEFT">nop</TD><TD ALIGN="LEFT">dword ptr [rax]</TD><TD></TD></TR><TR><TD ALIGN="LEFT">0x00401320&#58;&nbsp;</TD><TD ALIGN="LEFT">mov</TD><TD ALIGN="LEFT">rdx, r14</TD><TD></TD></TR><TR><TD ALIGN="LEFT">0x00401323&#58;&nbsp;</TD><TD ALIGN="LEFT">mov</TD><TD ALIGN="LEFT">rsi, r13</TD><TD></TD></TR><TR><TD ALIGN="LEFT">0x00401326&#58;&nbsp;</TD><TD ALIGN="LEFT">mov</TD><TD ALIGN="LEFT">edi, r12d</TD><TD></TD></TR><TR><TD ALIGN="LEFT">0x00401329&#58;&nbsp;</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&#58;&nbsp;</TD><TD ALIGN="LEFT">mov</TD><TD ALIGN="LEFT">rdx, r14</TD><TD></TD></TR><TR><TD ALIGN="LEFT">0x00401323&#58;&nbsp;</TD><TD ALIGN="LEFT">mov</TD><TD ALIGN="LEFT">rsi, r13</TD><TD></TD></TR><TR><TD ALIGN="LEFT">0x00401326&#58;&nbsp;</TD><TD ALIGN="LEFT">mov</TD><TD ALIGN="LEFT">edi, r12d</TD><TD></TD></TR><TR><TD ALIGN="LEFT">0x00401329&#58;&nbsp;</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&#58;&nbsp;</TD><TD ALIGN="LEFT">add</TD><TD ALIGN="LEFT">rbx, 1</TD><TD></TD></TR><TR><TD ALIGN="LEFT">0x00401331&#58;&nbsp;</TD><TD ALIGN="LEFT">cmp</TD><TD ALIGN="LEFT">rbp, rbx</TD><TD></TD></TR><TR><TD ALIGN="LEFT">0x00401334&#58;&nbsp;</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&#58;&nbsp;</TD><TD ALIGN="LEFT">add</TD><TD ALIGN="LEFT">rsp, 8</TD><TD></TD></TR><TR><TD ALIGN="LEFT">0x0040133a&#58;&nbsp;</TD><TD ALIGN="LEFT">pop</TD><TD ALIGN="LEFT">rbx</TD><TD></TD></TR><TR><TD ALIGN="LEFT">0x0040133b&#58;&nbsp;</TD><TD ALIGN="LEFT">pop</TD><TD ALIGN="LEFT">rbp</TD><TD></TD></TR><TR><TD ALIGN="LEFT">0x0040133c&#58;&nbsp;</TD><TD ALIGN="LEFT">pop</TD><TD ALIGN="LEFT">r12</TD><TD></TD></TR><TR><TD ALIGN="LEFT">0x0040133e&#58;&nbsp;</TD><TD ALIGN="LEFT">pop</TD><TD ALIGN="LEFT">r13</TD><TD></TD></TR><TR><TD ALIGN="LEFT">0x00401340&#58;&nbsp;</TD><TD ALIGN="LEFT">pop</TD><TD ALIGN="LEFT">r14</TD><TD></TD></TR><TR><TD ALIGN="LEFT">0x00401342&#58;&nbsp;</TD><TD ALIGN="LEFT">pop</TD><TD ALIGN="LEFT">r15</TD><TD></TD></TR><TR><TD ALIGN="LEFT">0x00401344&#58;&nbsp;</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&#58;&#58;ostream&#58;&#58;operator&#60;&#60;(std&#58;&#58;ostream&amp; (std&#58;&#58;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&#58;&#58;ostream&#58;&#58;operator&#60;&#60;(std&#58;&#58;ostream&amp; (std&#58;&#58;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&#58;&#58;ostream&#58;&#58;operator&#60;&#60;(std&#58;&#58;ostream&amp; (std&#58;&#58;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&#58;&#58;ostream&#58;&#58;operator&#60;&#60;(std&#58;&#58;ostream&amp; (std&#58;&#58;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&#58;&#58;ios_base&#58;&#58;Init&#58;&#58;&#123;ctor&#125;()</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&#58;&#58;ostream&#58;&#58;operator&#60;&#60;(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&#58;&#58;ostream&#58;&#58;operator&#60;&#60;(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&#58;&#58;ostream&#58;&#58;operator&#60;&#60;(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&#58;&#58;ostream&#58;&#58;operator&#60;&#60;(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