Angr學習(5)

Misaka10046發表於2020-10-21

低階記憶體介面

>>> proj.memory.store(0x4000,proj.solver.BVV(0x12345678,64))
>>> proj.memory.load
<bound method SimSymbolicMemory.load of <angr.state_plugins.symbolic_memory.SimSymbolicMemory object at 0x7f29b0fbac10>>
>>> proj.memory.load(0x4000)//進行記憶體的儲存讀取操作
<BV64 0x12345678>
>>> proj.arch.memory_endness//看是大段序還是小端序
'Iend_LE'

基礎執行

>>> proj.step//當前的程式的位置
<bound method SimState.step of <SimState @ 0x400610>>
>>> proj.step()//返回當前執行到下一個分支有幾種情況
<IRSB from 0x400610: 1 sat>
>>> proj.step().successors[0]
<SimState @ 0x4005d0>
>>> proj.step().successors//successors包含了程式接下來執行所有的可能性的列表
[<SimState @ 0x4005d0>]

在這裡插入圖片描述
發現跳轉記錄的分支與程式一致。

在這裡插入圖片描述
剛剛那個只有一個分支的,現在找有兩個分支的

>>> while 1:
...     h = proj.step()
...     if len(h.successors) == 2:
...             break
...     proj = h.successors[0]
... 
>>> h.successors
[<SimState @ 0x1117a47>, <SimState @ 0x1117a88>]
>>> h.successors[0].solver.constraints
[<Bool syscall_stub_ptrace_6_64 <= 0xfffffffffffff000>]
>>> h.successors[1].solver.constraints
[<Bool syscall_stub_ptrace_6_64 > 0xfffffffffffff000>]

通過這個能很明顯的看出符號執行的原理,遇到判斷的時候,我們會產生兩個完全分開的狀態——一個用於模擬條件為真,另一個用於模擬條件為假,然後在第一個狀態中,我們新增<= 0xfffffffffffff000為約束條件,而在第二個狀態中,我們新增> 0xfffffffffffff000為約束條件。這樣的話就能確保程式把所有路徑都跑一遍從而找出正確的那個。

history外掛

>>> for addr in proj.history.bbl_addrs: //接著上面的,history裡面記錄一個狀態的執行路徑,就是一個連結串列,bbl_addrs中是state已經執行過的基本塊的地址列表
...   print hex(addr)
... 
0x400610L
0x4005d0L
0x1021ab0L
0x400890L
0x400560L
0x400575L
0x4008c3L
0x4008c8L
0x4006d0L
0x4006f8L
0x400670L
0x400692L
0x4008ddL
0x4008d0L
0x4007a8L
0x400590L
0x1042790L
0x1021100L
0x10b1690L
0x10b16b6L
0x10b16c6L
0x10427a6L
0x1042860L
0x10427f6L
0x4007bbL
0x4007c1L
0x400600L
0x11179e0L
0x1117a3fL
>>> proj.history.recent_bbl_addrs
[17922623L]
>>> proj.history.descriptions
<angr.state_plugins.history.LambdaAttrIter object at 0x7f29b116cd50>
>>> proj.history.descriptions.hardcopy//描述state上每輪執行的狀態的字串列表
['<IRSB from 0x400610: 1 sat>', '<IRSB from 0x4005d0: 1 sat>', '<SimProcedure __libc_start_main from 0x1021ab0: 1 sat>', '<IRSB from 0x400890: 1 sat>', '<IRSB from 0x400560: 1 sat 1 unsat>', '<IRSB from 0x400575: 1 sat>', '<IRSB from 0x4008c3: 1 sat 1 unsat>', '<IRSB from 0x4008c8: 1 sat>', '<IRSB from 0x4006d0: 1 sat 1 unsat>', '<IRSB from 0x4006f8: 1 sat>', '<IRSB from 0x400670: 1 sat 1 unsat>', '<IRSB from 0x400692: 1 sat>', '<IRSB from 0x4008dd: 1 sat 1 unsat>', '<IRSB from 0x4008d0: 1 sat>', '<IRSB from 0x4007a8: 1 sat>', '<IRSB from 0x400590: 1 sat>', '<IRSB from 0x1042790: 1 sat>', '<IRSB from 0x1021100: 1 sat>', '<IRSB from 0x10b1690: 1 sat 1 unsat>', '<IRSB from 0x10b16b6: 1 sat 1 unsat>', '<IRSB from 0x10b16c6: 1 sat>', '<IRSB from 0x10427a6: 1 sat 1 unsat>', '<IRSB from 0x1042860: 1 sat>', '<IRSB from 0x10427f6: 1 sat>', '<IRSB from 0x4007bb: 1 sat 1 unsat>', '<IRSB from 0x4007c1: 1 sat>', '<IRSB from 0x400600: 1 sat>', '<IRSB from 0x11179e0: 1 sat>', '<SimProcedure ptrace (syscall) (stub) from 0x1117a3f: 1 sat>']
>>> proj.history.bbl_addrs.hardcopy
[4195856L, 4195792L, 16915120L, 4196496L, 4195680L, 4195701L, 4196547L, 4196552L, 4196048L, 4196088L, 4195952L, 4195986L, 4196573L, 4196560L, 4196264L, 4195728L, 17049488L, 16912640L, 17503888L, 17503926L, 17503942L, 17049510L, 17049696L, 17049590L, 4196283L, 4196289L, 4195840L, 17922528L, 17922623L]//獲取這些值的平面列表
>>> proj.history.jumpkinds
<angr.state_plugins.history.LambdaAttrIter object at 0x7f29b116cd50>
>>> proj.history.jumpkinds.hardcopy
['Ijk_Boring', 'Ijk_Call', 'Ijk_Boring', 'Ijk_Call', 'Ijk_Call', 'Ijk_Boring', 'Ijk_Ret', 'Ijk_Boring', 'Ijk_Call', 'Ijk_Boring', 'Ijk_Boring', 'Ijk_Boring', 'Ijk_Ret', 'Ijk_Boring', 'Ijk_Call', 'Ijk_Call', 'Ijk_Boring', 'Ijk_Call', 'Ijk_Boring', 'Ijk_Boring', 'Ijk_Boring', 'Ijk_Ret', 'Ijk_Boring', 'Ijk_Boring', 'Ijk_Ret', 'Ijk_Boring', 'Ijk_Call', 'Ijk_Boring', 'Ijk_Sys_syscall', 'Ijk_Ret']

Ijk_Boring:就是一個正常的跳轉
Ijk_Call:用call的形式的跳轉
Ijk_Ret:return形式的跳轉
Ijk_Sys_syscall:系統呼叫
Ijk_NoHook:跳到angrHook了的地方

>>> proj.history.events
<angr.state_plugins.history.LambdaIterIter object at 0x7f29b116ccd0>
>>> proj.history.events.hardcopy//記錄檔案執行中的一些操作的列表
[<SimActionData __libc_start_main() reg/read>, <SimActionData __libc_start_main() reg/read>, <SimActionData __libc_start_main() reg/read>, <SimActionData __libc_start_main() reg/read>, <SimActionData __libc_start_main() reg/read>, <SimActionData __libc_start_main() reg/read>, <SimActionData __libc_start_main() reg/write>, <SimActionData __libc_start_main() reg/read>, <SimActionData __libc_start_main() reg/write>, <SimActionData __libc_start_main() reg/read>, <SimActionData __libc_start_main() reg/read>, <SimActionData __libc_start_main() reg/write>, <SimActionData __libc_start_main() reg/write>, <SimActionData __libc_start_main() reg/write>, <SimActionData __libc_start_main() reg/write>, <SimActionData __libc_start_main() reg/read>, <SimActionData __libc_start_main() mem/write>, <SimActionData __libc_start_main() reg/write>, <SimActionData __libc_start_main() mem/read>, <SimEvent unconstrained 20, with fields ['bits', 'name']>, <SimEvent uninitialized 21, with fields ['memory_id', 'addr', 'size']>, <SimEvent unconstrained 22, with fields ['bits', 'name']>, <SimEvent uninitialized 23, with fields ['memory_id', 'addr', 'size']>, <SimEvent unconstrained 24, with fields ['bits', 'name']>, <SimEvent uninitialized 25, with fields ['memory_id', 'addr', 'size']>, <SimEvent unconstrained 26, with fields ['bits', 'name']>, <SimEvent uninitialized 27, with fields ['memory_id', 'addr', 'size']>, <SimEvent unconstrained 28, with fields ['bits', 'name']>, <SimEvent uninitialized 29, with fields ['memory_id', 'addr', 'size']>, <SimEvent unconstrained 30, with fields ['bits', 'name']>, <SimEvent uninitialized 31, with fields ['memory_id', 'addr', 'size']>, <SimEvent unconstrained 32, with fields ['bits', 'name']>, <SimActionData ptrace() reg/write>, <SimActionData ptrace() reg/read>, <SimActionData ptrace() reg/read>, <SimActionData ptrace() reg/write>, <SimActionData ptrace() reg/write>]
>>> proj.history.actions
<angr.state_plugins.history.LambdaIterIter object at 0x7f29b116cc10>
>>> proj.history.actions.hardcopy
[<SimActionData __libc_start_main() reg/read>, <SimActionData __libc_start_main() reg/read>, <SimActionData __libc_start_main() reg/read>, <SimActionData __libc_start_main() reg/read>, <SimActionData __libc_start_main() reg/read>, <SimActionData __libc_start_main() reg/read>, <SimActionData __libc_start_main() reg/write>, <SimActionData __libc_start_main() reg/read>, <SimActionData __libc_start_main() reg/write>, <SimActionData __libc_start_main() reg/read>, <SimActionData __libc_start_main() reg/read>, <SimActionData __libc_start_main() reg/write>, <SimActionData __libc_start_main() reg/write>, <SimActionData __libc_start_main() reg/write>, <SimActionData __libc_start_main() reg/write>, <SimActionData __libc_start_main() reg/read>, <SimActionData __libc_start_main() mem/write>, <SimActionData __libc_start_main() reg/write>, <SimActionData __libc_start_main() mem/read>, <SimActionData ptrace() reg/write>, <SimActionData ptrace() reg/read>, <SimActionData ptrace() reg/read>, <SimActionData ptrace() reg/write>, <SimActionData ptrace() reg/write>]//填充程式對所有記憶體、暫存器、臨時值訪問的日誌

觀察棧幀

>>> for i in proj.callstack: //只能用迭代器的方法來打出這些棧裡面的值
...     print i
... 
Backtrace:
Frame 0: 0x4007c1 => 0x400600, sp = 0x7fffffffffeff28
Frame 1: 0x4008d0 => 0x4007a8, sp = 0x7fffffffffeff38
Frame 2: 0x1021ab0 => 0x400890, sp = 0x7fffffffffeff78
Frame 3: 0x400610 => 0x4005d0, sp = 0x7fffffffffeff88
Frame 4: 0x0 => 0x0, sp = 0xffffffffffffffff
Backtrace:
Frame 0: 0x4008d0 => 0x4007a8, sp = 0x7fffffffffeff38
Frame 1: 0x1021ab0 => 0x400890, sp = 0x7fffffffffeff78
Frame 2: 0x400610 => 0x4005d0, sp = 0x7fffffffffeff88
Frame 3: 0x0 => 0x0, sp = 0xffffffffffffffff
Backtrace:
Frame 0: 0x1021ab0 => 0x400890, sp = 0x7fffffffffeff78
Frame 1: 0x400610 => 0x4005d0, sp = 0x7fffffffffeff88
Frame 2: 0x0 => 0x0, sp = 0xffffffffffffffff
Backtrace:
Frame 0: 0x400610 => 0x4005d0, sp = 0x7fffffffffeff88
Frame 1: 0x0 => 0x0, sp = 0xffffffffffffffff
Backtrace:
Frame 0: 0x0 => 0x0, sp = 0xffffffffffffffff
>>> proj.callstack//觀察棧裡面的值
<CallStack (depth 5)>
>>> proj.callstack[0]
<CallStack (depth 5)>
>>> proj.callstack[1]
<CallStack (depth 4)>
>>> proj.callstack[2]
<CallStack (depth 3)>
>>> proj.callstack.func_addr//函式的開始地址
4195840L
>>> proj.callstack.call_site_addr//呼叫當前函式的基本塊地址
4196289L
>>> hex(proj.callstack.stack_ptr)//當前函式的棧頂指標
'0x7fffffffffeff28L'
>>> hex(proj.callstack.ret_addr)//當前函式的返回地址
'0x4007dfL'