Open y0umu opened 1 year ago
I think I can illustrate more with this example:
import ctypes
import subprocess
import os
import pymem
local_helper = ctypes.CDLL(ctypes.util.find_library(r'D:\xzc\lab\pyWeKi\python-dll-injection\simple_adder\x64\Debug\helper.dll'))
h_helper = ctypes.windll.kernel32.GetModuleHandleA(b'helper.dll')
print(f'h_helper={h_helper}')
tgt_ps = subprocess.Popen([r'simple_adder\x64\Debug\simple_adder.exe'])
pm = pymem.Pymem('simple_adder.exe')
helper_path = ctypes.util.find_library(r'D:\xzc\lab\pyWeKi\python-dll-injection\simple_adder\x64\Debug\helper.dll')
helper_path = bytes(helper_path, 'utf-8')
_helper_address = pymem.process.inject_dll(pm.process_handle, helper_path)
print(f'_helper_address=0x{_helper_address:x}')
tgt_ps.kill()
D:\xzc\lab\pyWeKi\python-dll-injection
is a directory junction if you have to ask.
this is definitely not intended behavior, seems inject_dll
also gets LoadLibraryA from the local process? not sure though
this is definitely not intended behavior, seems
inject_dll
also gets LoadLibraryA from the local process? not sure though
To get the address to LoadLibraryA from the local process is OK. A DLL loaded into different processes will have the same base address for each reboot. And a module handle is just the DLL base address.
However the problem is the https://github.com/srounet/Pymem/blob/ea2c215dcd1427d76b604b5faa1b39fe4ba89d69/pymem/process.py#L70 This will try to get the handle from the local process and if the DLL is not loaded in the local process, then this will fail and return None. The solution is to use the workaround @y0umu mention:
module_address = pymem.process.module_from_name(handle, dll_name)
If this is the only problematic line: https://github.com/srounet/Pymem/blob/ea2c215dcd1427d76b604b5faa1b39fe4ba89d69/pymem/process.py#L70
Maybe we can pull request and patch it.
this is definitely not intended behavior, seems
inject_dll
also gets LoadLibraryA from the local process? not sure thoughTo get the address to LoadLibraryA from the local process is OK. A DLL loaded into different processes will have the same base address for each reboot. And a module handle is just the DLL base address.
However the problem is the
https://github.com/srounet/Pymem/blob/ea2c215dcd1427d76b604b5faa1b39fe4ba89d69/pymem/process.py#L70
This will try to get the handle from the local process and if the DLL is not loaded in the local process, then this will fail and return None. The solution is to use the workaround @y0umu mention:
module_address = pymem.process.module_from_name(handle, dll_name)
I see, I was unsure if the LoadLibraryA usage was alright
also if the suggested change fixes this issue a pr with it would be great
Describe the bug It seems
pymem.process.inject_dll
should return the handle of the injected dll. But it is usingGetModuleHandleW
to search for that handle locally (i.e. in the python.exe process?). I can confirm with Process Explore and x64dbg that the dll is already in the memory of the target process. Butpymem.process.inject_dll
always gives meNone
.If I am wrong please point it out.
Your Environment
Expected behavior
pymem.process.inject_dll
correctly yields the the address of injected dll by searching the remote process.Traceback Sorry I don't have a traceback.
Additional context May be the following code could serve as a workaround.