def test_simplify_dead_assign_0(): block = ailment.Block(0x1337, 10) n = count() important = 0x999 block.statements.extend( [ ailment.Assignment( next(n), ailment.Register(next(n), None, 1, 64), ailment.Const(next(n), None, 100, 64), ins_addr=0x1337, ), ailment.Assignment( important, ailment.Register(next(n), None, 1, 64), ailment.Const(next(n), None, 101, 64), ins_addr=0x1338, ), ailment.Stmt.Jump( next(n), ailment.Expr.Const(None, None, 0x3333, 64), ins_addr=0x1338 ), ] ) b = block_simplify(block) nose.tools.assert_equal(len(b.statements), 2) nose.tools.assert_equal(b.statements[0].idx, important)
def test_simplify_dead_assign_1(): # if a register is used ever, it should not be simplified away arch = archinfo.arch_from_id('AMD64') block = ailment.Block(0x1337, 10) n = count(start=1) important = 0x999 block.statements.extend([ ailment.Assignment( next(n), ailment.Register(next(n), None, arch.registers['rdi'][0], 64), ailment.Const(next(n), None, 0x13371337, 64), ins_addr=0x1337, ), # rdi = 0x13371337 ailment.Stmt.Call( important, ailment.Const(next(n), None, 0x400080, 64), ins_addr=0x1338, ), # Call(0x400080), which uses rdi but also overwrites rdi (since it is a caller-saved argument) ]) b = block_simplify(block) nose.tools.assert_equal(len(b.statements), 2) nose.tools.assert_equal(b.statements[0].idx, 1) nose.tools.assert_equal(b.statements[1].idx, important)
def test_constant_dereference(): # a = *(A) :=> a = the variable at at A iff # - A is a pointer that points to a read-only section. proj = angr.Project(os.path.join(test_location, "armel", "decompiler", "rm"), auto_load_libs=False) stmt = ailment.Assignment( None, ailment.Register(None, None, proj.arch.registers['r0'][0], proj.arch.registers['r0'][1] * proj.arch.byte_width, ins_addr=0x400100), ailment.Expr.Load( None, ailment.Expr.Const(None, None, 0xa000, proj.arch.bits), proj.arch.bytes, archinfo.Endness.LE), ins_addr=0x400100, ) opt = ConstantDereferences(proj) optimized = opt.optimize(stmt) assert isinstance(optimized, ailment.Assignment) assert optimized.dst is stmt.dst assert isinstance(optimized.src, ailment.Const) assert optimized.src.value == 0x183f8 assert optimized.tags.get( 'ins_addr', None) == 0x400100, "Peephole optimizer lost tags." # multiple cases that no optimization should happen # a. Loading a pointer from a writable location stmt = ailment.Assignment( None, ailment.Register(None, None, proj.arch.registers['r0'][0], 1, ins_addr=0x400100), ailment.Expr.Load( None, ailment.Expr.Const(None, None, 0x21df4, proj.arch.bits), 1, archinfo.Endness.LE), ins_addr=0x400100, ) opt = ConstantDereferences(proj) optimized = opt.optimize(stmt) assert optimized is None
def test_simplify_pointless_assign(): arch = archinfo.arch_from_id('AMD64') block = ailment.Block(0x1337, 10) block.statements.append( ailment.Assignment( 0, ailment.Register(1, None, arch.registers['rax'][0], 64), ailment.Register(2, None, arch.registers['rax'][0], 64), ins_addr=0x1337, )) block.statements.append( ailment.Assignment( 3, ailment.Register(4, None, arch.registers['rbx'][0], 64), ailment.Register(5, None, arch.registers['rcx'][0], 64), ins_addr=0x1338, )) b = block_simplify(block) nose.tools.assert_equal(len(b.statements), 1) nose.tools.assert_equal(b.statements[0].idx, 3)