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 依序就是程式載入位置,與指令集架構等等

code
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

code
// 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 腳本

code
# 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

code
  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也有可能是一個位置

code
  for stmt in bb.vex.statements:
    print(stmt.pp())
  print(bb.pp())

多虧angr我就可以直接從bianry 去取得 該basic block 的stmt

code
    print(bb.vex)

也可以取得較為漂亮的輸出,這會輸出這個basic block 相對應的程式碼vex ir

code
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
}
code
  print(bb.vex.pp())
code
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

code
  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))
code
<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進行過濾

code
  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))
code
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 我們只是帶過

code
  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()

code
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 蠻麻煩,退出又要重裝了

code
vim /home/angr/.virtualenvs/angr/lib/python3.8/site-packages/pydot.py

裝完環境後我們直接修改

code
  print(tmp_dir+tmp_name)

在我們的分析器加上這個

code
plot_cfg(cfg, "ais3_cfg",format="dot", asminst=True, remove_imports=True, remove_path_terminator=True)  

我們直接倒出dot

code
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"]
}

可以實際觀察到,跟一般compiler 的cfg確實不太一樣,不過概念應該差不多,由此可以看到整個程式的call graph

那麼當今天我們假設要進行program slicing,在一堆程式碼中切出有可能會經過的程式碼片段,再進行分析

angr Backward Slicing

https://docs.angr.io/built-in-analyses/backward_slice 一開始以為可以靜態的去切割,實際上好像也是需要透過angr去模擬才行 那麼在讓我們程式碼在整齊一點

code
// 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;
}
code
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來說我們可能要找到跟某些程式碼片段大概要經過哪些步驟呢

code
    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

code
    # 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 的片段中,某一些參數要切割的就標註起來

code
    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進行找尋

code
    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呼叫看看

code
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

code
---------------
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

code
  bs_targets = [(target_call_node, 5)] # 05 | PUT(rdi) = t3 # (moving buf into rdi as a parameter for f_target(...))

如果推論的正確這些+,-將是切割出來的程式碼片段

code
   # 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來看下

對應 vex ir

code
-[ 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 的靜態檢測應該可以,只不過在

code
    // buf[1] = 'a';
    // buf[2] = 'd';
    // buf[3] = 's';
    // buf[4] = 'w';
    f_target(buf);
    buf[3] = 's';<===檢測不到

    return 0;
}

code
void f2(char buf[])
{
    buf[0] = 'a';
    buf[1] = '\0';
    // f_target(buf);
}

這種跨fucntion,和執行順序的,靜態分析就好像就不太有辦法做切割,如果真的能切割出程式碼片段,其實我們可以得到stmt到底遍佈在那些地方,我們就可以用這些information進行更加抽象的分析,valgrind在某些程式碼片段是沒辦法進行檢測的, 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