def successors(self, *args, **kwargs):
"""
Perform execution using any applicable engine. Enumerate the current engines and use the
first one that works. Return a SimSuccessors object classifying the results of the run.
:param state: The state to analyze
:param addr: optional, an address to execute at instead of the state's ip
:param jumpkind: optional, the jumpkind of the previous exit
:param inline: This is an inline execution. Do not bother copying the state.
Additional keyword arguments will be passed directly into each engine's process method.
"""
return self.project.engines.successors(*args, **kwargs)
所以實際上,最終調用的是engines中的successors()函數對狀態進行操作。因此,通過深入研究engines可以瞭解angr是如何操作states對程序進行模擬執行的。
(這裏有個問題,現在還沒想明白:爲什麼調用的是engines.successors,在successors的初始化函數中,並沒有調用engines.process方法,但是參數最終都會傳給process方法,那麼從哪裏調用的process呢???)
下面是SimEngine的一些方法。
process
(state, *args, **kwargs)
執行一個狀態。
我們只在子類裏面重寫此方法以提供正確的方法簽名和文檔。我們應該重寫_prcess方法來進行實際的執行操作。
參數:
state -將要執行的狀態。這個在修改前被複制。
inline -這是一個內聯執行。不影響複製狀態。
force_addr -強制執行,假裝我們正在這個具體地址運行。
返回值:一個SimSuccessors對象對執行的successor狀態進行分類。
check
(state, *args, **kwargs)
檢查此引擎是否可用於在當前狀態下執行。回調check_failure在失敗的檢查時被調用。請注意,即使check()返回True,執行仍可能失敗。您只應在子類中重寫此方法以提供正確的方法簽名和文檔字符串。您應該重寫_check方法來執行您的實際執行。
參數:
state(SimState) - 要執行的狀態。
args - 將傳遞給process()的位置參數。
kwargs - 將傳遞給process()的關鍵字參數。
返回:如果狀態可以由當前引擎處理,則爲真,否則爲False。
從代碼中可以看出,SimEngine是一個父類(基類),那麼真正的引擎有一下幾種,它們都重寫了SimEngine類的check方法和process方法。
vex_preset.add_default_plugin('unicorn', SimEngineUnicorn)
vex_preset.add_default_plugin('failure', SimEngineFailure)
vex_preset.add_default_plugin('syscall', SimEngineSyscall)
vex_preset.add_default_plugin('hook', SimEngineHook)
vex_preset.add_default_plugin(' ', SimEngineVEX)
vex_preset.add_default_plugin('procedure_engine', SimEngineProcedure)
下面先主要介紹SimEngineVEX和SimSimEngineUnicorn。
1. SimEngineVEX
基於VEX,Valgrind的IR的執行引擎。
process
(state, irsb=None, skip_stmts=0, last_stmt=99999999, whitelist=None, inline=False, force_addr=None, insn_bytes=None, size=None, num_inst=None, traceflags=0, thumb=False, opt_level=None, **kwargs)
參數:
state - 執行的狀態
irsb - 用於執行的PyVEX IRSB對象。如果沒有提供,將被解除。
skip_stmts - 處理中跳過的語句數
last_stmt - 在此語句後不要執行任何語句
whitelist - 僅在此組中執行語句
inline - 這是一個內聯執行。不打擾複製狀態。
force_addr - 強制執行,假裝我們正在這個具體地址工作
thumb - 是否應該在ARM的THUMB模式下解除塊。
opt_level - 要使用的VEX優化級別。
insn_bytes - 用於塊而不是project的字節串。
size - 塊的最大大小,以字節爲單位。
num_inst - 指令的最大數量。
traceflags - traceflags傳遞給VEX。 (默認:0)
返回:
SimSuccessors對象對塊的successors進行分類
lift
(state=None, clemory=None, insn_bytes=None, arch=None, addr=None, size=None, num_inst=None, traceflags=0, thumb=False, opt_level=None)
lift an IRSB。
有許多可能的有效參數組。您至少必須傳遞一些數據源,一些架構源和一些地址源。
數據源按優先級順序排列:insn_bytes,clemory,state
地址源,按優先級順序排列:地址addr,狀態state
架構源,按照優先順序排列:arch,clemory,state
參數:
state - 用作數據源的狀態。
clemory - 用作數據源的cle.memory.Clemory對象。
addr - 啓動塊的地址。
thumb - 是否應該在ARM的THUMB模式下解除塊。
opt_level - 要使用的VEX優化級別。最終的IR優化級別由(按優先級排序)確定: - 參數opt_level - 如果狀態選項中存在OPTIMIZE_IR,則opt_level設置爲1 - self._default_opt_level
insn_bytes - 用作數據源的字節字符串。
size - 塊的最大大小,以字節爲單位。
num_inst - 指令的最大數量。
traceflags - traceflags傳遞給VEX。(默認:0)
2.SimEngineUnicorn
Unicorn引擎中的具體執行,qemu的一個分支。
process
(state, step=None, extra_stop_points=None, inline=False, force_addr=None, **kwargs)
參數:
state - 執行的狀態
step - 我們要執行多少個基本塊
extra_stop_points - 執行應該暫停的地址集合
inline - 這是一個內聯執行。 不要打擾複製狀態。
force_addr - 強制執行,假裝我們正在這個具體地址工作
返回:
SimSuccessors對象將運行結果和它是否成功進行分類。
對於每個引擎的具體執行細節先暫時不探討。只需要知道,執行的邏輯是從process開始的即可。要想深入研究則跟蹤這個函數走下去就行。