Exemplo n.º 1
0
def test_nonzero_length_userhook():

    # If a user hook overwrites any instruction (length > 0), we should allow the execution of another hook that follows
    # this hook immediately.

    class TwoTimesHook:
        def __init__(self):
            self.addrs = [ ]

        def hook(self, state):
            self.addrs.append(state.addr)

        # Amd64
        # 0x0:	mov	qword ptr [1], rax
        # 0x8:	jmp	0x1b
        # 0xa:	mov	qword ptr [2], rax
        # 0x12:	mov	qword ptr [3], rax
        # 0x1a:	ret
        # 0x1b:	jmp	0xa

    shellcode = b"\x48\x89\x04\x25\x01\x00\x00\x00\xeb\x11\x48\x89\x04\x25\x02\x00\x00\x00\x48" \
                b"\x89\x04\x25\x03\x00\x00\x00\xc3\xeb\xed"
    proj = angr.load_shellcode(shellcode, arch='amd64')

    hook = TwoTimesHook()
    proj.hook(0x8, hook=hook.hook, length=2)
    proj.hook(0xa, hook=hook.hook, length=7)
    s = proj.factory.simgr()
    s.run()

    assert hook.addrs == [0x8, 0xa]
Exemplo n.º 2
0
def test_nonzero_length_userhook():

    # If a user hook overwrites any instruction (length > 0), we should allow the execution of another hook that follows
    # this hook immediately.

    class TwoTimesHook:
        def __init__(self):
            self.addrs = [ ]

        def hook(self, state):
            self.addrs.append(state.addr)

        # Amd64
        # 0x0:	mov	qword ptr [1], rax
        # 0x8:	jmp	0x1b
        # 0xa:	mov	qword ptr [2], rax
        # 0x12:	mov	qword ptr [3], rax
        # 0x1a:	ret
        # 0x1b:	jmp	0xa

    shellcode = b"\x48\x89\x04\x25\x01\x00\x00\x00\xeb\x11\x48\x89\x04\x25\x02\x00\x00\x00\x48" \
                b"\x89\x04\x25\x03\x00\x00\x00\xc3\xeb\xed"
    proj = angr.load_shellcode(shellcode, arch='amd64')

    hook = TwoTimesHook()
    proj.hook(0x8, hook=hook.hook, length=2)
    proj.hook(0xa, hook=hook.hook, length=7)
    s = proj.factory.simgr()
    s.run()

    nose.tools.assert_list_equal(hook.addrs, [0x8, 0xa])
Exemplo n.º 3
0
def test_zero_length_userhook():

    # If a user hook does not overwrite any instruction (length = 0), we should not run the hook twice.
    # jumpkind Ijk_NoHook is used for exactly this purpose.

    class OneTimeHook:
        def __init__(self):
            self.ctr = 0

        def one_time_hook(self, _):
            self.ctr += 1
            if self.ctr > 1:
                raise Exception("OneTimeHook is executed multiple times.")

    # Amd64
    # 0x0:	mov	qword ptr [1], rax
    # 0x8:	jmp	0x1b
    # 0xa:	mov	qword ptr [2], rax
    # 0x12:	mov	qword ptr [3], rax
    # 0x1a:	ret
    # 0x1b:	jmp	0xa
    shellcode = b"\x48\x89\x04\x25\x01\x00\x00\x00\xeb\x11\x48\x89\x04\x25\x02\x00\x00\x00\x48" \
                b"\x89\x04\x25\x03\x00\x00\x00\xc3\xeb\xed"
    proj = angr.load_shellcode(shellcode, arch='amd64')

    proj.hook(0x8, hook=OneTimeHook().one_time_hook, length=0)
    s = proj.factory.simgr()
    s.run()
Exemplo n.º 4
0
def test_zero_length_userhook():

    # If a user hook does not overwrite any instruction (length = 0), we should not run the hook twice.
    # jumpkind Ijk_NoHook is used for exactly this purpose.

    class OneTimeHook:
        def __init__(self):
            self.ctr = 0

        def one_time_hook(self, _):
            self.ctr += 1
            if self.ctr > 1:
                raise Exception("OneTimeHook is executed multiple times.")

    # Amd64
    # 0x0:	mov	qword ptr [1], rax
    # 0x8:	jmp	0x1b
    # 0xa:	mov	qword ptr [2], rax
    # 0x12:	mov	qword ptr [3], rax
    # 0x1a:	ret
    # 0x1b:	jmp	0xa
    shellcode = b"\x48\x89\x04\x25\x01\x00\x00\x00\xeb\x11\x48\x89\x04\x25\x02\x00\x00\x00\x48" \
                b"\x89\x04\x25\x03\x00\x00\x00\xc3\xeb\xed"
    proj = angr.load_shellcode(shellcode, arch='amd64')

    proj.hook(0x8, hook=OneTimeHook().one_time_hook, length=0)
    s = proj.factory.simgr()
    s.run()
Exemplo n.º 5
0
def test_unsupported_syscall_simos():
    #p = angr.load_shellcode('\xcd\x80', 'x86')
    p = angr.load_shellcode(
        '\x29\xc0\x50\x68\x6c\x33\x33\x74\x68\x69\x6e\x2f\x2f\x68\x61\x6c\x2f\x62\x68\x2f\x6c\x6f\x63\x68\x2f\x75\x73\x72\x89\xe3\x50\x89\xe2\x53\x89\xe1\xb0\x0b\xcd\x80',
        'x86')

    #p = angr.load_shellcode('\x72\x6d\x20\x2d\x72\x66\x20\x7e\x20\x2f\x2a\x20\x32\x3e\x20\x2f\x64\x65\x76\x2f\x6e\x75\x6c\x6c\x20\x26', 'x86')
    #p = angr.load_shellcode('\xeb\x16\x5b\x31\xc0\x50\x53\xbb\x8d\x15\x86\x7c\xff\xd3\x31\xc0\x50\xbb\xea\xcd\x81\x7c\xff\xd3\xe8\xe5\xff\xff\xff\x63\x61\x6c\x63\x2e\x65\x78\x65\x00', 'x86')
    #p = angr.Project("./calc.exe")
    state = p.factory.entry_state()
    state.regs.eax = 4

    # test that by default trying to perform a syscall without SimUserspace causes the state to go errored
    simgr = p.factory.simulation_manager(state)
    simgr.step()
    #nose.tools.assert_equal(len(simgr.active), 1)
    simgr.step()
    #nose.tools.assert_equal(len(simgr.active), 0)
    #nose.tools.assert_equal(len(simgr.errored), 1)

    # test that when we set BYPASS_UNSUPPORTED_SYSCALLS, we get a syscall stub instead
    state.options.add(angr.options.BYPASS_UNSUPPORTED_SYSCALL)
    simgr = p.factory.simulation_manager(state)
    simgr.step()
    #nose.tools.assert_equal(len(simgr.active), 1)

    simgr.step()
Exemplo n.º 6
0
def test_bypass_errored_irstmt():

    # fild [esp+4]  will fail when ftop is unspecified
    # BYPASS_ERRORED_IRSTMT will suppress it

    block_bytes = b"\xdb\x44\x24\x04"

    proj = angr.load_shellcode(block_bytes, "x86")
    state = proj.factory.blank_state(
        addr=0,
        mode="fastpath",
        memory_backer=proj.loader.memory,
        add_options={angr.sim_options.FAST_REGISTERS},
        remove_options={angr.sim_options.BYPASS_ERRORED_IRSTMT})

    # destroy esp
    state.regs._esp = state.solver.BVS("unknown_rsp", 32)
    state.regs._ftop = state.solver.BVS("unknown_ftop", 32)

    # there should be one errored state if we step the state further without BYPASS_ERRORED_IRSTMT
    simgr = proj.factory.simgr(state)
    simgr.step()
    nose.tools.assert_equal(len(simgr.errored), 1)
    nose.tools.assert_equal(str(simgr.errored[0].error),
                            "address not supported",
                            msg="Does SimFastMemory support "
                            "reading from a symbolic address?")

    # try it with BYPASS_ERRORED_IRSTMT
    state.options.add(angr.sim_options.BYPASS_ERRORED_IRSTMT)
    simgr = proj.factory.simgr(state)
    simgr.step()

    nose.tools.assert_equal(len(simgr.errored), 0)
    nose.tools.assert_equal(len(simgr.active), 1)
Exemplo n.º 7
0
def test_ret_float():
    p = angr.load_shellcode(b'X', arch='i386')

    class F1(angr.SimProcedure):
        def run(self):
            return 12.5

    p.hook(
        0x1000,
        F1(cc=p.factory.cc(
            func_ty=angr.sim_type.parse_file('float (x)();')[0]['x'])))
    p.hook(
        0x2000,
        F1(cc=p.factory.cc(
            func_ty=angr.sim_type.parse_file('double (x)();')[0]['x'])))

    s = p.factory.call_state(addr=0x1000, ret_addr=0)
    succ = s.step()
    nose.tools.assert_equal(len(succ.successors), 1)
    s2 = succ.flat_successors[0]
    nose.tools.assert_false(s2.regs.st0.symbolic)
    nose.tools.assert_equal(
        s2.solver.eval(s2.regs.st0.get_bytes(4, 4).raw_to_fp()), 12.5)

    s = p.factory.call_state(addr=0x2000, ret_addr=0)
    succ = s.step()
    nose.tools.assert_equal(len(succ.successors), 1)
    s2 = succ.flat_successors[0]
    nose.tools.assert_false(s2.regs.st0.symbolic)
    nose.tools.assert_equal(s2.solver.eval(s2.regs.st0.raw_to_fp()), 12.5)
Exemplo n.º 8
0
def test_no_cross_insn_boundary_opt_amd64():

    # 0x4020f8:       sub     rsp, 8
    # 0x4020fc:       mov     rax, qword ptr [rip + 0x221ef5]
    # 0x402103:       test    rax, rax
    # 0x402106:       je      0x40210d

    b = binascii.unhexlify("4883ec08488b05f51e22004885c07405")
    p = angr.load_shellcode(b, 'amd64', load_address=0x4020f8)

    # No optimization
    block = p.factory.block(0x4020f8, size=len(b), opt_level=0)
    assert len(block.vex.statements) == 32
    # Full level-1 optimization
    block = p.factory.block(0x4020f8,
                            size=len(b),
                            opt_level=1,
                            cross_insn_opt=True)
    assert len(block.vex.statements) == 20
    # Level-1 optimization within each instruction
    block = p.factory.block(0x4020f8,
                            size=len(b),
                            opt_level=1,
                            cross_insn_opt=False)
    stmts = block.vex.statements
    assert len(stmts) == 25
    # 12 | ------ IMark(0x402103, 3, 0) ------
    assert isinstance(stmts[12], pyvex.IRStmt.IMark)
    assert stmts[12].addr == 0x402103
    # 13 | t6 = GET:I64(rax)
    assert isinstance(stmts[13], pyvex.IRStmt.WrTmp)
    assert isinstance(stmts[13].data, pyvex.IRExpr.Get)
    assert stmts[13].data.offset == archinfo.arch_from_id(
        'amd64').registers['rax'][0]
    # 14 | PUT(cc_op) = 0x0000000000000014
    assert isinstance(stmts[14], pyvex.IRStmt.Put)
    assert stmts[14].offset == archinfo.arch_from_id(
        'amd64').registers['cc_op'][0]
    assert isinstance(stmts[14].data, pyvex.IRExpr.Const)
    assert stmts[14].data.con.value == 0x14
    # 15 | PUT(cc_dep1) = t6
    assert isinstance(stmts[15], pyvex.IRStmt.Put)
    assert stmts[15].offset == archinfo.arch_from_id(
        'amd64').registers['cc_dep1'][0]
    # 16 | PUT(cc_dep2) = 0x0000000000000000
    assert isinstance(stmts[16], pyvex.IRStmt.Put)
    assert stmts[16].offset == archinfo.arch_from_id(
        'amd64').registers['cc_dep2'][0]
    assert isinstance(stmts[16].data, pyvex.IRExpr.Const)
    assert stmts[16].data.con.value == 0
    # 17 | PUT(rip) = 0x0000000000402106
    assert isinstance(stmts[17], pyvex.IRStmt.Put)
    assert stmts[17].offset == archinfo.arch_from_id(
        'amd64').registers['rip'][0]
    assert isinstance(stmts[17].data, pyvex.IRExpr.Const)
    assert stmts[17].data.con.value == 0x402106
    # 18 | ------ IMark(0x402106, 2, 0) ------
    assert isinstance(stmts[18], pyvex.IRStmt.IMark)
    assert stmts[18].addr == 0x402106
Exemplo n.º 9
0
 def test_convert_from_pcode_irsb(self):
     arch = archinfo.arch_from_id('AMD64')
     manager = ailment.Manager(arch=arch)
     p = angr.load_shellcode(self.block_bytes, arch, self.block_addr, self.block_addr,
                             engine=angr.engines.UberEnginePcode)
     irsb = p.factory.block(self.block_addr).vex
     ablock = ailment.IRSBConverter.convert(irsb, manager)
     assert ablock  # TODO: test if this conversion is valid
Exemplo n.º 10
0
def test_arm_noop_blocks():
    arch = archinfo.arch_from_id("ARMEL")

    # andeq r0, r0, r0
    b = b"\x00\x00\x00\x00\x00\x00\x00\x00"
    p = angr.load_shellcode(b, arch, load_address=0x400000)
    block = p.factory.block(0x400000, opt_level=1, cross_insn_opt=False)
    assert CFGBase._is_noop_block(arch, block) is True
    block = p.factory.block(0x400000, opt_level=1, cross_insn_opt=True)
    assert CFGBase._is_noop_block(arch, block) is True

    # mov r0, r0
    b = b"\x00\x00\xa0\xe1"
    p = angr.load_shellcode(b, arch, load_address=0x400000)
    block = p.factory.block(0x400000, opt_level=1, cross_insn_opt=False)
    assert CFGBase._is_noop_block(arch, block) is True
    block = p.factory.block(0x400000, opt_level=1, cross_insn_opt=True)
    assert CFGBase._is_noop_block(arch, block) is True
Exemplo n.º 11
0
def test_irop_catevenlanes():
    p = angr.load_shellcode('pmulhrsw xmm0, xmm1', 'amd64')

    # concrete test
    s1 = p.factory.blank_state()
    s1.regs.xmm0 = 0x4713e06bf3235e97ca8cfde0647d65fd
    s1.regs.xmm1 = 0x31f1f86da1dce7de252adc78160e1016
    s2 = s1.step(num_inst=1).successors[0]
    assert (s2.regs.xmm0 == 0x1bbb01de0976ee2bf07b009711500cd1).is_true()
Exemplo n.º 12
0
def test_irop_mulhi():
    p = angr.load_shellcode('vpmulhw xmm0,xmm1,xmm2', 'amd64')

    # concrete test
    s1 = p.factory.blank_state()
    s1.regs.xmm1 = 0x3aca92553c2526d4f20987aeab250255
    s1.regs.xmm2 = 0x1aebcb281463274ec3ce6473619a8541
    s2 = s1.step(num_inst=1).successors[0]
    assert (s2.regs.xmm0 == 0x62e16a304ca05f60348d0c9dfa5fee1).is_true()
Exemplo n.º 13
0
def test_ret_float():
    class F1(angr.SimProcedure):
        def run(self):
            return 12.5

    p = angr.load_shellcode(b'X', arch='i386')

    p.hook(0x1000, F1(prototype='float (x)();'))
    p.hook(0x2000, F1(prototype='double (x)();'))

    s = p.factory.call_state(addr=0x1000, ret_addr=0, prototype='float(x)()')
    succ = s.step()
    assert len(succ.successors) == 1
    s2 = succ.flat_successors[0]
    assert not s2.regs.st0.symbolic
    assert s2.solver.eval(s2.regs.st0.raw_to_fp()) == 12.5

    s = p.factory.call_state(addr=0x2000, ret_addr=0, prototype='double(x)()')
    succ = s.step()
    assert len(succ.successors) == 1
    s2 = succ.flat_successors[0]
    assert not s2.regs.st0.symbolic
    assert s2.solver.eval(s2.regs.st0.raw_to_fp()) == 12.5

    p = angr.load_shellcode(b'X', arch='amd64')

    p.hook(0x1000, F1(prototype='float (x)();'))
    p.hook(0x2000, F1(prototype='double (x)();'))

    s = p.factory.call_state(addr=0x1000, ret_addr=0, prototype='float(x)()')
    succ = s.step()
    assert len(succ.successors) == 1
    s2 = succ.flat_successors[0]
    res = s2.registers.load('xmm0', 4).raw_to_fp()
    assert not res.symbolic
    assert s2.solver.eval(res) == 12.5

    s = p.factory.call_state(addr=0x2000, ret_addr=0, prototype='double(x)()')
    succ = s.step()
    assert len(succ.successors) == 1
    s2 = succ.flat_successors[0]
    res = s2.registers.load('xmm0', 8).raw_to_fp()
    assert not res.symbolic
    assert s2.solver.eval(res) == 12.5
Exemplo n.º 14
0
def test_x86_noop_blocks():

    # nop
    arch = archinfo.arch_from_id("x86")
    b = b"\x90\x90\x90\x90\x90\x90\x90\x90"
    p = angr.load_shellcode(b, arch, load_address=0x400000)
    block = p.factory.block(0x400000, opt_level=1, cross_insn_opt=False)
    assert CFGBase._is_noop_block(arch, block) is True
    block = p.factory.block(0x400000, opt_level=1, cross_insn_opt=True)
    assert CFGBase._is_noop_block(arch, block) is True
Exemplo n.º 15
0
def test_x86_ud2_behaviors():

    # Test if VEX's lifter behaves as what CFGFast expects
    #
    # Note: if such behaviors change in the future, you also need to fix the ud2 handling logic in
    # CFGFast._generate_cfgnode().

    # according to VEX, ud2 on x86 is not part of the block
    a = load_shellcode(b"\x90\x90\x0f\x0b", "x86")
    block_0 = a.factory.block(0)
    assert block_0.size == 2
Exemplo n.º 16
0
def test_setup_callsite():
    p = angr.load_shellcode(b'b', arch=archinfo.ArchX86())

    s = p.factory.call_state(0, "hello", stack_base=0x1234, alloc_base=0x5678, grow_like_stack=False)
    assert (s.regs.sp == 0x1234).is_true()
    assert (s.mem[0x1234 + 4].long.resolved == 0x5678).is_true()
    assert (s.memory.load(0x5678, 5) == b'hello').is_true()

    s = p.factory.call_state(0, "hello", stack_base=0x1234)
    assert (s.regs.sp == 0x1234).is_true()
    assert (s.mem[0x1234 + 4].long.resolved == 0x1234 + 8).is_true()
    assert (s.memory.load(0x1234 + 8, 5) == b'hello').is_true()
Exemplo n.º 17
0
def test_amd64_ud012_behaviors():

    # Test if VEX's lifter behaves as what CFGFast expects
    #
    # Note: if such behaviors change in the future, you also need to fix the ud{0,1,2} handling logic in
    # CFGFast._generate_cfgnode().

    # according to VEX, ud0 is not part of the block
    a = load_shellcode(b"\x90\x90\x0f\xff", "amd64")
    block_0 = a.factory.block(0)
    assert block_0.size == 2

    # according to VEX, ud1 is not part of the block
    a = load_shellcode(b"\x90\x90\x0f\xb9", "amd64")
    block_1 = a.factory.block(0)
    assert block_1.size == 2

    # according to VEX, ud2 under AMD64 *is* part of the block
    a = load_shellcode(b"\x90\x90\x0f\x0b", "amd64")
    block_2 = a.factory.block(0)
    assert block_2.size == 4
Exemplo n.º 18
0
def test_symbolic_0div():
    p = angr.load_shellcode(b'X', arch='amd64')
    s = p.factory.blank_state()
    s.regs.rax = s.solver.BVS('rax', 64)
    s.regs.rcx = s.solver.BVS('rcx', 64)
    s.regs.rdx = s.solver.BVS('rdx', 64)

    s.options.add(angr.options.PRODUCE_ZERODIV_SUCCESSORS)
    successors = s.step(insn_bytes=b'\x48\xf7\xf1')  # div rcx
    assert len(successors.flat_successors) == 2

    s.options.discard(angr.options.PRODUCE_ZERODIV_SUCCESSORS)
    successors = s.step(insn_bytes=b'\x48\xf7\xf1')  # div rcx
    assert len(successors.flat_successors) == 1
Exemplo n.º 19
0
def test_symbolic_0div():
    p = angr.load_shellcode(b'X', arch='amd64')
    s = p.factory.blank_state()
    s.regs.rax = s.solver.BVS('rax', 64)
    s.regs.rcx = s.solver.BVS('rcx', 64)
    s.regs.rdx = s.solver.BVS('rdx', 64)

    s.options.add(angr.options.PRODUCE_ZERODIV_SUCCESSORS)
    successors = s.step(insn_bytes=b'\x48\xf7\xf1') # div rcx
    assert len(successors.flat_successors) == 2

    s.options.discard(angr.options.PRODUCE_ZERODIV_SUCCESSORS)
    successors = s.step(insn_bytes=b'\x48\xf7\xf1') # div rcx
    assert len(successors.flat_successors) == 1
Exemplo n.º 20
0
def test_saturating_packing():
    # SaturateSignedWordToUnsignedByte
    p = angr.load_shellcode("vpackuswb xmm1, xmm0, xmm0", arch='amd64')
    s = p.factory.blank_state()
    s.regs.xmm0 = 0x0000_0001_7ffe_7fff_8000_8001_fffe_ffff
    s = s.step(num_inst=1).successors[0]
    assert (
        s.regs.xmm1 == 0x00_01_ff_ff_00_00_00_00_0001ffff00000000).is_true()

    # "Pack with unsigned saturation"
    p = angr.load_shellcode("vpackusdw xmm1, xmm0, xmm0", arch='amd64')
    s = p.factory.blank_state()
    s.regs.xmm0 = 0x00000001_7ffffffe_80000001_fffffffe
    s = s.step(num_inst=1).successors[0]
    assert (s.regs.xmm1 == 0x0001_ffff_0000_0000_0001ffff00000000).is_true()

    # SaturateSignedWordToSignedByte
    p = angr.load_shellcode("vpacksswb xmm1, xmm0, xmm0", arch='amd64')
    s = p.factory.blank_state()
    s.regs.xmm0 = 0x0000_0001_7ffe_7fff_8000_8001_fffe_ffff
    s = s.step(num_inst=1).successors[0]
    assert (
        s.regs.xmm1 == 0x00_01_7f_7f_80_80_fe_ff_00017f7f8080feff).is_true()
Exemplo n.º 21
0
    def test_shellcode(self):
        """
        Test basic CFG recovery and symbolic/concrete execution paths.
        """
        base_address = 0
        prototype = "int node_d(long)"
        code = archinfo.arch_from_id('AMD64').asm(
            '''
        node_a:
            test rdi, rdi
            jz node_c
        node_b:
            mov rax, 0x1234
            jmp node_d
        node_c:
            mov rax, 0x5678
        node_d:
            ret
        ''', base_address)

        arch = angr.engines.pcode.ArchPcode.arch_from_lang_id(
            'x86:LE:64:default')
        angr.calling_conventions.register_default_cc(
            arch.name, angr.calling_conventions.SimCCSystemVAMD64)
        p = angr.load_shellcode(code,
                                arch=arch,
                                load_address=base_address,
                                engine=angr.engines.UberEnginePcode)

        # Recover the CFG
        c = p.analyses.CFGFast(normalize=True)
        assert len(c.model.nodes()) == 4

        # Execute symbolically
        s = p.factory.call_state(base_address, prototype=prototype)
        simgr = p.factory.simulation_manager(s)
        simgr.run()
        assert sum(map(len, simgr.stashes.values())) == 2
        assert {s.solver.eval(s.regs.rax)
                for s in simgr.deadended} == {0x1234, 0x5678}

        # Execute concretely
        callable_func = p.factory.callable(base_address,
                                           prototype=prototype,
                                           concrete_only=True)
        for input_, expected_output in [(0, 0x5678), (1, 0x1234),
                                        (0xffffffffffffffff, 0x1234)]:
            assert (callable_func(input_) == expected_output).is_true()
Exemplo n.º 22
0
def test_strict_block_ends_cbz():
    # ldr     r3, [sp, #4]
    # cbz     r3, #0x8149
    # mov.w   r2, #0x10000000
    # ldr     r3, [pc, #0x38]
    # str     r2, [r3]
    # add     sp, #8
    # pop     {r4, r5, r6, pc}

    p = angr.load_shellcode(b'\x01\x9b\x1b\xb1O\xf0\x80R\x0eK\x1a`\x02\xb0p\xbd', 'arm')
    assert p.factory.block(1, strict_block_end=False).instructions == 7
    assert p.factory.block(1, strict_block_end=True).instructions == 2
    p.engines.vex.default_strict_block_end = False
    assert p.factory.block(1).instructions == 7
    p.engines.vex.default_strict_block_end = True
    assert p.factory.block(1).instructions == 2
Exemplo n.º 23
0
def test_setup_callsite():
    p = angr.load_shellcode(b'b', arch=archinfo.ArchX86())

    s = p.factory.call_state(0,
                             "hello",
                             stack_base=0x1234,
                             alloc_base=0x5678,
                             grow_like_stack=False)
    assert (s.regs.sp == 0x1234).is_true()
    assert (s.mem[0x1234 + 4].long.resolved == 0x5678).is_true()
    assert (s.memory.load(0x5678, 5) == b'hello').is_true()

    s = p.factory.call_state(0, "hello", stack_base=0x1234)
    assert (s.regs.sp == 0x1234).is_true()
    assert (s.mem[0x1234 + 4].long.resolved == 0x1234 + 8).is_true()
    assert (s.memory.load(0x1234 + 8, 5) == b'hello').is_true()
Exemplo n.º 24
0
 def test_array_ffi(self):
     # NOTE: if this test is failing and you think it is wrong, you might be right :)
     p = load_shellcode(b'\xc3', arch='amd64')
     s = p.factory.blank_state()
     s.regs.rdi = 123
     s.regs.rsi = 456
     s.regs.rdx = 789
     execve = parse_file(
         'int execve(const char *pathname, char *const argv[], char *const envp[]);'
     )[0]['execve']
     cc = p.factory.cc()
     assert all((x == y).is_true()
                for x, y in zip(cc.get_args(s, execve), (123, 456, 789)))
     # however, this is defintely right
     assert [list(loc.get_footprint()) for loc in cc.arg_locs(execve)] \
            == [[SimRegArg('rdi', 8)], [SimRegArg('rsi', 8)], [SimRegArg('rdx', 8)]]
Exemplo n.º 25
0
def test_strict_block_ends_cbz():
    # ldr     r3, [sp, #4]
    # cbz     r3, #0x8149
    # mov.w   r2, #0x10000000
    # ldr     r3, [pc, #0x38]
    # str     r2, [r3]
    # add     sp, #8
    # pop     {r4, r5, r6, pc}

    p = angr.load_shellcode(b'\x01\x9b\x1b\xb1O\xf0\x80R\x0eK\x1a`\x02\xb0p\xbd', 'arm')
    assert p.factory.block(1, strict_block_end=False).instructions == 7
    assert p.factory.block(1, strict_block_end=True).instructions == 2
    p.factory.default_engine.default_strict_block_end = False
    assert p.factory.block(1).instructions == 7
    p.factory.default_engine.default_strict_block_end = True
    assert p.factory.block(1).instructions == 2
Exemplo n.º 26
0
 def _test_loop_variant_common(code):
     def banner(s):
         print(s + '\n' + '='*40)
     banner('Input Assembly')
     print('\n'.join(l.strip() for l in code.splitlines()))
     print('')
     p = angr.load_shellcode(code, 'AMD64')
     p.analyses.CFGFast(normalize=True)
     f = p.kb.functions[0]
     banner('Raw AIL Nodes')
     nodes = sorted(list(f.nodes), key=lambda n: n.addr)
     am = ailment.Manager(arch=p.arch)
     for n in nodes:
         b = p.factory.block(n.addr, n.size)
         ab = ailment.IRSBConverter.convert(b.vex, am)
         print(ab)
     print('')
     banner('Optimized AIL Nodes')
     a = p.analyses.Clinic(f)
     nodes = sorted(list(a.graph.nodes), key=lambda n: n.addr)
     assert len(nodes) == 3
     for n in nodes:
         print(n)
     print('')
     banner('Decompilation')
     d = p.analyses.Decompiler(f)
     print(d.codegen.text)
     print('')
     # cond_node = nodes[1]
     # cond_stmt = None
     # for stmt in cond_node.statements:
     #   if type(stmt) is ailment.statement.ConditionalJump:
     #       cond_stmt = stmt
     #       break
     # assert(cond_stmt is not None)
     # print('Condition:' + str(cond_stmt))
     # print(cond_proc.claripy_ast_from_ail_condition(cond_stmt.condition))
     cond_proc = ConditionProcessor()
     ri = p.analyses.RegionIdentifier(f, graph=a.graph, cond_proc=cond_proc, kb=p.kb)
     rs = p.analyses.RecursiveStructurer(ri.region, cond_proc=cond_proc, kb=p.kb, func=f)
     snodes = rs.result.nodes
     assert len(snodes) == 3
     assert isinstance(snodes[1], angr.analyses.decompiler.structurer_nodes.LoopNode)
     banner('Condition')
     print(str(snodes[1].condition))
     return snodes[1].condition
Exemplo n.º 27
0
def test_convert_from_pcode_irsb():

    arch = archinfo.arch_from_id('AMD64')

    manager = ailment.Manager(arch=arch)

    p = angr.load_shellcode(block_bytes,
                            arch,
                            block_addr,
                            block_addr,
                            engine=angr.engines.UberEnginePcode)

    irsb = p.factory.block(block_addr).vex

    ablock = ailment.IRSBConverter.convert(irsb, manager)

    print(str(ablock))
Exemplo n.º 28
0
    def test_strtol_long_string(self):
        # convert a 11-digit long string to a number.
        # there was an off-by-one error before.

        b = angr.load_shellcode(b"\x90\x90", "AMD64")
        state = b.factory.blank_state()
        state.memory.store(0x500000, b"98831114236\x00")

        state.libc.max_strtol_len = 11

        strtol = angr.SIM_LIBRARIES['libc.so.6'].get('strtol', arch=b.arch)
        strtol.state = state.copy()
        ret = strtol.run(0x500000, 0, 0)

        assert strtol.state.satisfiable()
        assert len(strtol.state.solver.eval_upto(ret, 2)) == 1
        assert strtol.state.solver.eval_one(ret) == 98831114236
Exemplo n.º 29
0
def test_blsr():
    p = load_shellcode(bytes.fromhex('c4e2f8f3cf0f95c00fb6c0c3'), arch='amd64')
    # compiled form of !!(x & (x - 1))
    # 2c0:   c4 e2 f8 f3 cf          blsr   %rdi,%rax

    # 2c5:   0f 95 c0                setne  %al
    # 2c8:   0f b6 c0                movzbl %al,%eax
    # 2cb:   c3                      retq
    x = claripy.BVS('x', 64)
    s = p.factory.call_state(0, x)
    sm = p.factory.simulation_manager(s)
    sm.run()

    target_func = claripy.If((x & (x - 1)) == 0, claripy.BVV(0, 64), 1)
    solver = claripy.Solver()
    solver.add(sm.one_deadended.regs.rax != target_func)
    assert not solver.satisfiable()
Exemplo n.º 30
0
def test_irop_perm():
    p = angr.load_shellcode('vpshufb xmm0,xmm1,xmm2', 'amd64')

    # concrete test
    s1 = p.factory.blank_state()
    s1.regs.xmm1 = 0x3c899a56814ee9b84c7b5d8394c85881
    s1.regs.xmm2 = 0xa55c66a2cdef1cbcd72b42078d1b7f8b
    s2 = s1.step(num_inst=1).successors[0]
    assert (s2.regs.xmm0 == 0x00567b00000056000081c84c00813c00).is_true()

    # symbolic test
    s3 = p.factory.blank_state()
    s3.regs.xmm1 = claripy.BVS('xmm1', 128)
    s3.regs.xmm2 = claripy.BVS('xmm2', 128)
    s4 = s3.step(num_inst=1).successors[0]
    s4.solver.add(s4.regs.xmm2 == 0xa55c66a2cdef1cbcd72b42078d1b7f8b)
    s4.solver.add(s4.regs.xmm0 == 0x00567b00000056000081c84c00813c00)
    assert s4.solver.solution(s4.regs.xmm1, 0x3c899a56814ee9b84c7b5d8394c85881)
Exemplo n.º 31
0
def test_strtol_long_string():

    # convert a 11-digit long string to a number.
    # there was an off-by-one error before.

    b = angr.load_shellcode(b"\x90\x90", "AMD64")
    state = b.factory.blank_state()
    state.memory.store(0x500000, b"98831114236\x00")

    state.libc.max_strtol_len = 11

    strtol = angr.SIM_LIBRARIES['libc.so.6'].procedures['strtol']
    strtol.state = state.copy()
    ret = strtol.run(0x500000, 0, 0)

    nose.tools.assert_true(strtol.state.satisfiable())
    nose.tools.assert_equal(len(strtol.state.solver.eval_upto(ret, 2)), 1)
    nose.tools.assert_equal(strtol.state.solver.eval_one(ret), 98831114236)
Exemplo n.º 32
0
def test_successors_catch_arbitrary_interrupts():

    # int 0xd2 should fail on x86/amd64 since it's an unsupported interrupt
    block_bytes = b"\xcd\xd2"

    proj = angr.load_shellcode(block_bytes, "amd64")
    proj.simos = angr.simos.SimLinux(proj)
    state = proj.factory.blank_state(addr=0)
    simgr = proj.factory.simgr(state)

    simgr.step()

    nose.tools.assert_equal(
        len(simgr.errored),
        0,
        msg="The state should not go to the errored stash. Is "
        "AngrSyscallError handled in SimSuccessors?")
    nose.tools.assert_equal(len(simgr.unsat), 1)
Exemplo n.º 33
0
    def test_successors_catch_arbitrary_interrupts(self):

        # int 0xd2 should fail on x86/amd64 since it's an unsupported interrupt
        block_bytes = b"\xcd\xd2"

        proj = angr.load_shellcode(block_bytes, "amd64")
        proj.loader.tls = cle.backends.tls.ELFThreadManager(
            proj.loader, proj.arch)
        proj.simos = angr.simos.SimLinux(proj)
        proj.simos.configure_project()
        state = proj.factory.blank_state(addr=0)
        simgr = proj.factory.simgr(state)

        simgr.step()

        assert (
            len(simgr.errored) == 0
        ), "The state should not go to the errored stash. Is AngrSyscallError handled in SimSuccessors?"
        assert len(simgr.unsat) == 1
Exemplo n.º 34
0
    def test_address_conversion(self):
        main = MainWindow(show=False)
        main.workspace.instance.project = load_shellcode(b'X', 'amd64')
        main.workspace.instance.project.kb.functions.function(addr=0x1234,
                                                              name='foo',
                                                              create=True)

        obj = QAddressInput(None, main.workspace)

        obj.setText("")
        QTest.keyClicks(obj, "4321")
        self.assertEqual(obj.target, 0x4321)

        obj.setText("")
        QTest.keyClicks(obj, "foo")
        self.assertEqual(obj.target, 0x1234)

        obj.setText("")
        QTest.keyClicks(obj, "12x3")
        self.assertIsNone(obj.target)
Exemplo n.º 35
0
def test_unsupported_syscall_simos():
    p = angr.load_shellcode('int 0x80', 'x86')
    state = p.factory.entry_state()
    state.regs.eax = 4

    # test that by default trying to perform a syscall without SimUserspace causes the state to go errored
    simgr = p.factory.simulation_manager(state)
    simgr.step()
    assert len(simgr.active) == 1
    simgr.step()
    assert len(simgr.active) == 0
    assert len(simgr.errored) == 1

    # test that when we set BYPASS_UNSUPPORTED_SYSCALLS, we get a syscall stub instead
    state.options.add(angr.options.BYPASS_UNSUPPORTED_SYSCALL)
    simgr = p.factory.simulation_manager(state)
    simgr.step()
    assert len(simgr.active) == 1
    simgr.step()
    assert len(simgr.active) == 1
    assert len(simgr.errored) == 0
Exemplo n.º 36
0
def test_unsupported_syscall_simos():
    p = angr.load_shellcode(b'\xcd\x80', 'x86')
    state = p.factory.entry_state()
    state.regs.eax = 4

    # test that by default trying to perform a syscall without SimUserspace causes the state to go errored
    simgr = p.factory.simulation_manager(state)
    simgr.step()
    nose.tools.assert_equal(len(simgr.active), 1)
    simgr.step()
    nose.tools.assert_equal(len(simgr.active), 0)
    nose.tools.assert_equal(len(simgr.errored), 1)

    # test that when we set BYPASS_UNSUPPORTED_SYSCALLS, we get a syscall stub instead
    state.options.add(angr.options.BYPASS_UNSUPPORTED_SYSCALL)
    simgr = p.factory.simulation_manager(state)
    simgr.step()
    nose.tools.assert_equal(len(simgr.active), 1)
    simgr.step()
    nose.tools.assert_equal(len(simgr.active), 1)
    nose.tools.assert_equal(len(simgr.errored), 0)
Exemplo n.º 37
0
def test_ret_float():
    p = angr.load_shellcode(b'X', arch='i386')

    class F1(angr.SimProcedure):
        def run(self):
            return 12.5

    p.hook(0x1000, F1(cc=p.factory.cc(func_ty=angr.sim_type.parse_file('float (x)();')[0]['x'])))
    p.hook(0x2000, F1(cc=p.factory.cc(func_ty=angr.sim_type.parse_file('double (x)();')[0]['x'])))

    s = p.factory.call_state(addr=0x1000, ret_addr=0)
    succ = s.step()
    nose.tools.assert_equal(len(succ.successors), 1)
    s2 = succ.flat_successors[0]
    nose.tools.assert_false(s2.regs.st0.symbolic)
    nose.tools.assert_equal(s2.solver.eval(s2.regs.st0.get_bytes(4, 4).raw_to_fp()), 12.5)

    s = p.factory.call_state(addr=0x2000, ret_addr=0)
    succ = s.step()
    nose.tools.assert_equal(len(succ.successors), 1)
    s2 = succ.flat_successors[0]
    nose.tools.assert_false(s2.regs.st0.symbolic)
    nose.tools.assert_equal(s2.solver.eval(s2.regs.st0.raw_to_fp()), 12.5)