angr嘗試

中文簡介添加鏈接描述
但是官方github上的pdf文檔介紹的更詳細。

測試了一下中文簡介的內容大概就這些,只是測試加上個人理解,不一定正確不喜勿噴

#coding=utf-8
import angr

b=angr.Project("./level2")

print (hex(b.entry))  #程序的載入地址
print hex(b.loader.min_addr), hex(b.loader.max_addr) #程序的最小
print b.filename    #加載項目全名
print b.loader       #裝載器
print b.loader.shared_objects   #裝載的庫名稱和內存用於操作共享庫
print

print b.loader.memory[0x8048350]  #輸出制定內存地址處的值
print b.loader.main_object        #二進制對象(輸出主二進制模塊的開始和結束地址)

print b.loader.find_object_containing(0x8048350)   #找到一個內存地址屬於哪個函數(也可能是模塊)

print b.loader.find_symbol_got_entry('__libc_start_main')   #獲取指定符號的got表條目

print b.loader.main_object.deps   #得到dynmic section的

print b.loader.main_object.memory #是關於主二進制對象的內存內容的dict
print b.loader.shared_objects['libc.so.6'].imports  #這是一個裝載的libc所需的導入條目的dict

print b.loader.main_object.imports  #這是一個主二進制對象所需的導入條目的dict(name->ELFRelocation),其地址通常是0

在github上衆多栗子中找了個合適的

#!/usr/bin/env python


'''
ais3_crackme has been developed by Tyler Nighswander (tylerni7) for ais3.

It is an easy crackme challenge. It checks the command line argument.
'''

import angr
import claripy


def main():
    project = angr.Project("./ais3_crackme")

    #create an initial state with a symbolic bit vector as argv1
    argv1 = claripy.BVS("argv1",100*8) #since we do not the length now, we just put 100 bytes
    initial_state = project.factory.entry_state(args=["./crackme1",argv1])

    #create a path group using the created initial state 
    sm = project.factory.simulation_manager(initial_state)

    #symbolically execute the program until we reach the wanted value of the instruction pointer
    sm.explore(find=0x400602) #at this instruction the binary will print(the "correct" message)

    found = sm.found[0]
    #ask to the symbolic solver to get the value of argv1 in the reached state as a string
    solution = found.solver.eval(argv1, cast_to=bytes)

    print(repr(solution))
    solution = solution[:solution.find(b"\x00")]
    print(solution)
    return solution

def test():
    res = main()
    assert res == b"ais3{I_tak3_g00d_n0t3s}"


if __name__ == '__main__':
    print(repr(main()))

手動測試了一下,輸出了一些內容,加上了一些註解

# coding=utf-8
import angr
import claripy
def main():
	project=angr.Project("./ais3_crackme")
	
	argv1=claripy.BVS("angv1",100*8)#打包
	print (argv1)
	print(hex(project.entry))#顯示正常加載的地址,可以驗證跟下一句返回值相同
	initial_state=project.factory.entry_state(args=["./crackme1",argv1]) #返回一個程序載入地址,是複製了一份原本的程序,但是命令行參數是args
	
	print (initial_state)
	
	sm=project.factory.simulation_manager(initial_state)#用初始化的狀態創建一個路徑組
	sm.explore(find=0x400602)#使用符號執行一直執行知道訪問了0x400602地址處的值
	print ("sm=",sm)
	found=sm.found[0]  #一組路徑裏符合條件(訪問了0x400602這個地址的一條路徑)
	print ("found=",found)
	
	solution=found.solver.eval(argv1,cast_to=bytes)#得到argv1的值類型是byte形式
	print (repr(solution))
	solution=solution[:solution.find(b"\x00")]
	print(repr(solution))
	return solution
	
	
if __name__=='__main__':
	print (repr(main()))

總結:這裏的核心是
project.factory.entry_state(args=["./crackme1",argv1]) #路徑名並不是真的,是賦值了一份原本程序傳進去一些參數。
sm.explore(find=0x400602)符號執行進行大量數據測試直到訪問了find的值內存處的內容。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章