06.change symbolic in heap
再来复习一下流程
1.建立项目
p=angr.Project(path)
2.设置入口
state=p.factory.blank_state(0xffffffff)
3.设置符号对象
pw=claripy.BVS('pw',64)
4.这次是把符号放到堆上,于是可以自己创个新的堆就好了
(1).给新的堆一个地址
(2).给新的指向堆的指针一个地址
(3).大端序改成小端序
5.把符号对象保存到新的堆上
state.memory.store(fake_heap_address0,pw)
6.模拟器获得状态
simulation = project.factory.simgr(state)
7.开始执行
simulation.explore(find=is_successful, avoid=should_abort)
8.找到了的处理
solution_state = simulation.found[0]
solution0 = solution_state.se.eval(pw,cast_to=bytes)
即获得了正确输入solution
07.change symblic in file
1.找入口
start_address = 0x080488e7 #memset的后一条指令
2.设置符号
password = claripy.BVS('password', symbolic_file_size_bytes * 8)
3.设置模拟文件的名称,读取的大小,创建模拟文件
filename = "OJKSQYDP.txt"
symbolic_file_size_bytes = 8
password_file = angr.storage.SimFile(filename, content=password)
4.将simfile插入到状态里面
initial_state.fs.insert(filename, password_file)
5.后面步骤相同:为项目设置模拟器,模拟器设置状态;模拟器explore;simulation.found取解
08.提前比较
这个例子是为了在输出Good Job之前就进行比较,可以减少for循环逐字比较带来的复杂度(angr进入库函数并不会带来额外的路径,它会仅仅将库函数作为一个返回约束条件的东西。因此只有自定义fori循环会添加路径,而strncmp函数不会)
1.设置入口
这里设在为buffer开辟空间之后
2.将缓冲区地址存入状态
password_address = 0x0804A050 #输入缓冲区地址
initial_state.memory.store(password_address, password)
3.设置模拟器,开始运行到指定地址,这个指定地址在for循环之前
simulation = project.factory.simgr(initial_state)
address_to_check_constraint =0x0804866E
simulation.explore(find=address_to_check_constraint)
4.到达之后,进行比较:先取出缓冲区数据,再添加约束
(1)取出缓冲区数据
if simulation.found:
solution_state = simulation.found[0]
constrained_parameter_address = 0x0804A050
constrained_parameter_size_bytes = 16
constrained_parameter_bitvector = solution_state.memory.load(
constrained_parameter_address,
constrained_parameter_size_bytes
)
(2)设置比较值
constrained_parameter_desired_value ="AUPDNNPROEZRJWKB"
(3)添加约束,添加解
solution_state.add_constraints(constrained_parameter_bitvector == constrained_parameter_desired_value)
solution = solution_state.solver.eval(password,cast_to=bytes).decode()
09.钩子
这个例子是为了添加一个钩子替代一个fori循环的call
1.设置入口,可以从头开始
2.设置断点,即断掉哪个函数
check_equals_called_address = 0x80486b3
3.这个函数要跳多少条指令
instruction_to_skip_length = 5
4.设置钩子,跳掉,添加自己的函数处理
@project.hook(check_equals_called_address, length=instruction_to_skip_length)
def skip_check_equals_(state): #hook函数
user_input_buffer_address = 0x804a054 #加载用户输入
user_input_buffer_length = 16
user_input_string = state.memory.load(
user_input_buffer_address,
user_input_buffer_length
)
check_against_string ='XYMKBKUHNIQYNQXE'#手动比较,由于反编译发现原来的函数将比较结果保存到eax,所以设置eax
state.regs.eax = claripy.If(
user_input_string == check_against_string,
claripy.BVV(1, 32), #相当于三元比较,如果相等,则填充数值为1的位向量到寄存器,否则填充0位向量
claripy.BVV(0, 32)
)
5.后面流程相似,添加模拟器和状态,if检查found,state.posix.dumps(0)获取键盘输入
simulation = project.factory.simgr(initial_state)
def is_successful(state):
stdout_output = state.posix.dumps(sys.stdout.fileno())
return b'Good Job.' in state.posix.dumps(1)
def should_abort(state):
stdout_output = state.posix.dumps(sys.stdout.fileno())
return b'Try again.' in state.posix.dumps(1)
simulation.explore(find=is_successful, avoid=should_abort)
if simulation.found:
solution_state = simulation.found[0]``
solution = solution_state.posix.dumps(0)
print(solution)
else:
raise Exception('Could not find the solution')
10.simProcedure
这里是为了模拟一个过程,即每次到达这个地址,都不用原函数,而使用自定义函数
1.设置项目,入口
path_to_binary = "E:\\A_reverse\\angr_ctf-master\\dist\\10_angr_simprocedures"
project = angr.Project(path_to_binary)
initial_state = project.factory.entry_state()
2.设置替代函数
class ReplacementCheckEquals(angr.SimProcedure):
def run(self, addr, size):
user_input_buffer_address =addr
user_input_buffer_length = size
user_input_string = self.state.memory.load(
user_input_buffer_address,
user_input_buffer_length
)
check_against_string = 'ORSDDWXHZURJRBDH'
return claripy.If(check_against_string==user_input_string, claripy.BVV(1, 32),
claripy.BVV(0, 32))
3.代替操作
check_equals_symbol = 'check_equals_ORSDDWXHZURJRBDH' #要替代的函数的名字
project.hook_symbol(check_equals_symbol, ReplacementCheckEquals())
4.后面操作不变
simulation = project.factory.simgr(initial_state)
def is_successful(state):
stdout_output = state.posix.dumps(sys.stdout.fileno())
return b'Good Job.' in state.posix.dumps(1)
def should_abort(state):
stdout_output = state.posix.dumps(sys.stdout.fileno())
return b'Try again.' in state.posix.dumps(1)
simulation.explore(find=is_successful, avoid=should_abort)
if simulation.found:
solution_state = simulation.found[0]
solution =solution_state.posix.dumps(0)
print(solution)
else:
raise Exception('Could not find the solution')
标签:Ange,06,10,solution,simulation,state,address,input,check
From: https://www.cnblogs.com/ljyink/p/18262618