angr學習(一)


基本屬性
首先,我們有一些關於這個項目的基本屬性:它的CPU體系結構,文件名以及入口點的地址。
>>> import monkeyhex # this will format numerical results in hexadecimal
>>> proj.arch
<Arch AMD64 (LE)>
>>> proj.entry
0x401670
>>> proj.filename
'/bin/true'
arch是archinfo.Arch對象的一個實例,用於編譯程序的任何體系結構,在本例中是little-endian amd64。它包含大量關於運行的CPU的文書數據,您可以在閑暇時閱讀這些數據。你關心的常見問題是arch.bits,arch.bytes(其中一個是主要Arch類的@property聲明),
arch.name和arch.memory_endness。
entry是二進制的入口點!
filename是二進制文件的絕對文件名
 
 
The loader(加載器)
 
從二進制文件加載到在虛擬地址空間中非常復雜!我們有一個叫CLE的模塊來處理這個問題。 CLE的結果,稱為加載程序,在.loader屬性中可用。我們將詳細介紹如何盡快使用它,
但是現在只要知道你可以用它來查看angr加載程序時同時加載的共享庫,並對加載的地址空間進行基本的查詢。
 
>>> proj.loader
<Loaded true, maps [0x400000:0x5004000]>
 
>>> proj.loader.shared_objects # may look a little different for you!
{'ld-linux-x86-64.so.2': <ELF Object ld-2.24.so, maps [0x2000000:0x2227167]>,
'libc.so.6': <ELF Object libc-2.24.so, maps [0x1000000:0x13c699f]>}
 
>>> proj.loader.min_addr
0x400000
>>> proj.loader.max_addr
0x5004000
 
>>> proj.loader.main_object # we've loaded several binaries into this project. Here's the main one!
<ELF Object true, maps [0x400000:0x60721f]>
 
>>> proj.loader.main_object.execstack # sample query: does this binary have an executable stack?
False
>>> proj.loader.main_object.pic # sample query: is this binary position-independent?
True

 

 
 
The factory
 
Angr中有很多類,其中大部分需要實例化一個項目。而不是讓你到處將項目作為參數傳遞,我們提供project.factory,它有幾個方便的常用對象的構造函數,你會經常使用。
本節還將介紹幾個基本的angr概念。
 
Blocks
 
angr分析代碼是以基本塊(在編譯器構造中,基本塊是一個直線代碼序列,除了入口外沒有分支,除了出口處沒有分支)為單位。
首先,project.factory.block( ),它用來從給定的地址提取一個基本的代碼塊。你將得到一個Block對象,它可以告訴你關於代碼塊的很多有趣的事情:
 
>>> block = proj.factory.block(proj.entry) # lift a block of code from the program's entry point
<Block for 0x401670, 42 bytes>
 
>>> block.pp() # pretty-print a disassembly to stdout
0x401670: xor ebp, ebp
0x401672: mov r9, rdx
0x401675: pop rsi
0x401676: mov rdx, rsp
0x401679: and rsp, 0xfffffffffffffff0
0x40167d: push rax
0x40167e: push rsp
0x40167f: lea r8, [rip + 0x2e2a]
0x401686: lea rcx, [rip + 0x2db3]
0x40168d: lea rdi, [rip - 0xd4]
0x401694: call qword ptr [rip + 0x205866]
 
>>> block.instructions # how many instructions are there?
0xb
>>> block.instruction_addrs # what are the addresses of the instructions?
[0x401670, 0x401672, 0x401675, 0x401676, 0x401679, 0x40167d, 0x40167e, 0x40167f, 0x401686, 0x40168d, 0x401694]
 

 

此外,您可以使用Block對象來獲取代碼塊的其他表示形式:
 
>>> block.capstone # capstone disassembly
<CapstoneBlock for 0x401670>
>>> block.vex # VEX IRSB (that's a python internal address, not a program address)
<pyvex.block.IRSB at 0x7706330>
 

 

 

States

Project對象只代表程序的“初始化映像”。當你用angr執行執行時,使用的是一個代表模擬程序狀態的特定對象 (SimState)。
 
>>> state = proj.factory.entry_state()
<SimState @ 0x401670>

 

一個SimState包含一個程序的內存,寄存器,文件系統數據...任何會在執行中改變的“實時數據”都會在這個state中。稍后我們將介紹如何與狀態進行深入交互,但現在讓我們使用state.regs和state.mem來訪問這個狀態的寄存器和內存:
 
>>> state.regs.rip # get the current instruction pointer
<BV64 0x401670>
>>> state.regs.rax
<BV64 0x1c>
>>> state.mem[proj.entry].int.resolved # interpret the memory at the entry point as a C int
<BV32 0x8949ed31>

 

這里是如何從python ints轉換為bitvectors,然后再返回:
>>> bv = state.solver.BVV(0x1234, 32)        # create a 32-bit-wide bitvector with value 0x1234
<BV32 0x1234>                                # BVV stands for bitvector value
>>> state.solver.eval(bv)                    # convert to python int
0x1234

 

您可以將這些位向量存儲回寄存器和內存,也可以直接存儲一個python整數,並將其轉換為適當大小的位向量:
 
>>> state.regs.rsi = state.solver.BVV(3, 64)
>>> state.regs.rsi
<BV64 0x3>
 
>>> state.mem[0x1000].long = 4
>>> state.mem[0x1000].long.resolved
<BV64 0x4>

 

使用array [index]表示法指定一個地址
使用<type>來指定內存應該被解釋為<type>(通用值:char,short,int,long,size_t,uint8_t,uint16_t ...)
從那里,你可以:
    存儲一個值,無論是一個bitvector或一個python int
    使用.resolved將該值作為bitvector
    使用.concrete將該值作為python int
 
如果嘗試去獲取其他寄存器,可能會遇到看起來很奇怪的值:
>>> state.regs.rdi
<BV64 reg_48_11_64{UNINITIALIZED}>
它仍舊是一個64bit 的bitvector,但它不包含一個數值,而是一個名稱,叫做symbolic variable(符號變量),它是符號執行的基礎。
 
 
Simulation Managers(模擬化管理器)
 
如果一個state表示處在某個時間點的程序,那么一定會有方法使它達到下一個時間點。Simulation Manager是angr中的主要接口,用於進行執行或者說模擬。
 
首先,我們創建simulation manager,
>>> simgr = proj.factory.simgr(state) # TODO: change name before merge
<SimulationManager with 1 active>
>>> simgr.active
[<SimState @ 0x401670>]

 

造函數會參數一個state或state列表。
 
 
simulation manager含有幾個stash,默認的stash,active,由傳入的state初始化。
 
我們開始執行
>>> simgr.step()
 
可以再次查看存活的stash,注意到它已經改變,而且這並不會修改原來的state,SimState對象在執行過程中透明。可以安全的使用單個state作為任意一次執行的起點。
>>> simgr.active
[<SimState @ 0x1020300>]
>>> simgr.active[0].regs.rip # new and exciting!
<BV64 0x1020300>
>>> state.regs.rip # still the same!
<BV64 0x401670>

 

 
 
Analyses
 
angr預先打包了幾個內置analyses,可以利用它們來獲取程序中一些有趣的信息:
>>> proj.analyses. # Press TAB here in ipython to get an autocomplete-listing of everything:
proj.analyses.BackwardSlice        proj.analyses.CongruencyCheck        proj.analyses.reload_analyses
proj.analyses.BinaryOptimizer      proj.analyses.DDG                    proj.analyses.StaticHooker
proj.analyses.BinDiff              proj.analyses.DFG                    proj.analyses.VariableRecovery
proj.analyses.BoyScout             proj.analyses.Disassembly            proj.analyses.VariableRecoveryFast
proj.analyses.CDG                  proj.analyses.GirlScout              proj.analyses.Veritesting
proj.analyses.CFG                  proj.analyses.Identifier             proj.analyses.VFG
proj.analyses.CFGAccurate          proj.analyses.LoopFinder             proj.analyses.VSA_DDG
proj.analyses.CFGFast              proj.analyses.Reassembler

 

 
如何構建並使用一個快速控制流程圖:
# Originally, when we loaded this binary it also loaded all its dependencies into the same virtual address space
# This is undesirable for most analysis.
>>> proj = angr.Project('/bin/true', auto_load_libs=False)
>>> cfg = proj.analyses.CFGFast()
<CFGFast Analysis Result at 0x2d85130>
 
# cfg.graph is a networkx DiGraph full of CFGNode instances
# You should go look up the networkx APIs to learn how to use this!
>>> cfg.graph
<networkx.classes.digraph.DiGraph at 0x2da43a0>
>>> len(cfg.graph.nodes())
951
 
# To get the CFGNode for a given address, use cfg.get_any_node
>>> entry_node = cfg.get_any_node(proj.entry)
>>> len(list(cfg.graph.successors(entry_node)))
2

 

翻譯自:https://docs.angr.io

 
 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2026 CODEPRJ.COM