Angr_ctf

3 篇文章 0 订阅
1 篇文章 0 订阅

Angr_ctf:1~13练习

#、angr 入门

angr,符号执行,利用python开发的二进制程序分析框架。

linux安装

安装依赖库

sudo apt-get install python-dev libffi-dev build-essential virtualenvwrapper

python3安装angr

pip install angr

然后再在python控制台导入库就说明安装完成。

>>> import angr

然后下面就先进行Angr_Ctf练习,来熟悉angr

跟着B站up的视频做的:angr符号执行练习,他每个练习出了一个视频,讲的真的很清楚。

angr_ctf地址:https://github.com/jakespringer/angr_ctf

所有代码均是python3,两个环境

win10-vscode-python3.8

ubuntu-puthon3.8

00_angr_find

(1)总结

第0题完全是为了让我们熟悉angr的用法,给出了最简单的样例,类似模板。

(2)练习

第00道题比较简单,程序本身也不复杂,有明显的分支。

image-20210906164724803

image-20210906164803288

angr符号执行时我们可以直接忽略算法,只关注分支结果。

写angr求解。

#win10环境-vscode-python3
import angr
p = angr.Project("D:\\user\\Desktop\\2021.Study\\8.19-python_angr\\dist\\00\\00_angr_find")#导入程序
init_state = p.factory.entry_state()#相当于获取程序的入口点
sm = p.factory.simulation_manager(init_state)#从程序的入口点开始符号执行
print(sm.explore(find=0x08048678))#探索,寻找这个地址,结果打印出来,一个类,显示有几个解。
if sm.found:
    found_state = sm.found[0]#结果存在这个数组里,一般唯一解,所以下标0
    print(found_state.posix.dumps(0))#0代表输入 即解,1代表输出
else:
    print("Could not find the solution")

image-20210906170204762

获得解:JXWVXRKX

测试下

image-20210906170631811

正确!

01_angr_avoid

(1)总结

第01道题主要是熟悉在sm.explore()这个方法里,除了有find表示我们要探索的地址外,还有avoid表示我们要避免的地址。可以有效提高angr的效率。

(2)练习

IDA打开,如果f5的话,要反编译很久也没有成功,

所以直接看看汇编(因为不是很难。。。),其实也不是,只需要IDActrl+f12查找字符串,找到结尾的表示正确字符串和表示错误字符串,然后再按X键查看交叉引用,就直接过去了。。。

image-20210906233758292

所以sm.explore(find=0x080485e0,avoid=0x080485F2),多了一个avoid,可以适当提高效率。

下面直接给出完成脚本。

#win10环境-vscode-python3
import angr
p = angr.Project("D:\\user\\Desktop\\2021.Study\\8.19-python_angr\\dist\\01\\01_angr_avoid")#导入程序
init_state = p.factory.entry_state()#相当于获取程序的入口点
sm = p.factory.simulation_manager(init_state)#从程序的入口点开始符号执行
print(sm.explore(find=0x080485e0,avoid=0x080485F2))#探索,寻找这个地址,结果打印出来,一个类,显示有几个解。
if sm.found:
    found_state = sm.found[0]#结果存在这个数组里,一般唯一解,所以下标0
    print(found_state.posix.dumps(0))#0代表输入 即解,1代表输出
else:
    print("Could not find the solution")

这里是在ubuntu18的python3里面测试的。

image-20210906234939488

然后就打印正确结果即可。

image-20210906235144389

’HUJOZMYS’

然后再在原题测试一下:

image-20210906235253530

成功!

02_angr_condition

(1)总结

第2道题也不难,主要是让我们熟悉另一种写法。

顾名思义condition是条件、情况的意思,第2题就是给出了条件、情况的概念。

即:我们在sm.explore(find=***,avoid=***)的时候,其中***可以是一个情况,比如输出情况(结尾输出的字符串)。


好了,具体怎么操作,下面来练习这道题。


(2)练习

IDA打开,f5,结构比较简单,注意结果输出。

image-20210910105056540

给出新得,condition的写法:

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)

所以,写出完整对应脚本,(导入sys,通过命令行传路径参数)

import angr
import sys

def main(argv):
    bin_path = argv[1]#传入命令行参数
    print(bin_path)
    p = angr.Project(bin_path)
    
    init_state = p.factory.entry_state()

    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]
        print('Solution:{}'.format(found_state.posix.dumps(0)))


if __name__ == '__main__':
    main(sys.argv)#传入命令行参数

执行结果:

image-20210910105708456

测试一下:

image-20210910105744865

成功!

03_angr_symbolic_registers

(1)总结

第3题给出的样例,输入是分开的,也就是说angr可以分开输入,同时同个输入,通过符号向量库claripy,固定变量的位数(类似z3的向量求解)。

同时,由于angr是基于unicorn开发(Unicorn可以执行任意一段代码数据),可以将符号向量直接传入angr给定的寄存器如init_state.regs.eax。即可以不用从entry_state()开始执行,而是通过blank_state(addr=start_addr)方法,从任意位置start_addr开始执行。然后angr符号执行完成后,可以直接查看寄存器取出输入结果。

具体怎么操作,下面来练习第3题。

(2)练习

IDA打开,找到输出结果condition,以及关注输入

image-20210910160029420

进入输入函数,发现要分开一次输入三个16进制数

image-20210910160101912

查看这部分的汇编,

image-20210910160303036

根据调用约定理清思路,函数参数是从右往左一次压入堆栈的,所以看一看出,寄存器eax、ebx、edx依次存放的是参数1、参数2、参数3(从左往右1-2-3)。

所以,来到主函数

image-20210910160741187

分析完之后就可以写angr脚本了,(我给了注释)

import angr
import sys
import claripy#新建符号向量

def main(argv):
    bin_path = argv[1]
    #D:\\user\\Desktop\\2021.Study\\8.19-python_angr\\dist\\03\\03_angr_symbolic_registers
    p = angr.Project(bin_path)
    start_addr=0x08048980#自定义程序起始地址
    init_state = p.factory.blank_state(addr=start_addr)#从自定义的起始地址开始启动

    pass1 = claripy.BVS('pass1',32)#新建一个32位的符号向量,对应题目中寄存器长度32位
    pass2 = claripy.BVS('pass2',32)
    pass3 = claripy.BVS('pass3',32)
    
    init_state.regs.eax = pass1#初始化寄存器,类似z3
    init_state.regs.ebx = pass2
    init_state.regs.edx = pass3

    sm = p.factory.simulation_manager(init_state)#启动仿真模拟

    #定义condition
    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(pass1)#类似z3求解,求解对应单个值
        password2 = found_state.solver.eval(pass2)
        password3 = found_state.solver.eval(pass3)

        print("Solution:{:x} {:x} {:x}".format(password1,password2,password3))
    else:
        print('No solution found!')

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

通过命令行带地址参数执行

image-20210910160918038

结果带入原题测试一下

image-20210910160946972

成功!

04_angr_symbolic_stack

(1)总结

第04题给出的样例也是输入也是分开的,与03题不同的是,04题输入的变量,存储在局部堆栈,所以04题练习的就是利用angr,例如:init_state.stack_push(init_state.regs.ebp),来构造堆栈,并且是模拟题目中的堆栈分布,当然,也会创建符号向量。

具体怎么操作,下面来练习第04题。

(2)练习

IDA打开,梳理一下结构,发现要输入的变量,存储在堆栈,并且每次使用都在堆栈取值。

这时,就不能单纯利用寄存器求值了。

所以这里可以利用angr构造堆栈,然后将符号向量压入堆栈,就可以完全模拟题目中的堆栈分布结构。

image-20210911115531601

image-20210911115837283

分析完之后,就可以写angr脚本了

import angr
import sys

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

    start_addr = 0x08048697
    init_state = p.factory.blank_state(addr=start_addr)

    #初始化堆栈
    init_state.stack_push(init_state.regs.ebp)
    init_state.regs.esp = init_state.regs.ebp

    #模拟题目中的堆栈空间,两个两个变量分别是[ebp-0xc]、[ebp-0x10]
    #所以[ebp-4]、[ebp-8]这两个位置其实是我们不用的
    padding_size = 8
    init_state.regs.esp -= padding_size

    #创建符号向量
    pass1 = init_state.solver.BVS('pass1',32)
    pass2 = init_state.solver.BVS('pass2',32)

    #将符号向量压入堆栈,
    #也是模拟题目中的堆栈空间,两个两个变量分别是[ebp-0xc]、[ebp-0x10]
    init_state.stack_push(pass1)
    init_state.stack_push(pass2)

    #构造完成,开始启动仿真
    #simgr()方法其实可以看作等价于simulation_manager()方法,只是简洁便于写
    sm = p.factory.simgr(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(pass1)
        password2 = found_state.solver.eval(pass2)

        print('Solution:{} {}'.format(password1,password2))
    else:
        print('Solution not found!')
if __name__ == '__main__':
    main(sys.argv)

然后在命令行带参数执行。

image-20210911121250796

最后,测试一下结果

image-20210911121314667

正确!

05_angr_symbolic_memory

(1)总结

第05题是让输入四个8位字符串,变量既不是存储与寄存器,也不是堆栈,直接是在内存中。

所以05题给出的知识点就是利用angr通过init_state.memory.store(addr,p)将符号向量p引入到对应地址aadr中!

(2)练习

IDA打开,查看主结构,让分别输入4个8字符的字符串,并且分别存储与不同的内存。

image-20210911162804950

同时,启动地址也是跳过scanf

image-20210911163258060

下面就可以写对应的angr脚本了

import angr
import sys

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

    start_addr = 0x08048601
    init_state = p.factory.blank_state(addr=start_addr)
    
    #创建符号向量
    #题目中输入8个字符,对应长度64位
    p1 = init_state.solver.BVS('p1',64)
    p2 = init_state.solver.BVS('p2',64)
    p3 = init_state.solver.BVS('p3',64)
    p4 = init_state.solver.BVS('p4',64)

    #关键:
    # 将符号向量引入到内存中
    p1_addr = 0x0A1BA1C0
    p2_addr = 0x0A1BA1C8
    p3_addr = 0x0A1BA1D0
    p4_addr = 0x0A1BA1D8
    init_state.memory.store(p1_addr,p1)
    init_state.memory.store(p2_addr,p2)
    init_state.memory.store(p3_addr,p3)
    init_state.memory.store(p4_addr,p4)

    #启动仿真模拟
    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]

        #将符号向量从内存中取出,cast_to为bytes型
        pass1 = found_state.solver.eval(p1,cast_to=bytes).decode('utf-8')
        pass2 = found_state.solver.eval(p2,cast_to=bytes).decode('utf-8')
        pass3 = found_state.solver.eval(p3,cast_to=bytes).decode('utf-8')
        pass4 = found_state.solver.eval(p4,cast_to=bytes).decode('utf-8')

        print("Solution:{} {} {} {}".format(pass1,pass2,pass3,pass4))
    else:
        raise Exception("Solution not found")
if __name__ == '__main__':
    main(sys.argv)

命令行带参数执行。

image-20210911163423487

最后测试一下

image-20210911163625480

成功!!

06_angr_symbolic_dynamic_memory

(1)总结

第06题的是让分别输入两个8字符的字符串,与前面题不同的是,06题是通过指向堆区的指针来存储输入的数据,既不是寄存器、堆栈,也不是固定的内存,因为是通过malloc申请的堆区内存空间,具有随机性。

所以06题引入的知识点就是通过我们自己在内存中挑一块固定的内存,用来充当malloc申请的堆区空间,然后把这块内存空间的地址付给题目中的buffer0buffer1指针,让这两个指针指向我们自己挑的固定的地址,再把创建的符号向量引入这一块固定的地址,然后等待模拟仿真结束之后,再把解出符号向量的值,即可!

(2)练习

IDA打开,查看整体结构,是让我们分别输入两个8字符的字符串,是通过指向堆区的指针来存储输入的数据,既不是寄存器、堆栈,也不是固定的内存,因为是通过malloc申请的堆区内存空间,具有随机性。

image-20210911195153720

就像偷梁换柱一样。

下面,就写angr脚本,进一步理解。

import angr
import sys

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

    start_addr = 0x08048699
    init_state = p.factory.blank_state(addr=start_addr)

    #我们自己申请的地址,用于代替题目中malloc的堆区空间
    #(为了防止这个地址被命中,我们直接往大了写。。。。)(具体我也不是很透彻。。。)
    print(init_state.regs.esp)#0x7fff0000
    buffer0 = init_state.regs.esp-0x100
    buffer1 = init_state.regs.esp-0x200

    #题目中存储堆区地址的指针buffer0、buffer1的地址
    buffer0_addr = 0x0ABCC8A4
    buffer1_addr = 0x0ABCC8AC

    #把参数二的值写到参数一对应的地址,第三个参数是指定小端存储
    init_state.memory.store(buffer0_addr,buffer0,endness=p.arch.memory_endness)
    init_state.memory.store(buffer1_addr,buffer1,endness=p.arch.memory_endness)

    #创建符号向量
    p1 = init_state.solver.BVS('p1',8*8)
    p2 = init_state.solver.BVS('p2',8*8)

    #把符号向量引入到我们自己“申请”的空间
    init_state.memory.store(buffer0,p1)
    init_state.memory.store(buffer1,p2)

    #启动仿真模拟
    sm = p.factory.simgr(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]
        pass1 = found_state.solver.eval(p1,cast_to=bytes).decode('utf-8')
        pass2 = found_state.solver.eval(p2,cast_to=bytes).decode('utf-8')

        print('Solution:{} {}'.format(pass1,pass2))
    else:
        raise Exception("Solution not found!")
    

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

命令行带参数执行。

image-20210911200003290

最后测试一下

image-20210911200026028

成功!!

07_angr_symbolic_file

(1)总结

第07题只是让输入字符串,不过题目有文件读取,这道题给的知识点就是利用angr模拟文件读取,同样也是会有符号化向量,将其引入我们模拟读取的文件。

(2)练习

IDA打开,分析大致文件结构,发现程序让我们输入字符串buffer,然后打开一个文件OJKSQYDP.txt,将buffer写入,再关闭文件OJKSQYDP.txt

image-20210912160344832

我们要做的,就是模拟这个文件,然后创造符号向量代替我们输入的字符串信息,再将其写入到模拟的文件,即可实现前面这一部分代码的功能。

image-20210912161316148

下面就是写利用angr模拟文件的代码

import angr
import sys

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

    start_addr = 0x080488D9
    init_state = p.factory.blank_state(addr=start_addr)

    filename = "OJKSQYDP.txt"
    file_size = 0x40 #字节

    #创建符号化向量
    password = init_state.solver.BVS("password",file_size*8)

    #SimFile是构造文件信息,包括文件名,文件内容和文件大小,同时将创建的符号化向量引入文件,文件大小是按位算的
    sim_file = angr.storage.SimFile(filename,content=password,size=file_size*8)

    #angr.fs.insert是将文件插入到文件系统中,需要文件名与符号化的文件
    init_state.fs.insert(filename,sim_file)

    #启动模拟仿真
    sm = p.factory.simgr(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]
        password = found_state.solver.eval(password,cast_to=bytes).decode('utf-8')
        print("Solution:{}".format(password))
    else:
        raise Exception("Solution not found!")

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

命令行带参数执行一下

image-20210912161500449

测试一下:

image-20210912161515109

成功!!

08_angr_constraints

(1)总结

第08题涉及路径爆炸的问题,路径爆炸大致是复杂度很高,angr实现起来太难了。比如在比较的时候,一个字符一个字符循环比较,比较路径过多,就会出现路径爆炸。

为了解决这个问题,angr给出的方法是避开循环比较,在比较之前停下来,添加约束,例如check_state.add_constraints(desired_string == check_bvs),最后通过约束求解,相当于z3约束求解。

(2)练习

IDA打开,就让输入16个字符,

image-20210912180251583

查看下面11行的check函数

image-20210912180601303

下面就写angr脚本感受一下!

import angr
import sys

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

    start_addr = 0x08048625#这个启动的位置就是scanf之后
    init_state = p.factory.blank_state(addr = start_addr)

    #创建符号向量
    buffer_addr = 0x0804A050#题目中buffer的地址
    password = init_state.solver.BVS("password",16*8)#题目中可以看到循环16次说明16个字符
    #将符号向量引入对应内存
    init_state.memory.store(buffer_addr,password)

    #启动仿真模拟
    sm = p.factory.simgr(init_state)

    #为了防止路径爆炸,就在check函数开始的地方停止,然后通过约束求解,避开循环比较
    check_addr = 0x08048565#题目中check函数的开头
    sm.explore(find=check_addr)

    if sm.found:
        check_state = sm.found[0]

        #在内存中取出之前的符号向量
        check_str_addr = buffer_addr
        check_str_size = 0x10
        check_bvs = check_state.memory.load(check_str_addr,check_str_size)

        desired_string = "AUPDNNPROEZRJWKB"#用于比较的字符串,题目中的password
        #添加约束
        check_state.add_constraints(desired_string == check_bvs)

        #求解约束的符号向量
        password = check_state.solver.eval(password,cast_to=bytes).decode('utf-8')
        print("Solution:{}".format(password))
    else:
        raise Exception("Solution not found!")

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

命令行带参数执行一下

image-20210912180733038

测试一下:

image-20210912180745117

成功!!

09_angr_hooks

(1)总结

第09题是输入两个16字符,准确的说应该是先输入16字符然后check函数验证,再输入16字符再strcmp函数验证,check函数与08题的一一致。因为是分成两次输入所以不方便通过约束符号向量求解,所以第09题给出的方法是hook掉check函数,等待仿真模拟结束之后直接查看输入即可。

(2)练习

IDA打开,查看整体结构

image-20210913211435744

hook的含义不必多说,

hook的过程是当程序执行到check函数时,我们自定义check机制,通过取出buffer对应地址的值,来比较check字符串。

下面就写脚本感受一下。

import angr
import sys
import claripy

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

    init_state = p.factory.entry_state()#因为要连续输入两次,就直接从入口点开始

    #利用angr来hook掉题目中的check函数,防止路径爆炸
    check_addr = 0x080486B3#要hook的函数地址
    check_skip_size = 5#字节数,一般call指令都是5个字节

    #hook的部分 @代表“修饰器” 具体看这篇文章https://www.yiibai.com/python/decorator.html

    @p.hook(check_addr,length=check_skip_size)
    def check_hook(state): #hook题目中check函数的函数
        
        user_input_addr = 0x0804A054#check函数的参数,即我们输入的字符串buffer的地址。
        user_input_length = 0x10
        
        #取出符号向量
        user_input_bvs = state.memory.load(
            user_input_addr,
            user_input_length
        )
        #用于check的字符串
        desired = "XYMKBKUHNIQYNQXE"

        #因为函数的返回值存储去eax
        #所以这里通过claripy.If(),
        # 如果相等,则执行参数2,将eax置为1
        # 如果不等,则执行参数3,将eax置为0
        state.regs.eax = claripy.If(
            desired == user_input_bvs,
            claripy.BVV(1,32),
            claripy.BVV(0,32)
        )

    #启动仿真模拟
    sm = p.factory.simgr(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]
        print("Solution:{}".format(found_state.posix.dumps(0)))
    else:
        raise Exception("Solution not found!")

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

命令行带参数执行

image-20210913211813327

测试一下:

image-20210913211847725

成功!

10_angr_simprocedures

(1)总结

第10题也是hook,是在09题的基础上延伸的,09题只hook一个地址,但当一个check函数多次重复使用的时候,每个地址都hook,那工程量就比较大,第10题提供了以函数名hook的hook方式,可以有效解决一个check函数多次重复使用的情形。

(2)练习

IDA打开,f5反编译出来结构和09题差不多,一样的check函数,(反编译出来只有一个?)

image-20210913234858369

但查看其流程图,发现竟然有很多个相同的check函数被重复调用(可能IDA没有成功f5反编译出来)

image-20210913235724574

所以,如果以函数名来hook,那么效率就会高很多。

下面写脚本感受一下

import angr
import sys
import claripy

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

    class mySimPro(angr.SimProcedure):
        #第一个参数self固定,后续参数模拟题目中要hook的函数拥有的参数。
        #check_equals_ORSDDWXHZURJRBDH((int)s, 0x10u) 
        #slef包含state成员
        def run(self,user_input_addr,user_input_length):
            angr_bvs = self.state.memory.load( 
                user_input_addr,
                user_input_length
            )
            desired_string = "ORSDDWXHZURJRBDH"
            return claripy.If( 
                desired_string == angr_bvs,
                claripy.BVV(1,32),
                claripy.BVV(0,32)
            )
    #以函数名hook函数
    check_symbol = "check_equals_ORSDDWXHZURJRBDH"
    #第二参数mySimPro是个类,继承angr.SimProcedures,提供的run方法就是我们用于hook的替代函数,
    p.hook_symbol(check_symbol,mySimPro())

    sm = p.factory.simgr(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]
        print("Solution:{}".format(found_state.posix.dumps(0).decode('utf-8')))
    else:
        raise Exception("Solution not found!")
        

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

命令行带参数执行一下

image-20210913235929783

测试一下:

image-20210913235951123

成功!

11_angr_sim_scanf

(1)总结

(2)练习

12_angr_veritesting

(1)总结

(2)练习

13_angr_static_binary

(1)总结

(2)练习

Pro是个类,继承angr.SimProcedures,提供的run方法就是我们用于hook的替代函数,
p.hook_symbol(check_symbol,mySimPro())

sm = p.factory.simgr(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]
    print("Solution:{}".format(found_state.posix.dumps(0).decode('utf-8')))
else:
    raise Exception("Solution not found!")

if name == ‘main’:
main(sys.argv)


命令行带参数执行一下

[外链图片转存中...(img-H5VNNn7C-1635175824885)]

测试一下:

[外链图片转存中...(img-eampEc7F-1635175824885)]

成功!



## 11_angr_sim_scanf

### (1)总结



### (2)练习



## 12_angr_veritesting

### (1)总结



### (2)练习



## 13_angr_static_binary

### (1)总结



### (2)练习
  • 2
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值