学逆向论坛

找回密码
立即注册

只需一步,快速开始

发新帖

116

积分

0

好友

25

主题
发表于 2020-6-15 00:44:09 | 查看: 2513| 回复: 0

相关题目:


前言
  此篇来了解一下如何对内存寄存器进行直接存取
通过直接地址写入  对于.bss段等固定地址的变量我们可以利用claripy直接地址写入,进行初始化state。下面我通过一个例子进行简单说明。
例题来自于sym-write  载入IDA

深入浅出angr(三)

深入浅出angr(三)
  其中变量u位于.bss段,是未初始化的变量,我们可以在state状态,初始化simulation_manager的state时,将其设置.

深入浅出angr(三)

深入浅出angr(三)
  为了可以进行符号地址的写入,在设置state需要申明add_options={"SYMBOLIC_WRITE_ADDRESSES"}
  angr提供了SimMemory类对内存进行操作。

深入浅出angr(三)

深入浅出angr(三)
  并且提供了两种方法

深入浅出angr(三)

深入浅出angr(三)

深入浅出angr(三)

深入浅出angr(三)
  通过上下文,可以知道u是一个8bit的值。因此我们通过state.memory.store(0x804a021, u)将u存储到0x804a021处

深入浅出angr(三)

深入浅出angr(三)
  然后设置需要到达的路径即可
sm.explore(find=0x80484e3, avoid=0x80484f5)

深入浅出angr(三)

深入浅出angr(三)
  是不是很简单呢~
操纵内存以及寄存器数据  例题来自flareon2015_2
  IDA载入,发现是windows程序,而且逻辑也很简单。

深入浅出angr(三)

深入浅出angr(三)
  为了避免调用windows的API,我们需要从0x401084设为起始状态,并且设置好传入的参数。
  通过上下文,可以知道0x402159存放的是输入的数据,根据windows 32 位参数传递规则,我们可以如下进行构造。
s.memory.store(s.regs.esp+12, s.solver.BVV(40, s.arch.bits))
s.mem[s.regs.esp+8:].dword = 0x402159
s.mem[s.regs.esp+4:].dword = 0x4010e4
s.mem[s.regs.esp:].dword = 0x401064
  其中s.mem[s.regs.esp:].dword用来设置内存的值,并且大小为dword
  angr支持许多类型的数据,包括dword,word,long,int,uint8_t,uint32_t等等。我建议只要对自己的理解不产生影响,选取合适类型即可。我通常会选择uint8_t之类的数据类型,毕竟对linux编程比较熟悉。
  完整代码如下:
#!/usr/bin/env python
import angr

def main():
b = angr.Project("very_success", load_options={"auto_load_libs":False})
# create a state at the checking function
# Since this is a windows binary we have to start after the windows library calls
# remove lazy solves since we don't want to explore unsatisfiable paths
s = b.factory.blank_state(addr=0x401084)
# set up the arguments on the stack
s.memory.store(s.regs.esp+12, s.solver.BVV(40, s.arch.bits))
s.mem[s.regs.esp+8:].dword = 0x402159
s.mem[s.regs.esp+4:].dword = 0x4010e4
s.mem[s.regs.esp:].dword = 0x401064
# store a symbolic string for the input
s.memory.store(0x402159, s.solver.BVS("ans", 8*40))
# explore for success state, avoiding failure
sm = b.factory.simulation_manager(s)
sm.explore(find=0x40106b, avoid=0x401072)
# print(the string)
found_state = sm.found[0]
return found_state.solver.eval(found_state.memory.load(0x402159, 40), cast_to=bytes).strip(b'\0')

def test():
assert main() == b'a_Little_b1t_harder_plez@flare-on.com'

if __name__ == '__main__':
print(main())
经典例题一  angrbird这题比较经典。
  首先程序很直接的反调试,而且又是这种线性的混淆,这用angr来解决是再合适不过了。

深入浅出angr(三)

深入浅出angr(三)
  一条斜线。有点飘。

深入浅出angr(三)

深入浅出angr(三)
  其中刚开始的部分就是反调试,通常的做法是patch程序,不过这里用angr来解决。
  为了绕过反调试我们需要将入口地址设置在mov     rdx, cs:stdin也就是0x4007C2,同时结合IDA的分析,我们需要将mov     [rbp+var_70], offset off_606018布局到相应的内存中,这里应该是在设置函数表。
  同时我们还应该设置好fgets函数的参数mov     ecx, [rbp+n]其中的[rbp+n]应该设置为21
  同时为了执行程序还应该设置mov     rbp, rsp
  这几步是必不可少的,因为跳过反调试,需要一定的代价。
因此初始化部分代码如下:
state.regs.rbp = state.regs.rsp
state.mem[state.regs.rbp - 0x74].uint32_t = 0x40
state.mem[state.regs.rbp - 0x70].uint64_t = 0x1000
state.mem[state.regs.rbp - 0x68].uint64_t = 0x1008
state.mem[state.regs.rbp - 0x60].uint64_t = 0x1010
state.mem[state.regs.rbp - 0x58].uint64_t = 0x1018
  正确设置完初始状态后就是正常的执行了。

深入浅出angr(三)

深入浅出angr(三)
经典例题二  此题使用angr有两种方法,分别是在不同的地方进行条件约束,我个人认为对angr的应用会有所帮助。仅做简单记录。
  google2016_unbreakable_1
方法一  通过命令行输入,并设置条件约束。
p = angr.Project('unbreakable',load_options={"auto_load_libs": False})

argv = claripy.BVS("argv",0x43*8)

state = p.factory.entry_state(args={"./unbreakable",argv},add_options={angr.options.LAZY_SOLVES})
state.libc.buf_symbolic_bytes=0x43 + 1

for byt in argv.chop(8):
state.add_constraints(state.solver.And(byt >= ord(' '),byt <= ord('~')))
  其中的state.libc.buf_symbolic_bytes=0x43 + 1是非常有必要的,我看官方所说,angr默认的symbolic_bytes只有60bytes,对于这题来说太小了。也就是说如果命令行传入的大小大于默认的值,所以需要手动调整大小。
  而且条件约束也是十分有必要的,这里说明一下chop方法:

深入浅出angr(三)

深入浅出angr(三)
  意思就是截取,所以我们每8bits截取,然后进行条件约束。
代码如下:
import angr
import claripy

START_ADDR = 0x4005bd # first part of program that does computation
AVOID_ADDR = 0x400850 # address of function that prints wrong
FIND_ADDR = 0x400830 # address of function that prints correct
INPUT_ADDR = 0x6042c0 # location in memory of user input
INPUT_LENGTH = 0xf2 - 0xc0 + 1 # derived from the first and last character
# reference in data

def extract_memory(state):
"""Convience method that returns the flag input memory."""
return state.solver.eval(state.memory.load(INPUT_ADDR, INPUT_LENGTH), cast_to=bytes)

def main():
p = angr.Project('unbreakable',load_options={"auto_load_libs": False})

argv = claripy.BVS("argv",0x43*8)

state = p.factory.entry_state(args={"./unbreakable",argv},add_options={angr.options.LAZY_SOLVES})
state.libc.buf_symbolic_bytes=0x43 + 1

for byt in argv.chop(8):
state.add_constraints(state.solver.And(byt >= ord(' '),byt <= ord('~')))


ex = p.factory.simulation_manager(state)


ex.explore(find=(FIND_ADDR,), avoid=(AVOID_ADDR,))

flag = extract_memory(ex.found[0]) # ex.one_found is equiv. to ex.found[0]

print(flag)

if __name__ == '__main__':
main()
方法二  第二种方法跳过命令行输入的过程,直接将值存储到引用的内存当中,并设置条件约束。比较简单。代码如下:
import angr
import claripy

START_ADDR = 0x4005bd # first part of program that does computation
AVOID_ADDR = 0x400850 # address of function that prints wrong
FIND_ADDR = 0x400830 # address of function that prints correct
INPUT_ADDR = 0x6042c0 # location in memory of user input
INPUT_LENGTH = 0xf2 - 0xc0 + 1 # derived from the first and last character
def main():
p = angr.Project('unbreakable')
state = p.factory.blank_state(addr=START_ADDR, add_options={angr.options.LAZY_SOLVES})
flag_chars = [state.solver.BVS('flag_%d' % i, 8) for i in range(0x43)]
for flag_chr in flag_chars:
state.add_constraints(state.solver.And(flag_chr >= ord(' '),flag_chr <= ord('~')))

for i in range(0x43):
state.memory.store(INPUT_ADDR+i,flag_chars[i])
#state.
ex = p.factory.simulation_manager(state)


ex.explore(find=(FIND_ADDR,), avoid=(AVOID_ADDR,))

found = ex.found[0] 
flag = found.solver.eval(state.memory.load(INPUT_ADDR, INPUT_LENGTH), cast_to=bytes)
print(flag)

if __name__ == '__main__':
main()
总结  通过以上四道例题,相信大家对angr的内存寄存器有一定的了解,如果有必要,我们可以另设一个起始状态,然后设置好所需的参数。
  下面后介绍angr中的Hook



温馨提示:
1.如果您喜欢这篇帖子,请给作者点赞评分,点赞会增加帖子的热度,评分会给作者加学币。(评分不会扣掉您的积分,系统每天都会重置您的评分额度)。
2.回复帖子不仅是对作者的认可,还可以获得学币奖励,请尊重他人的劳动成果,拒绝做伸手党!
3.发广告、灌水回复等违规行为一经发现直接禁言,如果本帖内容涉嫌违规,请点击论坛底部的举报反馈按钮,也可以在【投诉建议】板块发帖举报。

小黑屋|手机版|站务邮箱|学逆向论坛 ( 粤ICP备2021023307号 )|网站地图

GMT+8, 2024-4-25 22:49 , Processed in 0.098488 second(s), 42 queries .

Powered by Discuz! X3.4

Copyright © 2001-2021, Tencent Cloud.

快速回复 返回顶部 返回列表