函数分析

程序 输入

输入 保存在 栈中

所以 要模拟 程序的进行 要模拟出 当前这个函数开始时 的 push ebp; mov ebp, esp; 的操作

让程序入口为 0x8048697 开始执行

因为用到的值 是存在栈上 偏移分别为 [ebp-0xc],[ebp-0x10] 中 我们 可以利用 angr 去构造一个这也的栈结构 从而让符号化的值保存在这个栈地址

# -*- encoding: utf-8 -*-
from __future__ import print_function
'''
@文件        :angr_exp.py
@时间        :2020/04/23 17:29:18
@作者        :0xc4m3l
'''
import angr 
import sys
import claripy

def main(argv):
    bin_patch = argv[1]
    p = angr.Project(bin_patch)
    start_addr = 0x08048697

    init_state = p.factory.blank_state(addr = start_addr)
    
    init_state.stack_push(init_state.regs.ebp)
    init_state.regs.ebp = init_state.regs.esp

    # 需要的 符号化参数 push 进去保存所以要先 sub esp,8 这样压入的值保存在
    # [ebp - 0xc] [ebp - 0x10]   因为是小端 所以-8 (0-3) (4-7) (8-0xb)(0xc-0x9)
		# 所以这里 esp 要先 减 8
    init_state.regs.esp -= 8

    ans1 = claripy.BVS("ans1", 32)
    ans2 = claripy.BVS("ans2", 32)

    init_state.stack_push(ans1)
    init_state.stack_push(ans2)
    
		sm = p.factory.simgr(init_state)  # simgr 函数创建 Simulation Manager 对象
		

    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)
        password2 = found_state.solver.eval(ans2)
        print("Solver : {} {}".format(password1,password2))
    else:
        raise Exception("no found")

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