新知识

import claripy # 引用符号

p.factory.blank_state(addr = start_addr) # 让程序从当前位置进入 ans1 = claripy.BVS('ans1', 32) # 创建参数名为 ans1 大小为 32位 因为 eax是int形式

init_state.regs.eax = ans1 # 将创建的参数赋值给 寄存器 eax (regs寄存器)

password1 = found_state.solver.eval(ans1) # 计算出第一个 ans1 的值赋值给 password1

函数分析

三个 complex_function() 一个输入函数

输入函数

与之前的不一样 以前的是 %s 读入 这个是 %x 读入

这个输入 angr 不太支持 可以让函数从 scanf之后进行运行 且出入的是 16进制

直接赋值着 几个地址 就可以跳过 这个函数执行 也能达到一样的效果

保存在这些符号向量 从而让angr 执行程序

# -*- encoding: utf-8 -*-
from __future__ import print_function
'''
@文件        :angr_exp.py
@时间        :2020/04/23 14:40:10
@作者        :0xc4m3l
'''
import angr
import sys
import claripy      # 引用符号

def main(argv):
    bin_path = argv[1]
    p = angr.Project(bin_path)

    start_addr = 0x0804890E
    init_state = p.factory.blank_state(addr = start_addr) # 让程序从当前位置进入

    ans1 = claripy.BVS('ans1', 32)  # 创建参数名为 ans1 大小为 32位 因为 eax是int形式
    ans2 = claripy.BVS('ans2', 32)
    ans3 = claripy.BVS('ans3', 32)

    init_state.regs.eax = ans1  # 将创建的参数赋值给 寄存器 eax (regs寄存器)
    init_state.regs.ebx = ans2
    init_state.regs.edx = ans3
 
    sm = p.factory.simulation_manager(init_state)
    def is_good(state):
        return b'Good Job' in state.posix.dumps(1)
    
    def is_bad(state):
        return b'Try again' in state.posix.dumps(1)

    sm.explore(find=is_good, avoid=is_bad)

    if sm.found:   # 如果找到
        found_state = sm.found[0]
        
        password1 = found_state.solver.eval(ans1)   # 计算出第一个 ans1 的值赋值给 password1
        password2 = found_state.solver.eval(ans2)
        password3 = found_state.solver.eval(ans3)
        print("Solution: {:x} {:x} {:x}".format(password1,password2,password3))
    else:
        raise Exception("No solution found")

if __name__ == "__main__":
    main(sys.argv)