angr也可以将符号写在内存里,控制内存中的值,结合任意位置开始有奇效,但就是慢sym-write

     p = angr.Project('./issue', load_options={"auto_load_libs": False})
state = p.factory.entry_state(add_options={angr.options.SYMBOLIC_WRITE_ADDRESSES})
u = claripy.BVS("u", 8)
state.memory.store(0x804a021, u)

因为最近好像要开始0ctf了,再分析一道0ctf的题目,0ctf_trace

这个题目两个文件,一个.bin的看起来像是二进制文件,其中trace是MIPS指令集。上万行,头大。

首先通过grep jal可以得到所调用的所有函数的起始地址,接着grep jr r31得到函数的结束地址

trace中总共三个函数,有一个函数运行了100多次,虽然每个函数还是很长就是了

然后分析函数得到Flag的地址,程序首先对常量字符初始化了,然后加上了一串未知字符串,就是flag

 #!/usr/bin/env python2

 from __future__ import print_function
import struct
import angr MAIN_START = 0x4009d4
MAIN_END = 0x00400c18 FLAG_LOCATION = 0x400D80
FLAG_PTR_LOCATION = 0x410EA0 def load_trace():
res = []
delay_slots = set()
with open("./trace_8339a701aae26588966ad9efa0815a0a.log") as f:
for line in f:
if line.startswith('[INFO]'):
addr = int(line[6:6+8], 16) res.append(addr) if ("move r1, r1" in line):
delay_slots.add(addr) return res, delay_slots def main():
trace_log, delay_slots = load_trace() project = angr.Project("./data.bin", load_options={
'main_opts': {
'backend': 'blob',
'base_addr': 0x400770,
'arch': 'mipsel',
},
}) state = project.factory.blank_state(addr=MAIN_START)
state.memory.store(FLAG_LOCATION, state.solver.BVS("flag", 8*32))
state.memory.store(FLAG_PTR_LOCATION, struct.pack("<I", FLAG_LOCATION)) sm = project.factory.simulation_manager(state)
choices = [state] print("Tracing...")
for i, addr in enumerate(trace_log):
if addr in delay_slots:
continue for s in choices:
if s.addr == addr:
break else:
raise ValueError("couldn't advance to %08x, line %d" % (addr, i+1)) if s.addr == MAIN_END:
break if s.addr + 4 in delay_slots:
choices = project.factory.successors(s, num_inst=2).successors
else:
choices = project.factory.successors(s, num_inst=1).successors state = s print("Running solver...") solution = state.solver.eval(state.memory.load(FLAG_LOCATION, 32), cast_to=bytes).rstrip(b'\0').decode('ascii')
print("The flag is", solution) return solution def test():
assert main() == "0ctf{tr135m1k5l96551s9l5r}" if __name__ == "__main__":
main()

angr进阶(5)内存操作的更多相关文章

  1. Java进阶3. 内存回收机制

    Java进阶3. 内存回收机制 20131029 前言: 学过C++的都知道,C++中内存需要程序员自己维护.说道这里,很多开发的同学就感觉很痛苦,当他转向Java的时候,就会说你看Java多好啊,程 ...

  2. 【腾讯优测干货分享】如何降低App的待机内存(四)——进阶:内存原理

    本文来自于腾讯优测公众号(wxutest),未经作者同意,请勿转载,原文地址:http://mp.weixin.qq.com/s/3FTPFvZRqyAQnU047kmWJQ 1.4进阶:内存原理 在 ...

  3. java 21-11 数据输入、输出流和内存操作流

    IO数据流: 可以读写基本数据类型的数据 数据输入流:DataInputStream DataInputStream(InputStream in)   数据输出流:DataOutputStream ...

  4. 【转】《深入理解计算机系统》C程序中常见的内存操作有关的典型编程错误

    原文地址:http://blog.csdn.net/slvher/article/details/9150597 对C/C++程序员来说,内存管理是个不小的挑战,绝对值得慎之又慎,否则让由上万行代码构 ...

  5. c++ void,内存操作函数

    void的含义 void的字面意思是“无类型”, void * 则为“无类型指针”, void * 可以指向任何类型的数据 void几乎只有“注释”和限制程序的作用,因为从来没有人会定义一个void变 ...

  6. java基础知识回顾之javaIO类--内存操作流ByteArrayInputStream和ByteArrayOutputSteam(操作字节数组)

    直接看代码: package cn.itcast.io.p6.bytestream; import java.io.ByteArrayInputStream; import java.io.ByteA ...

  7. Java API —— IO流(数据操作流 & 内存操作流 & 打印流 & 标准输入输出流 & 随机访问流 & 合并流 & 序列化流 & Properties & NIO)

    1.操作基本数据类型的流     1) 操作基本数据类型 · DataInputStream:数据输入流允许应用程序以与机器无关方式从底层输入流中读取基本 Java 数据类型.应用程序可以使用数据输出 ...

  8. 【C++基础】内存操作 getMemory改错

    内存操作的考察点:①指针 ②变量生存期及作用范围 ③动态内存申请和释放 笔试题************************************************************* ...

  9. 《深入理解计算机系统》C程序中常见的内存操作有关的典型编程错误

    对C/C++程序员来说,内存管理是个不小的挑战,绝对值得慎之又慎,否则让由上万行代码构成的模块跑起来后才出现内存崩溃,是很让人痛苦的.因为崩溃的位置在时间和空间上,通常是在距真正的错误源一段距离之后才 ...

  10. Java基础知识强化之IO流笔记58:内存操作流

    1. 内存操作流: 用来操作处理临时存储的信息的. (1)操作字节数组: ByteArrayInputStream ByteArrayOutputStream 代码示例: package cn.itc ...

随机推荐

  1. Express安装

    安装Express 安装好node.js的前提下,再来安装Express. 1.按win+rR,打开“运行”对话框,输入:“cmd”. 2.需要创建一个目录,然后进入目录并作为当前工作目录. mkdi ...

  2. 对象转JSON

    /// <summary> /// 把对象序列化 JSON 字符串 /// </summary> /// <typeparam name="T"> ...

  3. 浅谈微信小程序一二

    1.生命周期 1.onLoad():页面加载时触发,一个页面只加载一次. 2.onShow():页面显示切换的时候触发 3.onReady():页面初次渲染完成时触发.一个页面只会调用一次,代表页面已 ...

  4. 下载 mysql 数据库 的步骤 完整版

    1. 官网(点这里)上下载 2. 3. 4. 5. 6. 7.

  5. RHEL7 配置网络yum源

    redhat系统安装好尽管默认带有yum,但是redhat的更新包只对注册用户有效(收费).所以需要更换yum源. 基本的流程就是: 1.删除redhat7.0系统自带的yum软件包: 2.自行下载所 ...

  6. RAID部署

    添加硬盘 1.创建一个RAID阵列卡 2.格式化刚刚做好的md0 3.创建挂载目录 4.自动挂载,永久生效 5.使用 创建RAID 1.创建一个RAID阵列卡 2.格式化 3.创建挂载目录 4.自动挂 ...

  7. Mesos源码分析(11): Mesos-Master接收到launchTasks消息

    根据Mesos源码分析(6): Mesos Master的初始化中的代码分析,当Mesos-Master接收到launchTask消息的时候,会调用Master::launchTasks函数.   v ...

  8. .NET Core 源码导航(按程序集链接)

    System.*.dll/dotnetfx mscorlib.dll/dotnetclr Microsoft.AspNetCore.dll Microsoft.EntityFrameworkCore. ...

  9. java并发面试

    1.在java中守护线程和本地线程区别? java中的线程分为两种:守护线程(Daemon)和用户线程(User). 任何线程都可以设置为守护线程和用户线程,通过方法Thread.setDaemon( ...

  10. 事件派发dispatchEvent

    1.什么是dispatchEvent? dispatch意为"调度"."派遣",event为"事件".所以dispatchEvent即向指定 ...