Beispiel #1
0
def test_retset():
    cmdline = (sys.executable +
               ' -c "import ctypes; ctypes.cdll.dll.Add(1, 1)"')
    dbg = Qdb()
    locs = {'marker': None}
    dbg.add_query('dll.Add', "marker = retset('eax+1', 8)")
    result = dbg.run(cmdline, locs)
    assert result is True
    assert locs['marker'] == 3
Beispiel #2
0
def test_db():
    dbg = Qdb()
    locs = {'marker': None}
    dbg.add_query(0x401010, "marker = db('poi(esp)', 1)")
    result = False
    result = dbg.run(hello_exe_path, locs)
    assert result is True
    # DWORD of beginning of "Hello, world!"
    assert locs['marker'][0] == struct.unpack('B', 'H')[0]
Beispiel #3
0
def test_bp():
    """FIXME: This test will break if da breaks, which is confusing."""
    dbg = Qdb()
    locs = {'marker': None}
    dbg.add_query(0x401000,
                  "bp(0x401010, 'marker = da(\\\'poi(esp)\\\', 5)')")
    result = dbg.run(hello_exe_path, locs)
    assert result is True
    assert locs['marker'] == 'Hello'
Beispiel #4
0
def test_da():
    dbg = Qdb()
    locs = {'marker': None}
    dbg.add_query(0x401010,
                  "marker = da('poi(esp)'); print('Marker = ' + str(marker))")
    result = dbg.run(hello_exe_path, locs)
    assert result is True
    # DWORD of beginning of "Hello, world!"
    assert locs['marker'] == 'Hello, world!\n\0'
Beispiel #5
0
def test_park_detach_attach_unpark():
    """This will spike CPU while the debuggee executes jmp -2 a few thousand
    times.
    """
    dbg = Qdb()
    locs = {'pid': None, 'flag': None}
    dbg.add_query(0x401010, "park(); pid = detach()")
    result = dbg.run(hello_exe_path, locs)
    assert result is True

    dbg = Qdb()
    dbg.attach(locs['pid'])
    dbg.add_query(0x401021, "flag = -1")
    dbg.unpark()
    result = dbg.run(parameters=locs)
    assert result is True

    assert locs['flag'] == -1
Beispiel #6
0
def test_kill():
    dbg = Qdb()
    locs = {'marker1': None, 'marker2': None}
    dbg.add_query(0x401010, "marker1 = kill()")
    dbg.add_query(0x40101b, "marker2 = vex('poi(ebp-0x4)')")
    result = dbg.run(hello_exe_path, locs)
    assert result is True
    assert locs['marker1'] is True
    assert locs['marker2'] is None
Beispiel #7
0
def test_stepi():
    dbg = Qdb()
    locs = {'location': None}
    dbg.add_query(0x401010, "stepi(); location = r('eip')")  # call _printf
    result = dbg.run(hello_exe_path, locs)

    assert result is True
    assert locs['location']
    assert locs['location'] == (0xD + 0x401015)  # At _printf
Beispiel #8
0
def test_python_ctypes_dll_intercept():
    cmdline = (sys.executable +
               ' -c "import ctypes; ctypes.cdll.dll.Add(40, 2)"')
    dbg = Qdb()
    locs = {'marker': None}
    dbg.add_query('dll.Add+0xd', "marker = r('eax')")
    result = dbg.run(cmdline, locs)
    assert result is True
    assert locs['marker'] == 42
Beispiel #9
0
def test_eb2():
    sentinel_value = 0xffff
    dbg = Qdb()
    locs = {'marker': None}
    # [ebp-4] here is equal to the length of the string "Hello, world!\n"
    dbg.add_query(0x40101b, "eb('ebp-4', '\xff\xff')")
    dbg.add_query(0x40101e, "marker = r('eax')")
    result = dbg.run(hello_exe_path, locs)
    assert result is True
    assert locs['marker'] == sentinel_value
Beispiel #10
0
def test_eb1():
    sentinel_value = 0x0f
    dbg = Qdb()
    locs = {'marker': None}
    # [ebp-4] here is equal to the length of the string "Hello, world!\n"
    dbg.add_query(0x40101b, "eb('ebp-4', " + str(sentinel_value) + ")")
    dbg.add_query(0x40101e, "marker = r('eax')")
    result = dbg.run('hello.exe', locs)
    assert result is True
    assert locs['marker'] == sentinel_value
Beispiel #11
0
def test_memcpy():
    """FIXME: This test will break if dd breaks, which is confusing."""
    dbg = Qdb()
    locs = {'marker': None}
    dbg.add_query(
        0x401010,
        "memcpy('poi(esp)', 'poi(esp)+4', 4); " + "marker = dd('poi(esp)', 1)")
    result = dbg.run(hello_exe_path, locs)
    assert result is True
    assert locs['marker'][0] == struct.unpack('@I', 'Hello, world!'[4:8])[0]
Beispiel #12
0
def test_one_mb_read_limit():
    ONE_MB = 1024 * 1024
    MORE = ONE_MB + 10
    PAGE_READWRITE = 0x4
    MEM_COMMIT = 0x1000
    MEM_RESERVE = 0x2000

    locs = {'location': None, 'size': None}

    args = (
        ' -c "import ctypes; '
        'm = ctypes.windll.kernel32.VirtualAlloc(' + hex(0).rstrip('L') +
        ', ' + hex(MORE).rstrip('L') + ', ' +
        hex(MEM_COMMIT | MEM_RESERVE).rstrip('L') + ', ' +
        hex(PAGE_READWRITE).rstrip('L') + '); '

        # Disclose the location of the memory returned by VirtualAlloc
        'ctypes.windll.kernel32.VirtualQuery(m, 0, 0);'

        # Trigger one more breakpoint for clarity
        'ctypes.windll.kernel32.VirtualFree(' + 'm, ' + hex(MORE).rstrip('L') +
        ', ' + '0x8000' + ');')

    # When running under py.test.exe, sys.executable is python.exe
    cmdline = sys.executable + args

    dbg = Qdb()

    dbg.add_query(
        'kernel32.VirtualQuery',
        # If lpBuffer + dwLength == NULL, then this is the Python
        # script's indication to qdb of where the memory is located.
        # Read it.
        "if not sum(dd('esp+8', 2)): location = dd('esp+4', 1)[0]; ")

    # VirtualFree is called by the debuggee (above) to trigger this code.
    dbg.add_query(
        'kernel32.VirtualFree',
        "m = readmem("
        "location, " + hex(MORE).rstrip('L') + ", "
        "1, "
        "None"
        ");"
        "size = len(m)"  # Collect the length that was read
    )

    result = dbg.run(cmdline, locs)
    assert result is True

    # If we did not get the location, that is useful to know for diagnosing
    # test failure.
    assert locs['location']

    # Check that ONE_MB of data was returned despite having tried to read MORE
    assert locs['size'] == ONE_MB
Beispiel #13
0
def test_get_pcs():
    dbg = Qdb()
    locs = {'pcs': None, 'tid': None}
    pc = 0x401000
    dbg.add_query(pc, 'pcs = get_pcs(); tid = q._trace.getCurrentThread()')
    result = dbg.run(hello_exe_path, locs)
    assert result is True
    # hello.exe is single-threaded
    for k, v in locs['pcs'].iteritems():
        assert k == locs['tid']
        assert v == pc
Beispiel #14
0
def test_eu_and_du():
    """FIXME: This test depends on both eu and du, which makes it break
    when either piece breaks.
    """
    dbg = Qdb()
    locs = {'marker': None}
    dbg.add_query(0x401010,
                  "eu('poi(esp)', u'Bye, world'); marker = du('poi(esp)', 3)")
    result = dbg.run(hello_exe_path, locs)
    assert result is True
    assert locs['marker'] == u'Bye'
Beispiel #15
0
def test_ea_and_da():
    """FIXME: This test depends on both ea and da, which makes it break
    when either piece breaks.
    """
    dbg = Qdb()
    locs = {'marker': None}
    dbg.add_query(0x401010,
                  "ea('poi(esp)', 'Bye, world'); marker = da('poi(esp)')")
    result = dbg.run(hello_exe_path, locs)
    assert result is True
    assert locs['marker'] == 'Bye, worldld!\n\0'
Beispiel #16
0
def test_callback_gets_context_with_pc_and_locals_as_arg(*args, **kwargs):
    dbg = Qdb()

    def callback(p, **kwargs):
        p['marker'] = True

    locs = {'marker': False}
    dbg.add_query(0x401010, callback)
    result = dbg.run(hello_exe_path, locs)
    assert result is True
    assert locs['marker'] is True
Beispiel #17
0
def test_get_push_arg():
    cmdline = (sys.executable +
               ' -c "import ctypes; ctypes.cdll.dll.Add(12, 34)"')
    dbg = Qdb()
    locs = {'arg_12': None, 'arg_34': None}
    dbg.add_query('dll.Add',
                  "arg_12 = get_push_arg(0); arg_34 = get_push_arg(1)")
    result = dbg.run(cmdline, locs)
    assert result is True
    assert locs['arg_12'] == 12
    assert locs['arg_34'] == 34
Beispiel #18
0
def test_gu():
    dbg = Qdb()
    locs = {'location': None}
    dbg.add_query(
        0x401022,
        "print(hex(r('eip'))); gu(); location = r('eip'); print(hex(location))"
    )  # At _printf
    result = dbg.run(hello_exe_path, locs)
    assert result is True
    assert locs['location']
    assert locs['location'] == 0x401015  # Right after call _printf
Beispiel #19
0
def test_writemem():
    """FIXME: This test will break if da breaks, which is confusing."""
    dbg = Qdb()
    locs = {'marker': None}
    s = "Goodbye, world!"
    print("writemem('poi(esp)', '" + s + "'); marker = da('poi(esp)')")
    dbg.add_query(
        0x401010,
        "writemem('poi(esp)', '" + s + "\\x00'); marker = da('poi(esp)')")
    result = dbg.run(hello_exe_path, locs)
    assert result is True
    assert locs['marker'] == s + '\x00'
Beispiel #20
0
def test_rapid_fire_WILL_TAKE_A_LONG_TIME():
    runs_expected = 1
    # runs_expected = 1400
    runs_counted = 0

    locs = {'marker': runs_counted}
    dbg = Qdb()
    dbg.add_query(0x0401262, "marker += 1; kill()")
    for i in xrange(runs_expected):
        result = dbg.run(hello_exe_path, locs)
        assert result is True
    assert locs['marker'] == runs_expected
Beispiel #21
0
def test_vexpr_nameerror():
    dbg = Qdb()
    locs = {'marker': None}
    dbg.add_query(0x401010, "marker = vex('poi(EXP)')")
    got_exception = False
    try:
        result = dbg.run(hello_exe_path, locs)
    except QdbBpException as e:
        got_exception = True
        ex_type_is_name_error = isinstance(e.exception, NameError)
    assert got_exception
    assert ex_type_is_name_error
    assert locs['marker'] is None
Beispiel #22
0
def test_disas_alias_uf():
    dbg = Qdb()
    locs = {'marker': None}
    dbg.add_query(0x401000, "marker = uf(None)")
    result = dbg.run(hello_exe_path, locs)
    assert result is True
    assert locs['marker'][0].startswith('push ebp')
    assert locs['marker'][1].startswith('mov ebp,esp')
    assert locs['marker'][2].startswith('push ecx')
    assert locs['marker'][3].startswith('mov dword [ebp - 4],0')
    assert locs['marker'][4].startswith('push 0x0040c000')
    assert locs['marker'][5].startswith('call 0x00401022')
    assert locs['marker'][6].startswith('add esp,4')
    assert locs['marker'][7].startswith('mov dword [ebp - 4],eax')
    assert locs['marker'][8].startswith('mov eax,dword [ebp - 4]')
    assert locs['marker'][9].startswith('mov esp,ebp')
    assert locs['marker'][10].startswith('pop ebp')
    assert locs['marker'][11].startswith('ret')
Beispiel #23
0
def _test_stacktrace(command="stacktrace()"):
    dbg = Qdb()
    locs = {'backtrace': None}
    dbg.add_query(0x401022, 'backtrace = %s' % (command))
    result = dbg.run(hello_exe_path, locs)

    assert result is True
    assert locs['backtrace']
    bt = locs['backtrace']

    # At least main, _printf, and one other frame
    assert len(bt) > 2

    # Stack frames numbered as expected
    assert all([(bt[i].nr == i) for i in range(len(bt))])

    # ebp direction as expected
    assert all([(bt[i].bp < bt[i + 1].bp) for i in range(len(bt) - 1)])

    # Known addresses that should be at the top of this stack frame
    assert bt[0].pc == 0x401022
    assert bt[0].pc_s == 'hello+0x22'
    assert bt[1].pc == 0x40120b
    assert bt[1].pc_s == 'hello+0x20b'
Beispiel #24
0
def test_run_no_breaks_and_exitcode():
    dbg = Qdb()
    result = dbg.run(hello_exe_path)
    assert result is True
    assert dbg.get_exitcode() == 14
Beispiel #25
0
def test_python_ctypes_dll_control_case():
    cmdline = (sys.executable +
               ' -c "import ctypes; ctypes.windll.dll.Add(1, 2)"')
    dbg = Qdb()
    result = dbg.run(cmdline)
    assert result is True
Beispiel #26
0
def test_rundll_dll_control_case():
    dbg = Qdb()
    result = dbg.run(r'rundll32.exe dll.dll,Add')
    assert result is True