Esempio n. 1
0
def test_decompiler_basic():

    #
    # pie
    #

    process = revenge.Process(basic_one_path, resume=False, verbose=False)

    process.radare2._r2.cmd("aaa")
    sleep(0.2)

    a = process.decompiler.decompile_address("basic_one:0x66d")
    assert len(a) == 1
    assert 0x66d in a
    assert a[0x66d].address == 0x66d
    assert "sym.func" in a[0x66d].src

    process.quit()

    #
    # No pie
    #

    process = revenge.Process(basic_one_ia32_nopie_path, resume=False, verbose=False)

    process.radare2._r2.cmd("aaa")
    sleep(0.2)

    a = process.decompiler.decompile_address(0x08048460)
    assert len(a) == 1
    assert 0x08048460 in a
    assert a[0x08048460].address == 0x08048460
    assert "sym.func" in a[0x08048460].src

    process.quit()
def test_frida_process_stdio(capsys):
    process = revenge.Process("/bin/cat", verbose=False, resume=True)
    process.stdin("hello world\n")
    assert b"hello world" in stdout_expect(process, b"world")
    process.quit()

    process = revenge.Process("/bin/cat", verbose=False, resume=False)
    process._stdout_echo = True
    process.memory[process.entrypoint].breakpoint = False
    process.stdin("hello world\n")
    sleep(0.5)
    assert "hello world" in capsys.readouterr().out
    process.quit()

    process = revenge.Process([cat_stderr_path, "hello world"],
                              verbose=False,
                              resume=True)
    assert b"hello world" in stderr_expect(process, b"world")
    process.quit()

    process = revenge.Process([cat_stderr_path, "Test2 Blerg"],
                              verbose=False,
                              resume=False)
    process._stderr_echo = True
    process.memory[process.entrypoint].breakpoint = False
    sleep(0.5)
    assert "Test2 Blerg" in capsys.readouterr().out
    process.quit()
Esempio n. 3
0
def test_process_arch():
    basic_one = revenge.Process(basic_one_path, resume=False, verbose=False, load_symbols='basic_one')
    basic_one_ia32 = revenge.Process(basic_one_ia32_path, resume=False, verbose=False, load_symbols='basic_one_ia32')

    assert basic_one.arch == "x64"
    assert basic_one_ia32.arch == "ia32"

    basic_one.quit()
    basic_one_ia32.quit()
Esempio n. 4
0
def test_plt():
    process = revenge.Process(basic_one_path, resume=False, verbose=False)
    basic_one_64_nopie = revenge.Process(basic_one_64_nopie_path, resume=False)
    basic_one_ia32 = revenge.Process(basic_one_ia32_path, resume=False)
    basic_one_ia32_nopie = revenge.Process(basic_one_ia32_nopie_path, resume=False)

    #
    # First parse
    # 

    basic_one_mod = process.modules['basic_one']
    assert basic_one_mod.plt & 0xfff == 0x510
    printf = process.memory[basic_one_mod.symbols['plt.printf']]
    assert printf("123456") == 6
    assert 'printf' in process.memory.describe_address(basic_one_mod.symbols['plt.printf'])
    assert 'printf' in process.memory.describe_address(basic_one_mod.symbols['got.printf'])
    assert 'printf' in process.memory.describe_address(process.memory[basic_one_mod.symbols['got.printf']].pointer)

    basic_one_mod = basic_one_64_nopie.modules['basic_one*']
    assert basic_one_mod.plt == 0x4003e0
    printf = basic_one_64_nopie.memory[basic_one_mod.symbols['plt.printf']]
    assert printf("123456") == 6
    assert 'printf' in basic_one_64_nopie.memory.describe_address(basic_one_mod.symbols['plt.printf'])
    assert 'printf' in basic_one_64_nopie.memory.describe_address(basic_one_mod.symbols['got.printf'])
    assert 'printf' in basic_one_64_nopie.memory.describe_address(basic_one_64_nopie.memory[basic_one_mod.symbols['got.printf']].pointer)

    basic_one_mod = basic_one_ia32.modules['basic_one*']
    assert basic_one_mod.plt & 0xfff == 0x3a0
    printf = basic_one_ia32.memory[basic_one_mod.symbols['plt.printf']]
    # This uses thunks... No easy way of testing call through plt rn..
    #assert printf("123456") == 6
    assert 'printf' in basic_one_ia32.memory.describe_address(basic_one_mod.symbols['plt.printf'])
    assert 'printf' in basic_one_ia32.memory.describe_address(basic_one_mod.symbols['got.printf'])
    assert 'printf' in basic_one_ia32.memory.describe_address(basic_one_ia32.memory[basic_one_mod.symbols['got.printf']].pointer)

    basic_one_mod = basic_one_ia32_nopie.modules['basic_one*']
    assert basic_one_mod.plt == 0x80482d0
    printf = basic_one_ia32_nopie.memory[basic_one_mod.symbols['plt.printf']]
    # This uses thunks... No easy way of testing call through plt rn..
    assert printf("123456") == 6
    assert 'printf' in basic_one_ia32_nopie.memory.describe_address(basic_one_mod.symbols['plt.printf'])
    assert 'printf' in basic_one_ia32_nopie.memory.describe_address(basic_one_mod.symbols['got.printf'])
    assert 'printf' in basic_one_ia32_nopie.memory.describe_address(basic_one_ia32_nopie.memory[basic_one_mod.symbols['got.printf']].pointer)

    process.quit()
    basic_one_64_nopie.quit()
    basic_one_ia32.quit()
    basic_one_ia32_nopie.quit()
Esempio n. 5
0
def test_memory_on_message():
    process = revenge.Process(basic_one_path,
                              resume=False,
                              verbose=False,
                              load_symbols='basic_one')

    f = process.memory.find(types.StringUTF8("This is my string"))
    f.sleep_until_completed()

    payload = {'payload': [{'address': 1337}, {'address': 31337}]}
    f._on_message(payload, None)
    assert 1337 in f
    assert 31337 in f

    f.completed = False
    f._script = None
    payload = {'payload': "DONE"}
    f._on_message(payload, None)
    assert f.completed == True

    # Unexpected message
    payload = {'payload': 1.12}
    f._on_message(payload, None)

    process.quit()
Esempio n. 6
0
def test_access_violation_execute():
    p = revenge.Process(exceptions_path, resume=False, verbose=False)

    do_access_exec_violation = p.memory[
        p.modules['exceptions'].symbols['do_access_exec_violation']]
    do_good = p.memory[p.modules['exceptions'].symbols['do_good']]

    e = do_access_exec_violation()
    assert isinstance(e, revenge.native_exception.NativeException)
    str(e)
    repr(e)
    assert e.type == 'access-violation'
    # 0x666 shouldn't be in any module
    assert p.modules[e.address] is None
    assert p.memory.describe_address(e.address) == "0x666"
    assert isinstance(e.backtrace, revenge.native_exception.NativeBacktrace)
    assert isinstance(e.context, revenge.cpu.contexts.x64.X64Context)

    assert e.memory_address == 0x666
    assert e.memory_operation == 'execute'

    # If we handled exception correctly, process should still be in good state
    assert not isinstance(do_good, revenge.native_exception.NativeException)

    p.quit()
Esempio n. 7
0
def test_timeless_basic_amd64():

    p = revenge.Process(timeless_one_path, resume=False, verbose=True)

    timeless = p.techniques.NativeTimelessTracer()
    repr(timeless)
    str(timeless)

    timeless.apply()
    t = list(timeless)[0]
    p.memory[p.entrypoint].breakpoint = False

    # Right after decrypting
    after_call = p.memory['timeless_one:0x6F5'].address
    ti = t.wait_for(after_call)
    assert ti.context.rax.next.thing == "SuperS3cretFl@g"
    # This is to make sure we're cache invalidating correctly..
    assert ti.context.rdi.next.thing == "SuperS3cretFl@g"
    assert int(ti.context.pc) == after_call

    repr(timeless)
    str(timeless)

    repr(t)
    str(t)

    for ti in t:
        repr(ti)
        str(ti)

    p.quit()
Esempio n. 8
0
def test_process_run_script_generic_include_js_dispose():

    process = revenge.Process(basic_one_path,
                              resume=False,
                              verbose=False,
                              load_symbols='basic_one')

    mem1 = process.memory.alloc(8)
    mem2 = process.memory.alloc(8)

    mem1.int32 = 0
    mem2.int32 = 0

    script = """dispose_push(function () {{ {}.writeS32(1337); }}); dispose_push(function () {{ {}.writeS32(1337); }});""".format(
        mem1.address.js, mem2.address.js)

    process.run_script_generic(script,
                               raw=True,
                               unload=True,
                               include_js="dispose.js")

    assert mem1.int32 == 1337
    assert mem2.int32 == 1337

    process.quit()
Esempio n. 9
0
def test_access_violation_read():
    p = revenge.Process(exceptions_path, resume=False, verbose=False)

    do_access_read_violation = p.memory[
        p.modules['exceptions'].symbols['do_access_read_violation']]
    do_good = p.memory[p.modules['exceptions'].symbols['do_good']]

    e = do_access_read_violation()
    assert isinstance(e, revenge.native_exception.NativeException)
    str(e)
    repr(e)
    assert e.type == 'access-violation'
    # This abort is run by throwing the signal from libc
    assert p.modules[e.address].name == 'exceptions'
    assert p.memory.describe_address(
        e.address).startswith("exceptions:do_access_read_violation")
    assert isinstance(e.backtrace, revenge.native_exception.NativeBacktrace)
    assert isinstance(e.context, revenge.cpu.contexts.x64.X64Context)

    assert e.memory_address == 0x666
    assert e.memory_operation == 'read'

    # If we handled exception correctly, process should still be in good state
    assert not isinstance(do_good, revenge.native_exception.NativeException)

    p.quit()
Esempio n. 10
0
def test_thread_breakpoint():
    p = revenge.Process(basic_threads_path,
                        resume=False,
                        verbose=False,
                        load_symbols='basic_threads')

    t = list(p.threads)[0]

    # Wait to hit the breakpoint
    while not t.breakpoint:
        pass

    start_address = p.memory["basic_threads:0x670"].address

    assert t.id in p.threads._breakpoint_context
    assert t.context.pc == start_address

    t.breakpoint = False

    # breakpoint doesn't directly update. it has to get updated by the script
    # terminating in frida
    while True:
        t = list(p.threads)[0]
        if not t.breakpoint:
            break

        elif t.breakpoint and t.context.pc != start_address:
            break

    p.quit()
Esempio n. 11
0
def test_argument_types():

    p = revenge.Process(basic_one_path,
                        resume=False,
                        verbose=False,
                        load_symbols='basic_one')

    strlen = p.memory[':strlen']

    assert strlen.argument_types is None

    # This should produce logger error and not set
    strlen.argument_types = 12
    assert strlen.argument_types is None

    strlen.argument_types = types.Int32
    assert strlen.argument_types == (types.Int32, )

    strlen.argument_types = (types.Int32, types.Double)
    assert strlen.argument_types == (types.Int32, types.Double)

    strlen.argument_types = [types.Int32, types.Double]
    assert strlen.argument_types == (types.Int32, types.Double)

    p.quit()
Esempio n. 12
0
def test_thread_join_linux():

    process = revenge.Process(basic_threads_path, resume=False, verbose=False)

    malloc = process.memory['malloc']
    malloc.argument_types = types.Int
    malloc.return_type = types.Pointer

    func = process.memory.create_c_function(
        "void *func() { return (void *)1337; }")
    t = process.threads.create(func.address)
    assert t.join() == 1337

    func = process.memory.create_c_function(
        "void* func() { double d=1337; double *dp = malloc(sizeof(double)); *dp = d; return (void *)dp; }",
        malloc=malloc)
    t = process.threads.create(func.address)
    assert process.memory[t.join()].double == 1337.0

    func = process.memory.create_c_function(
        "void* func() { float f=1337; float *fp = malloc(sizeof(float)); *fp = f; return (void *)fp; }",
        malloc=malloc)
    t = process.threads.create(func.address)
    assert process.memory[t.join()].float == 1337.0

    process.quit()
Esempio n. 13
0
def test_ctypes():
    process = revenge.Process(basic_struct_path, resume=False, verbose=False)

    assert types.Int8.ctype == "char"
    assert types.UInt8.ctype == "unsigned char"
    assert types.Char.ctype == "char"
    assert types.UChar.ctype == "unsigned char"
    assert types.Int16.ctype == "short"
    assert types.UInt16.ctype == "unsigned short"
    assert types.Short.ctype == "short"
    assert types.UShort.ctype == "unsigned short"
    assert types.Int32.ctype == "int"
    assert types.UInt32.ctype == "unsigned int"
    assert types.Int.ctype == "int"
    assert types.UInt.ctype == "unsigned int"
    assert types.Int64.ctype == "long"
    assert types.UInt64.ctype == "unsigned long"
    assert types.Long.ctype == "long"
    assert types.ULong.ctype == "unsigned long"
    assert types.Float.ctype == "float"
    assert types.Double.ctype == "double"
    assert types.Pointer.ctype == "void *"
    assert types.StringUTF8.ctype == "char *"

    process.quit()
Esempio n. 14
0
def test_basic_one_trace_thread_int():

    basic_one = revenge.Process(basic_one_path,
                                resume=False,
                                verbose=False,
                                load_symbols='basic_one')

    thread = list(basic_one.threads)[0]

    t = basic_one.techniques.NativeInstructionTracer(exec=True)
    t.apply([thread.id])
    str(t)
    t2 = list(t)[0]
    while len(t2) < 15:
        time.sleep(0.1)

    with pytest.raises(Exception):
        t3 = basic_one.techniques.NativeInstructionTracer(exec=True)
        t3.apply([12.12])

    # Testing exception for attempting to create another trace on a thread that is already being traced
    with pytest.raises(Exception):
        t3 = basic_one.techniques.NativeInstructionTracer(exec=True)
        t3.apply()

    t2.stop()

    # This should not raise an exception now
    t = basic_one.techniques.NativeInstructionTracer(exec=True)
    t.apply()

    basic_one.quit()
Esempio n. 15
0
def test_basic_one_trace_thread():

    basic_one = revenge.Process(basic_one_path,
                                resume=False,
                                verbose=False,
                                load_symbols='basic_one')

    thread = list(basic_one.threads)[0]

    t = basic_one.techniques.NativeInstructionTracer(exec=True)
    t.apply([thread])

    t2 = list(t)[0]
    while len(t2) < 15:
        time.sleep(0.1)
    assert len(t2) > 0
    t2.stop()

    time.sleep(0.3)
    t = basic_one.techniques.NativeInstructionTracer(exec=True)
    t.apply(thread)
    t2 = list(t)[0]
    basic_one.memory[basic_one.entrypoint].breakpoint = False
    t2.wait_for('basic_one:0x692')  # final ret
    assert len(t2) > 0

    # TODO: Figure out why this final trace stop causes things to hang...
    #t2.stop()

    basic_one.quit()
Esempio n. 16
0
def test_trace_exclude_ranges():

    p = revenge.Process(basic_one_path,
                        resume=False,
                        verbose=False,
                        load_symbols='basic_one')

    # Create a thread that will just spin
    m = p.memory.alloc(8)
    m.int64 = 0
    func = p.memory.create_c_function(
        """ void func() {{ while ( *(void *){} == 0 ) {{ ; }} }}""".format(
            hex(m.address)))

    # Start-er up
    t = p.threads.create(func.address)

    # Kick off thread, explicitly ignoring the thread code itself
    trace = p.techniques.NativeInstructionTracer(
        exec=True, exclude_ranges=[[func.address, func.address + 0x100]])
    trace.apply(t)
    m.int64 = 1

    time.sleep(0.2)

    # We should have nothing in our trace, since we excluded it all
    assert len(t.trace) == 0

    p.quit()
Esempio n. 17
0
def test_memory_find_general():
    process = revenge.Process(basic_one_path,
                              resume=False,
                              verbose=False,
                              load_symbols='basic_one')

    f = process.memory.find(types.StringUTF8("This is my string"))
    f.sleep_until_completed()

    assert len(f) > 0
    for addr in f:
        assert process.memory[addr].string_utf8 == "This is my string"

    # Test invalid find
    with pytest.raises(Exception):
        util.memory.find(1.12)
    """ This doesn't work. Probably because Frida is hiding it's own memory regions from returning

    my_string = types.StringUTF8('Hello world!')
    mem = process.memory.alloc_string(my_string)

    f = process.memory.find(my_string)
    f.sleep_until_completed()

    assert mem.address in f
    """

    process.quit()
Esempio n. 18
0
def test_access_violation_amd64_main_thread(caplog):
    p = revenge.Process(dvb_path_x86_64, resume=True, verbose=False)
    caplog.set_level(logging.INFO)

    p.stdout("?> ")
    p.stdin("1\n")
    p.stdout("input: ")
    p.stdin("A" * 128 + "\n")

    assert isinstance(list(p.threads)[0].exceptions, list)

    while list(p.threads)[0].exceptions == []:
        pass

    e = list(p.threads)[0].exceptions[0]
    str(e)
    repr(e)
    assert isinstance(e.context.pc, types.Telescope)
    assert e.type == 'access-violation'
    assert e.context.ip.next.thing.mnemonic == "ret"
    assert e.context.rbp.thing == 0x4141414141414141

    while "Caught exception in thread" not in caplog.text:
        pass

    p.quit()
Esempio n. 19
0
def test_techniques_basic():
    p = revenge.Process(basic_one_path, resume=False, verbose=False)

    list(p.techniques)

    # All techniques (as dict) should be subclass of Technique
    assert all(issubclass(x, Technique) for x in p.techniques)

    # Everything in dict should be a callable property
    assert all(
        callable(getattr(p.techniques, x.__name__)) for x in p.techniques)

    repr(p.techniques)

    for t in p.techniques:
        assert t.TYPE in Technique.TYPES

    # Just make sure we're populating at least
    assert p.techniques.InstructionTracer is not None

    # Try giving a memory map range
    range = p.memory.maps[p.memory['strlen'].address]
    tech = p.techniques.InstructionTracer(exec=True)
    tech._technique_code_range(range)

    p.quit()
Esempio n. 20
0
def test_memory_cast_struct(caplog):
    process = revenge.Process(basic_one_path,
                              resume=False,
                              verbose=False,
                              load_symbols='basic_one')
    basic_one_module = process.modules['basic_one']
    basic_one_i8_addr = basic_one_module.symbols['i8'].address

    # Just need scratch space
    addr = basic_one_i8_addr

    struct = types.Struct()
    struct.add_member('test1', types.Int32(-5))
    struct.add_member('test2', types.Int8(-12))
    struct.add_member('test3', types.UInt16(16))
    struct.add_member('test4', types.Pointer(4444))
    struct.add_member('test5', types.Int16)  # This should cause warning
    struct.add_member('test6', types.Pointer(5555))

    mem = process.memory[addr]

    assert mem.cast(types.Struct) is None
    s = mem.cast(struct)
    assert s is struct
    assert s.memory is mem

    process.quit()
Esempio n. 21
0
def test_basic_one_traceitem_manual_creation():

    basic_one = revenge.Process(basic_one_path,
                                resume=False,
                                verbose=False,
                                load_symbols='basic_one')
    module = basic_one.modules['basic_one']

    for i in trace_items:
        ti = TraceItem(basic_one, i)
        str(ti)
        repr(ti)
        assert ti.type == i['type']

    with pytest.raises(RevengeInvalidArgumentType):
        ti.type = 12

    # Invalid type
    t = ti.type
    ti.type = 'blerg'
    assert ti.type == t

    str(ti)
    repr(ti)

    basic_one.quit()
def test_native_instruction_counting_basic_x86_64():

    process = revenge.Process(basic_one_path, resume=False)

    # Grab the main thread
    t = next(thread for thread in process.threads if thread.state == "stopped")

    counters = process.techniques.NativeInstructionCounter(
        from_modules='basic*')
    counters.apply(t)
    counter = list(counters)[0]

    process.resume()

    # Not sure there's always going to be an exact number...
    # Just ballpark that we're counting something
    while counter.count < 500:
        continue

    counters.remove()
    """Run with func not yet supported on windows
    func = process.memory[0x00401560]

    # 5 instructions in func
    counters = process.techniques.NativeInstructionCounter(from_modules="basic*")

    # Call with technique
    func(techniques=counters)
    counter = list(counters)[0]
    while counter.count != 5:
        continue
    """

    process.quit()
Esempio n. 23
0
def test_thread_create_linux():

    process = revenge.Process(basic_threads_path, resume=False, verbose=False)

    # Create and set an int
    a = process.memory.alloc(8)
    a.int64 = 0

    # Create the cmodule function that will set this variable
    func = process.memory.create_c_function(
        "void func() {{ long *x = (long *){}; while ( 1 ) {{ *x = 1337; }} }}".
        format(hex(a.address)))

    # Kick off the thread
    t = process.threads.create(func.address)

    # Wait for it (super fast likely)
    while a.int64 == 0:
        pass

    assert a.int64 == 1337

    # Make sure we have a pthread_id
    assert t.pthread_id is not None

    process.quit()
Esempio n. 24
0
def test_basic_one_traceitem():

    basic_one = revenge.Process(basic_one_path,
                                resume=False,
                                verbose=False,
                                load_symbols='basic_one')
    module = basic_one.modules['basic_one']

    t = basic_one.techniques.NativeInstructionTracer()
    t.apply()

    tid = list(t)[0]._tid

    for i in trace_items:
        i['tid'] = tid
        t._on_message({'type': 'send', 'payload': [[i]]}, None)

    repr(t)
    t2 = list(t)[0]

    for i in list(t2):
        assert isinstance(i, TraceItem)

    len(t2)
    str(t2)
    repr(t2)

    assert isinstance(t2[0], TraceItem)

    basic_one.quit()
Esempio n. 25
0
def test_techniques_basic():
    p = revenge.Process(basic_one_path, resume=False, verbose=False)

    list(p.techniques)

    # All techniques (as dict) should be subclass of Technique
    assert all(issubclass(x, Technique) for x in p.techniques)

    # Everything in dict should be a callable property
    assert all(callable(getattr(p.techniques, x.__name__)) for x in p.techniques)

    repr(p.techniques)

    for t in p.techniques:
        assert t.TYPE in Technique.TYPES

    # Just make sure we're populating at least
    assert p.techniques.NativeInstructionTracer is not None

    # Try giving a memory map range
    range = p.memory.maps[p.memory['strlen'].address]
    tech = p.techniques.NativeInstructionTracer(exec=True)
    tech._technique_code_range(range)

    # Try using two stalking techniques at once
    time = p.memory['time']
    timeless = p.techniques.NativeTimelessTracer()
    trace = p.techniques.NativeInstructionTracer(exec=True)
    with pytest.raises(RevengeInvalidArgumentType):
        time(0, techniques=[timeless, trace])

    p.quit()
Esempio n. 26
0
def test_native_instruction_counting_basic_x86_64():

    process = revenge.Process(basic_one_path, resume=False)

    counters = process.techniques.NativeInstructionCounter()
    counters.apply()
    counter = list(counters)[0]

    process.resume()

    # Just an estimate
    while counter.count < 1000:
        continue

    counters.remove()

    basic = process.modules['basic*']
    func = basic.symbols['func'].memory

    # 5 instructions in func
    counters = process.techniques.NativeInstructionCounter(
        from_modules="basic*")

    # Call with technique
    func(techniques=counters)
    counter = list(counters)[0]
    while counter.count != 5:
        continue

    process.quit()
Esempio n. 27
0
def test_memory_write_struct(caplog):
    process = revenge.Process(basic_one_path,
                              resume=False,
                              verbose=False,
                              load_symbols='basic_one')
    basic_one_module = process.modules['basic_one']
    basic_one_i8_addr = basic_one_module.symbols['i8'].address

    # Just need scratch space
    addr = basic_one_i8_addr

    struct = types.Struct()
    struct.add_member('test1', types.Int32(-5))
    struct.add_member('test2', types.Int8(-12))
    struct.add_member('test3', types.UInt16(16))
    struct.add_member('test4', types.Pointer(4444))
    struct.add_member('test5', types.Int16)  # This should cause warning
    struct.add_member('test6', types.Pointer(5555))

    mem = process.memory[addr]
    caplog.clear()
    mem.struct = struct

    assert "was left uninitialized" in caplog.records[0].msg
    caplog.clear()

    assert mem.int32 == -5
    assert process.memory[addr + 4].int8 == -12
    assert process.memory[addr + 4 + 1].uint16 == 16
    assert process.memory[addr + 4 + 1 + 2].pointer == 4444
    assert process.memory[addr + 4 + 1 + 2 + 8 + 2].pointer == 5555

    process.quit()
Esempio n. 28
0
def test_native_instruction_counting_basic_ia32():

    process = revenge.Process(basic_one_ia32_path, resume=False)

    counters = process.techniques.NativeInstructionCounter(
        from_modules='basic*')
    counters.apply()
    counter = list(counters)[0]

    process.resume()

    # This seemed right and theoretically shouldn't change.
    while counter.count != 158:
        continue

    counters.remove()

    basic = process.modules['basic*']
    func = basic.symbols['func'].memory

    # 5 instructions in func
    counters = process.techniques.NativeInstructionCounter(
        from_modules="basic*")

    # Call with technique
    func(techniques=counters)
    counter = list(counters)[0]
    while counter.count != 9:
        continue

    process.quit()
Esempio n. 29
0
def test_angr_symbion_x86_64():
    process = revenge.Process(basic_constraints, resume=False, verbose=False)

    # Just for fun, let's start part way in
    begin = process.memory['basic_constraints:0x11f3']
    begin.breakpoint = True

    process.memory[process.entrypoint].breakpoint = False

    t = list(process.threads)[0]
    while not t.pc == begin.address:
        t = list(process.threads)[0]

    simgr = t.angr.simgr
    avoid = [
        process.memory['basic_constraints:0x1241'].address,
        process.memory['basic_constraints:0x12a5'].address
    ]
    find = [process.memory['basic_constraints:0x1297'].address]

    basic = process.modules['basic_constraints']

    # Checking our custom rehooking is working
    assert t.angr.project._sim_procedures[int(
        basic.symbols['plt.puts'].address)].display_name == 'puts'

    simgr.explore(find=find, avoid=avoid)
    assert len(simgr.found) == 1
    assert simgr.found[0].posix.dumps(0) == b"31337 \xba\xb333337 \xba\xb3"

    process.quit()
Esempio n. 30
0
def test_angr_symbion_x86_64():
    process = revenge.Process(basic_constraints, resume=False, verbose=False)

    # Just for fun, let's start part way in
    begin = process.memory[0x4015af]
    begin.breakpoint = True

    process.resume()

    t = list(process.threads)[0]
    while not t.pc == begin.address:
        t = list(process.threads)[0]

    def fgets_hook(state):
        state.regs.r8 = 0

    simgr = t.angr.simgr

    # Force to stdin
    t.angr.project.hook(0x4015e6, fgets_hook, length=0)
    t.angr.project.hook(0x401650, fgets_hook, length=0)

    avoid = [0x401613, 0x40167d]
    find = [0x40166f]

    puts = process.memory['puts']

    # Checking our custom rehooking is working
    assert t.angr.project._sim_procedures[puts.address].display_name == 'puts'

    simgr.explore(find=find, avoid=avoid)
    assert len(simgr.found) == 1
    assert simgr.found[0].posix.dumps(3) == b"31337 \xba\xb333337 \xba\xb3"

    process.quit()