From d0a5dc3c61afd56d5d03f9795ac285ba8524f559 Mon Sep 17 00:00:00 2001 From: hakril Date: Thu, 23 Jan 2025 14:13:05 +0100 Subject: [PATCH] more testing --- tests/test_injection.py | 6 ++++-- tests/test_process.py | 5 +++++ windows/injection.py | 19 ++++++++++--------- 3 files changed, 19 insertions(+), 11 deletions(-) diff --git a/tests/test_injection.py b/tests/test_injection.py index 6241623..7008e07 100644 --- a/tests/test_injection.py +++ b/tests/test_injection.py @@ -4,6 +4,7 @@ import pytest import weakref import shutil import time +import os import windows import windows.generated_def as gdef @@ -35,8 +36,9 @@ def proc_3264_runsus(request): # Its really the same test as test_process.test_load_library but with suspended process as well def test_dll_injection(proc_3264_runsus): assert (not proc_3264_runsus.peb.Ldr) or ("wintrust.dll" not in [mod.name for mod in proc_3264_runsus.peb.modules]) - windows.injection.load_dll_in_remote_process(proc_3264_runsus, "wintrust.dll") - assert "wintrust.dll" in [mod.name for mod in proc_3264_runsus.peb.modules] + modaddr = windows.injection.load_dll_in_remote_process(proc_3264_runsus, "wintrust.dll") + wintrustmod = [mod for mod in proc_3264_runsus.peb.modules if mod.name == "wintrust.dll"][0] + assert wintrustmod.baseaddr == modaddr def test_dll_injection_error_reporting(proc_3264_runsus): with pytest.raises(windows.injection.InjectionFailedError) as excinfo: diff --git a/tests/test_process.py b/tests/test_process.py index 32ba6ef..f2aacc9 100644 --- a/tests/test_process.py +++ b/tests/test_process.py @@ -370,6 +370,11 @@ class TestProcessWithCheckGarbage(object): proc32_64.load_library(DLL) assert DLL in [m.name for m in proc32_64.peb.modules] + def test_load_library_suspended(self, proc32_64_suspended): + DLL = "wintrust.dll" + proc32_64_suspended.load_library(DLL) + assert DLL in [m.name for m in proc32_64_suspended.peb.modules] + def test_load_library_unicode_name(self, proc32_64, tmpdir): mybitness = windows.current_process.bitness UNICODE_FILENAME = u'\u4e2d\u56fd\u94f6\u884c\u7f51\u94f6\u52a9\u624b.dll' diff --git a/windows/injection.py b/windows/injection.py index ae928f9..9a713f9 100644 --- a/windows/injection.py +++ b/windows/injection.py @@ -128,13 +128,20 @@ def generate_simple_LoadLibraryW_32_with_error(k32): code += x86.Ret() return code.get_code() -def generate_simple_LoadLibraryW_64(load_libraryW, GetLastError, remote_store): +def generate_simple_LoadLibraryW_64_with_error(k32, remote_store): + """A shellcode that execute LoadLibraryW(param) and store the value at a fixed address. + This allow a 32b process to inject and retrieve a 64bit module address + + Thread return value is the result of GetLastError() + """ + load_libraryW = k32.pe.exports["LoadLibraryW"] + GetLastError = k32.pe.exports["GetLastError"] code = RemoteLoadLibrayStub = x64.MultipleInstr() code += x64.Mov("RAX", load_libraryW) code += (x64.Push("RDI") * 5) # Prepare stack code += x64.Call("RAX") code += x64.Mov(x64.deref(remote_store), "RAX") - code += x64.Mov("RAX", GetLastError) + code += x64.Mov("RAX", GetLastError) # Add a jump ? code += x64.Call("RAX") code += (x64.Pop("RDI") * 5) # Clean stack code += x64.Ret() @@ -161,12 +168,6 @@ def load_dll_in_remote_process(target, dll_path): if k32: # We have kernel32 \o/ k32 = k32[0] - try: - load_libraryW = k32.pe.exports["LoadLibraryW"] - GetLastError = k32.pe.exports["GetLastError"] - except KeyError: - raise ValueError("Kernel32 have no export (wtf)") - with target.allocated_memory(0x1000) as addr: if target.bitness == 32: shellcode32 = generate_simple_LoadLibraryW_32_with_error(k32) @@ -193,7 +194,7 @@ def load_dll_in_remote_process(target, dll_path): param_addr = addr addr += len(full_dll_name) shellcode_addr = addr - shellcode = generate_simple_LoadLibraryW_64(load_libraryW, GetLastError, retval_addr) + shellcode = generate_simple_LoadLibraryW_64_with_error(k32, retval_addr) target.write_memory(shellcode_addr, shellcode) t = target.create_thread(shellcode_addr, param_addr) t.wait()