|
1 | 1 | import subprocess |
2 | | -import pytest |
3 | | -from pathlib import Path |
| 2 | + |
| 3 | +from iced_x86 import Register |
| 4 | +import regex |
4 | 5 |
|
5 | 6 | import memobj |
| 7 | +from memobj.utils import ValueWaiter |
| 8 | +from memobj.hook import create_capture_hook, RegisterCaptureSettings |
6 | 9 |
|
7 | | -import pytest |
8 | 10 |
|
| 11 | +def test_dll_injection(test_binaries): |
| 12 | + exe_path, dll_path = test_binaries |
9 | 13 |
|
10 | | -def test_dll_injection(): |
11 | | - # there is probably a better way to get this |
12 | | - library_root = Path(__file__).parent.parent.parent |
| 14 | + proc = subprocess.Popen([str(exe_path)]) |
| 15 | + try: |
| 16 | + process = memobj.WindowsProcess.from_id(proc.pid) |
| 17 | + assert process.inject_dll(dll_path), "DLL injection failed" |
| 18 | + |
| 19 | + module = process.get_module_named(dll_path.name) |
| 20 | + assert module is not None, "Failed to find injected DLL in remote process" |
| 21 | + finally: |
| 22 | + proc.terminate() |
13 | 23 |
|
14 | | - assert library_root.name == "memobj" |
15 | | - assert (library_root / "README.md").exists() is True |
16 | 24 |
|
17 | | - dll_path = ( |
18 | | - library_root / "target/release/test_inject.dll" |
19 | | - ).resolve() |
20 | | - exe_path = ( |
21 | | - library_root / "target/release/inject_target.exe" |
22 | | - ).resolve() |
| 25 | +def test_create_capture_hook(test_binaries): |
| 26 | + exe_path, _ = test_binaries |
23 | 27 |
|
24 | | - if not dll_path.exists(): |
25 | | - pytest.skip(f"Test DLL not found at {dll_path}") |
26 | | - if not exe_path.exists(): |
27 | | - pytest.skip(f"Test EXE not found at {exe_path}") |
| 28 | + # TODO: allow passing addresses so we can do a symbol lookup |
| 29 | + PlayerCaptureHook = create_capture_hook( |
| 30 | + pattern=regex.escape(bytes.fromhex("48 83 EC 28 F3 0F 10 41 04 0F 2E 05 40 52 01 00 76 0D 8B 09 E8 17 FF FF FF 01 05 21 D0 01 00 48 83 C4 28 C3")), |
| 31 | + module="inject_target.exe", |
| 32 | + bitness=64, |
| 33 | + register_captures=[RegisterCaptureSettings(Register.RCX, derefference=False)], |
| 34 | + ) |
28 | 35 |
|
29 | 36 | proc = subprocess.Popen([str(exe_path)]) |
30 | 37 | try: |
31 | 38 | process = memobj.WindowsProcess.from_id(proc.pid) |
32 | | - assert process.inject_dll(dll_path), "DLL injection failed" |
| 39 | + hook = PlayerCaptureHook(process) |
| 40 | + hook.activate() |
| 41 | + rcx_capture = hook.get_variable("RCX_capture") |
33 | 42 |
|
34 | | - module = process.get_module_named(dll_path.name) |
35 | | - assert module is not None, "Failed to find injected DLL in remote process" |
| 43 | + waiter = ValueWaiter(lambda: rcx_capture.read_typed(process.pointer_type)) |
| 44 | + address = waiter.wait_for_value(0, inverse=True, timeout=60) |
| 45 | + |
| 46 | + assert address != 0 |
36 | 47 | finally: |
37 | 48 | proc.terminate() |
| 49 | + |
0 commit comments