def test_fucked_extract(): not_fucked = claripy.Reverse(claripy.Concat(claripy.BVS('file_/dev/stdin_6_0_16_8', 8, explicit_name=True), claripy.BVS('file_/dev/stdin_6_1_17_8', 8, explicit_name=True))) m = claripy.backends.vsa.max(not_fucked) assert m > 0 zx = claripy.ZeroExt(16, not_fucked) pre_fucked = claripy.Reverse(zx) m = claripy.backends.vsa.max(pre_fucked) assert m > 0 #print(zx, claripy.backends.vsa.convert(zx)) #print(pre_fucked, claripy.backends.vsa.convert(pre_fucked)) f****d = pre_fucked[31:16] m = claripy.backends.vsa.max(f****d) assert m > 0 # here's another case wtf = ( ( claripy.Reverse( claripy.Concat( claripy.BVS('w', 8), claripy.BVS('x', 8), claripy.BVS('y', 8), claripy.BVS('z', 8) ) ) & claripy.BVV(15, 32) ) + claripy.BVV(48, 32) )[7:0] m = claripy.backends.vsa.max(wtf) assert m > 0
def test_reverse_concat_reverse_simplification(): # Reverse(Concat(Reverse(a), Reverse(b))) = Concat(b, a) a = claripy.BVS('a', 32) b = claripy.BVS('b', 32) x = claripy.Reverse(claripy.Concat(claripy.Reverse(a), claripy.Reverse(b))) nose.tools.assert_equal(x.op, 'Concat') nose.tools.assert_is(x.args[0], b) nose.tools.assert_is(x.args[1], a)
def test_reverse_extract_reverse_simplification(): # without the reverse_extract_reverse simplifier, loading dx from rdx will result in the following complicated # expression: # Reverse(Extract(63, 48, Reverse(BVS('rdx', 64)))) a = claripy.BVS('rdx', 64) dx = claripy.Reverse(claripy.Extract(63, 48, claripy.Reverse(a))) # simplification should have kicked in at this moment nose.tools.assert_equal(dx.op, 'Extract') nose.tools.assert_equal(dx.args[0], 15) nose.tools.assert_equal(dx.args[1], 0) nose.tools.assert_is(dx.args[2], a)
def test_reversed_concat(): a = claripy.SI('a', 32, lower_bound=10, upper_bound=0x80, stride=10) b = claripy.SI('b', 32, lower_bound=1, upper_bound=0xff, stride=1) reversed_a = claripy.Reverse(a) reversed_b = claripy.Reverse(b) # First let's check if the reversing makes sense nose.tools.assert_equal(claripy.backends.vsa.min(reversed_a), 0xa000000) nose.tools.assert_equal(claripy.backends.vsa.max(reversed_a), 0x80000000) nose.tools.assert_equal(claripy.backends.vsa.min(reversed_b), 0x1000000) nose.tools.assert_equal(claripy.backends.vsa.max(reversed_b), 0xff000000) a_concat_b = claripy.Concat(a, b) nose.tools.assert_equal(a_concat_b._model_vsa._reversed, False) ra_concat_b = claripy.Concat(reversed_a, b) nose.tools.assert_equal(ra_concat_b._model_vsa._reversed, False) a_concat_rb = claripy.Concat(a, reversed_b) nose.tools.assert_equal(a_concat_rb._model_vsa._reversed, False) ra_concat_rb = claripy.Concat(reversed_a, reversed_b) nose.tools.assert_equal(ra_concat_rb._model_vsa._reversed, False)
def test_complex_case_0(): # """ <Bool ((0#48 .. Reverse(unconstrained_read_69_16)) << 0x30) <= 0x40000000000000> Created by VEX running on the following x86_64 assembly: cmp word ptr [rdi], 40h ja skip """ x = claripy.BVS('x', 16) expr = ( claripy.ZeroExt(48, claripy.Reverse(x)) << 0x30) <= 0x40000000000000 s, r = claripy.balancer.Balancer(claripy.backends.vsa, expr).compat_ret assert s assert r[0][0] is x assert set(claripy.backends.vsa.eval(r[0][1], 1000)) == set( range(0, 65 * 0x100, 0x100))
def get_writing_mem_formulas(old_state, new_state, valid_mem_addrs: set = None): if valid_mem_addrs is None or len(valid_mem_addrs) == 0: changed_mem_addr_set = new_state.memory.changed_bytes( old_state.memory) else: # the memory needs to be read is fixed changed_mem_addr_set = valid_mem_addrs # here are changed bytes, we need to merge continuous bytes. # fortunately, angr symbolizes the bytes being used in continuous way. formulas = [] # continuous bytes use the same formula, save the string in right_side to avoid redundancy. right_sides = set() for addr in changed_mem_addr_set: if valid_mem_addrs and addr not in valid_mem_addrs: continue if new_state.memory.mem[addr] is None: continue # the changed value is in mem[addr].object, use ('mem_%x' % addr) as the left side of equations if str(new_state.memory.mem[addr].object) in right_sides: continue right_sides.add(str(new_state.memory.mem[addr].object)) left_side_name = 'mem_%x' % addr # because of big and little end arch, the mem may have 'Reverse' operation at the very beginning. Ignore it. right_side_ast = new_state.memory.mem[addr].object # if the first op is Reverse, this means this memory points to an object with more than 1 bytes # we only use the formulas, so we simply remove this Reverse if right_side_ast.op == 'Reverse': right_side_ast = right_side_ast.args[0] # if the project is little end, we need to reverse the constant value if right_side_ast.depth == 1 and isinstance( right_side_ast, BV) and not right_side_ast.symbolic: right_side_ast = claripy.Reverse(right_side_ast) formulas.append((left_side_name, right_side_ast)) return formulas
def do_start(state): params = {} import claripy params['f'] = claripy.Reverse(state.memory.load(state.regs.rsp - 12, 4)) return params