injectlib 0.0.1__py2.py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- injectlib/__init__.py +0 -0
- injectlib/api.py +90 -0
- injectlib/cfuncs.py +76 -0
- injectlib/channel.py +69 -0
- injectlib/injector.py +89 -0
- injectlib/libs/dotnet/x64/Newtonsoft.Json.dll +0 -0
- injectlib/libs/dotnet/x64/bootstrap.dll +0 -0
- injectlib/libs/dotnet/x64/worker_wpf.dll +0 -0
- injectlib/libs/dotnet/x86/Newtonsoft.Json.dll +0 -0
- injectlib/libs/dotnet/x86/bootstrap.dll +0 -0
- injectlib/libs/dotnet/x86/worker_wpf.dll +0 -0
- injectlib/libs/hook/x64/pywinmsg64.dll +0 -0
- injectlib/libs/hook/x64/pywinmsg64u.dll +0 -0
- injectlib/libs/hook/x86/pywinmsg32.dll +0 -0
- injectlib/libs/hook/x86/pywinmsg32u.dll +0 -0
- injectlib/libs/qt/x64/qt_srv.dll +0 -0
- injectlib/sysinfo.py +61 -0
- injectlib-0.0.1.dist-info/METADATA +42 -0
- injectlib-0.0.1.dist-info/RECORD +22 -0
- injectlib-0.0.1.dist-info/WHEEL +6 -0
- injectlib-0.0.1.dist-info/licenses/LICENSE +30 -0
- injectlib-0.0.1.dist-info/top_level.txt +1 -0
injectlib/__init__.py
ADDED
|
File without changes
|
injectlib/api.py
ADDED
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
import json
|
|
2
|
+
import logging
|
|
3
|
+
|
|
4
|
+
from .injector import Injector
|
|
5
|
+
from .channel import Pipe
|
|
6
|
+
|
|
7
|
+
logger = logging.getLogger(__package__)
|
|
8
|
+
|
|
9
|
+
# backend exit codes enum
|
|
10
|
+
OK = 0
|
|
11
|
+
PARSE_ERROR = 1
|
|
12
|
+
UNSUPPORTED_ACTION = 2
|
|
13
|
+
MISSING_PARAM = 3
|
|
14
|
+
RUNTIME_ERROR = 4
|
|
15
|
+
NOT_FOUND = 5
|
|
16
|
+
UNSUPPORTED_TYPE = 6
|
|
17
|
+
INVALID_VALUE = 7
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
class InjectedBaseError(Exception):
|
|
21
|
+
"""Base class for exceptions based on errors returned from injected DLL side"""
|
|
22
|
+
|
|
23
|
+
|
|
24
|
+
class InjectedUnsupportedActionError(InjectedBaseError):
|
|
25
|
+
"""The specified action is not supported"""
|
|
26
|
+
|
|
27
|
+
|
|
28
|
+
class InjectedRuntimeError(InjectedBaseError):
|
|
29
|
+
"""Runtime exception during code execution inside injected target"""
|
|
30
|
+
|
|
31
|
+
|
|
32
|
+
class InjectedNotFoundError(InjectedBaseError):
|
|
33
|
+
"""Requested item not found: control element, property, ..."""
|
|
34
|
+
|
|
35
|
+
|
|
36
|
+
class Singleton(type):
|
|
37
|
+
"""
|
|
38
|
+
Singleton metaclass implementation from StackOverflow
|
|
39
|
+
|
|
40
|
+
http://stackoverflow.com/q/6760685/3648361
|
|
41
|
+
"""
|
|
42
|
+
|
|
43
|
+
_instances = {}
|
|
44
|
+
|
|
45
|
+
def __call__(cls, *args, **kwargs):
|
|
46
|
+
if cls not in cls._instances:
|
|
47
|
+
cls._instances[cls] = super(Singleton, cls).__call__(*args, **kwargs)
|
|
48
|
+
return cls._instances[cls]
|
|
49
|
+
|
|
50
|
+
|
|
51
|
+
class ConnectionManager(object, metaclass=Singleton):
|
|
52
|
+
def __init__(self):
|
|
53
|
+
self._pipes = {}
|
|
54
|
+
|
|
55
|
+
def _get_pipe(self, pid):
|
|
56
|
+
if pid not in self._pipes:
|
|
57
|
+
self._pipes[pid] = self._create_pipe(pid)
|
|
58
|
+
return self._pipes[pid]
|
|
59
|
+
|
|
60
|
+
def _create_pipe(self, pid):
|
|
61
|
+
pipe_name = 'process_{}'.format(pid)
|
|
62
|
+
pipe = Pipe(pipe_name)
|
|
63
|
+
if pipe.connect(n_attempts=1):
|
|
64
|
+
logger.info('Pipe {} found, looks like dll has been injected already'.format(pipe_name))
|
|
65
|
+
return pipe
|
|
66
|
+
else:
|
|
67
|
+
logger.info('Pipe {} not found, injecting dll to the process'.format(pipe_name))
|
|
68
|
+
Injector(pid, 'dotnet', 'bootstrap')
|
|
69
|
+
pipe.connect()
|
|
70
|
+
return pipe
|
|
71
|
+
|
|
72
|
+
def call_action(self, action_name, pid, **params):
|
|
73
|
+
command = {'action': action_name}
|
|
74
|
+
command.update(params)
|
|
75
|
+
|
|
76
|
+
reply = self._get_pipe(pid).transact(json.dumps(command))
|
|
77
|
+
reply = json.loads(reply)
|
|
78
|
+
|
|
79
|
+
reply_code = reply['status_code']
|
|
80
|
+
|
|
81
|
+
if reply_code == UNSUPPORTED_ACTION:
|
|
82
|
+
raise InjectedUnsupportedActionError(reply['message'])
|
|
83
|
+
elif reply_code == RUNTIME_ERROR:
|
|
84
|
+
raise InjectedRuntimeError(reply['message'])
|
|
85
|
+
elif reply_code == NOT_FOUND:
|
|
86
|
+
raise InjectedNotFoundError(reply['message'])
|
|
87
|
+
elif reply_code != OK:
|
|
88
|
+
raise InjectedBaseError()
|
|
89
|
+
|
|
90
|
+
return reply
|
injectlib/cfuncs.py
ADDED
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
"""Some functions already exists in pywinauto, but for correctly
|
|
2
|
+
injector work needs full redefinition with ctypes compatible
|
|
3
|
+
"""
|
|
4
|
+
|
|
5
|
+
import win32con
|
|
6
|
+
from ctypes import Structure, sizeof, alignment
|
|
7
|
+
from ctypes import c_char_p, c_wchar_p
|
|
8
|
+
from ctypes import POINTER
|
|
9
|
+
from ctypes import windll
|
|
10
|
+
from ctypes.wintypes import BOOL, DWORD, HANDLE, LPVOID, LPCVOID
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
class SECURITY_ATTRIBUTES(Structure):
|
|
14
|
+
_fields_ = [
|
|
15
|
+
('nLength', DWORD),
|
|
16
|
+
('lpSecurityDescriptor', LPVOID),
|
|
17
|
+
('bInheritHandle', BOOL),
|
|
18
|
+
]
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
assert sizeof(SECURITY_ATTRIBUTES) == 12 or sizeof(SECURITY_ATTRIBUTES) == 24, sizeof(SECURITY_ATTRIBUTES)
|
|
22
|
+
assert alignment(SECURITY_ATTRIBUTES) == 4 or alignment(SECURITY_ATTRIBUTES) == 8, alignment(SECURITY_ATTRIBUTES)
|
|
23
|
+
|
|
24
|
+
PAGE_READWRITE = win32con.PAGE_READWRITE
|
|
25
|
+
WAIT_TIMEOUT = win32con.WAIT_TIMEOUT
|
|
26
|
+
PROCESS_ALL_ACCESS = win32con.PROCESS_ALL_ACCESS
|
|
27
|
+
VIRTUAL_MEM = (win32con.MEM_RESERVE | win32con.MEM_COMMIT)
|
|
28
|
+
LPCSTR = LPCTSTR = c_char_p
|
|
29
|
+
LPWTSTR = c_wchar_p
|
|
30
|
+
LPDWORD = PDWORD = POINTER(DWORD)
|
|
31
|
+
LPTHREAD_START_ROUTINE = LPVOID
|
|
32
|
+
LPSECURITY_ATTRIBUTES = POINTER(SECURITY_ATTRIBUTES)
|
|
33
|
+
|
|
34
|
+
OpenProcess = windll.kernel32.OpenProcess
|
|
35
|
+
OpenProcess.restype = HANDLE
|
|
36
|
+
OpenProcess.argtypes = (DWORD, BOOL, DWORD)
|
|
37
|
+
|
|
38
|
+
VirtualAllocEx = windll.kernel32.VirtualAllocEx
|
|
39
|
+
VirtualAllocEx.restype = LPVOID
|
|
40
|
+
VirtualAllocEx.argtypes = (HANDLE, LPVOID, DWORD, DWORD, DWORD)
|
|
41
|
+
|
|
42
|
+
ReadProcessMemory = windll.kernel32.ReadProcessMemory
|
|
43
|
+
ReadProcessMemory.restype = BOOL
|
|
44
|
+
ReadProcessMemory.argtypes = (HANDLE, LPCVOID, LPVOID, DWORD, DWORD)
|
|
45
|
+
|
|
46
|
+
WriteProcessMemory = windll.kernel32.WriteProcessMemory
|
|
47
|
+
WriteProcessMemory.restype = BOOL
|
|
48
|
+
WriteProcessMemory.argtypes = (HANDLE, LPVOID, LPCVOID, DWORD, DWORD)
|
|
49
|
+
|
|
50
|
+
CreateRemoteThread = windll.kernel32.CreateRemoteThread
|
|
51
|
+
CreateRemoteThread.restype = HANDLE
|
|
52
|
+
CreateRemoteThread.argtypes = (HANDLE, LPSECURITY_ATTRIBUTES, DWORD, LPTHREAD_START_ROUTINE, LPVOID, DWORD, LPDWORD)
|
|
53
|
+
|
|
54
|
+
GetModuleHandleA = windll.kernel32.GetModuleHandleA
|
|
55
|
+
GetModuleHandleA.restype = HANDLE
|
|
56
|
+
GetModuleHandleA.argtypes = (LPCTSTR,)
|
|
57
|
+
|
|
58
|
+
LoadLibraryA = windll.kernel32.LoadLibraryA
|
|
59
|
+
LoadLibraryA.restype = HANDLE
|
|
60
|
+
LoadLibraryA.argtypes = (LPCTSTR,)
|
|
61
|
+
|
|
62
|
+
GetModuleHandleW = windll.kernel32.GetModuleHandleW
|
|
63
|
+
GetModuleHandleW.restype = HANDLE
|
|
64
|
+
GetModuleHandleW.argtypes = (LPWTSTR,)
|
|
65
|
+
|
|
66
|
+
LoadLibraryW = windll.kernel32.LoadLibraryW
|
|
67
|
+
LoadLibraryW.restype = HANDLE
|
|
68
|
+
LoadLibraryW.argtypes = (LPWTSTR,)
|
|
69
|
+
|
|
70
|
+
GetProcAddress = windll.kernel32.GetProcAddress
|
|
71
|
+
GetProcAddress.restype = LPVOID
|
|
72
|
+
GetProcAddress.argtypes = (HANDLE, LPCTSTR)
|
|
73
|
+
|
|
74
|
+
WaitForSingleObject = windll.kernel32.WaitForSingleObject
|
|
75
|
+
WaitForSingleObject.restype = DWORD
|
|
76
|
+
WaitForSingleObject.argtypes = (HANDLE, DWORD)
|
injectlib/channel.py
ADDED
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
import pywintypes
|
|
2
|
+
import time
|
|
3
|
+
import win32file
|
|
4
|
+
import win32pipe
|
|
5
|
+
import winerror
|
|
6
|
+
import logging
|
|
7
|
+
|
|
8
|
+
logger = logging.getLogger(__package__)
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
class InjectedBrokenPipeError(Exception):
|
|
12
|
+
pass
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
class Pipe(object):
|
|
16
|
+
def __init__(self, name):
|
|
17
|
+
self.name = name
|
|
18
|
+
self.handle = None
|
|
19
|
+
|
|
20
|
+
def connect(self, n_attempts=30, delay=1):
|
|
21
|
+
for i in range(n_attempts):
|
|
22
|
+
try:
|
|
23
|
+
self.handle = win32file.CreateFile(
|
|
24
|
+
r'\\.\pipe\{}'.format(self.name),
|
|
25
|
+
win32file.GENERIC_READ | win32file.GENERIC_WRITE,
|
|
26
|
+
0,
|
|
27
|
+
None,
|
|
28
|
+
win32file.OPEN_EXISTING,
|
|
29
|
+
0,
|
|
30
|
+
None
|
|
31
|
+
)
|
|
32
|
+
win32pipe.SetNamedPipeHandleState(
|
|
33
|
+
self.handle,
|
|
34
|
+
win32pipe.PIPE_READMODE_MESSAGE | win32pipe.PIPE_WAIT,
|
|
35
|
+
None,
|
|
36
|
+
None,
|
|
37
|
+
)
|
|
38
|
+
logger.info('Connected to the pipe {}'.format(self.name))
|
|
39
|
+
break
|
|
40
|
+
except pywintypes.error as e:
|
|
41
|
+
if e.args[0] == winerror.ERROR_FILE_NOT_FOUND:
|
|
42
|
+
logger.warning('Attempt {}/{}: failed to connect to the pipe {}'.format(i + 1, n_attempts,
|
|
43
|
+
self.name))
|
|
44
|
+
time.sleep(delay)
|
|
45
|
+
else:
|
|
46
|
+
raise InjectedBrokenPipeError('Unexpected pipe error: {}'.format(e))
|
|
47
|
+
if self.handle is not None:
|
|
48
|
+
return True
|
|
49
|
+
return False
|
|
50
|
+
|
|
51
|
+
def transact(self, string):
|
|
52
|
+
try:
|
|
53
|
+
# TODO get preferred encoding from application
|
|
54
|
+
self.write(string, 'utf-8')
|
|
55
|
+
resp = win32file.ReadFile(self.handle, 64 * 1024)
|
|
56
|
+
return resp[1].decode('utf-8')
|
|
57
|
+
except pywintypes.error as e:
|
|
58
|
+
if e.args[0] == winerror.ERROR_BROKEN_PIPE:
|
|
59
|
+
raise InjectedBrokenPipeError("Broken pipe")
|
|
60
|
+
else:
|
|
61
|
+
raise InjectedBrokenPipeError('Unexpected pipe error: {}'.format(e))
|
|
62
|
+
|
|
63
|
+
def close(self):
|
|
64
|
+
win32file.CloseHandle(self.handle)
|
|
65
|
+
|
|
66
|
+
def write(self, string, encoding='utf-8'):
|
|
67
|
+
"""Write string with the specified encoding to the named pipe."""
|
|
68
|
+
win32file.WriteFile(self.handle, string.encode(encoding))
|
|
69
|
+
win32file.FlushFileBuffers(self.handle)
|
injectlib/injector.py
ADDED
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
import ctypes
|
|
2
|
+
import locale
|
|
3
|
+
import os
|
|
4
|
+
|
|
5
|
+
from . import sysinfo
|
|
6
|
+
from . import cfuncs
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
class Injector(object):
|
|
10
|
+
"""Class for injections dll"""
|
|
11
|
+
|
|
12
|
+
def __init__(self, pid, backend_name, dll_name, is_unicode=False):
|
|
13
|
+
"""Constructor inject dll (one application - one class instance)."""
|
|
14
|
+
self.is_unicode = is_unicode
|
|
15
|
+
self.pid = pid
|
|
16
|
+
if not sysinfo.is_x64_python() == sysinfo.is64_bitprocess(self.pid):
|
|
17
|
+
raise RuntimeError("Application and Python must be both 32-bit or both 64-bit")
|
|
18
|
+
self.h_process = self._get_process_handle(self.pid)
|
|
19
|
+
|
|
20
|
+
self.dll_path = os.path.join(os.path.dirname(os.path.realpath(__file__)),
|
|
21
|
+
'libs', backend_name,
|
|
22
|
+
'x{}'.format("64" if sysinfo.is64_bitprocess(self.pid) else "86"),
|
|
23
|
+
'{}.dll'.format(dll_name)).encode('utf-16' if self.is_unicode
|
|
24
|
+
else locale.getpreferredencoding())
|
|
25
|
+
self._inject_dll_to_process()
|
|
26
|
+
|
|
27
|
+
@staticmethod
|
|
28
|
+
def _get_process_handle(pid):
|
|
29
|
+
return cfuncs.OpenProcess(cfuncs.PROCESS_ALL_ACCESS, False, pid)
|
|
30
|
+
|
|
31
|
+
def _create_remote_thread_with_timeout(self, proc_address, arg_address, timeout_ms=1000,
|
|
32
|
+
call_err_text="", timeout_err_text=""):
|
|
33
|
+
thread_handle = cfuncs.CreateRemoteThread(self.h_process, None, 0, proc_address, arg_address, 0, None)
|
|
34
|
+
if not thread_handle:
|
|
35
|
+
raise RuntimeError(call_err_text)
|
|
36
|
+
# TODO: add timeout to pywinauto timings and replace
|
|
37
|
+
ret = cfuncs.WaitForSingleObject(thread_handle, ctypes.wintypes.DWORD(timeout_ms))
|
|
38
|
+
if ret == cfuncs.WAIT_TIMEOUT:
|
|
39
|
+
raise TimeoutError(timeout_err_text)
|
|
40
|
+
|
|
41
|
+
def _inject_dll_to_process(self):
|
|
42
|
+
# Get dll path length
|
|
43
|
+
c_dll_path = ctypes.create_unicode_buffer(self.dll_path) \
|
|
44
|
+
if self.is_unicode else ctypes.create_string_buffer(self.dll_path)
|
|
45
|
+
|
|
46
|
+
# Allocate space for DLL path
|
|
47
|
+
arg_address = cfuncs.VirtualAllocEx(self.h_process, 0, ctypes.sizeof(c_dll_path),
|
|
48
|
+
cfuncs.VIRTUAL_MEM, cfuncs.PAGE_READWRITE)
|
|
49
|
+
|
|
50
|
+
# Write DLL path to allocated space
|
|
51
|
+
if not cfuncs.WriteProcessMemory(self.h_process, arg_address,
|
|
52
|
+
ctypes.byref(c_dll_path), ctypes.sizeof(c_dll_path), 0):
|
|
53
|
+
raise AttributeError("Couldn't write data to process memory, check python access.")
|
|
54
|
+
|
|
55
|
+
# Resolve LoadLibraryA(W) Address
|
|
56
|
+
h_kernel32 = cfuncs.GetModuleHandleW(b"kernel32.dll") \
|
|
57
|
+
if self.is_unicode else cfuncs.GetModuleHandleA(b"kernel32.dll")
|
|
58
|
+
h_loadlib = cfuncs.GetProcAddress(h_kernel32, b"LoadLibraryW" if self.is_unicode else b"LoadLibraryA")
|
|
59
|
+
|
|
60
|
+
# Now call createRemoteThread with entry point set to LoadLibraryA(W) and pointer to DLL path as param
|
|
61
|
+
self._create_remote_thread_with_timeout(h_loadlib, arg_address, 1000,
|
|
62
|
+
"Couldn't create remote thread, application and Python must be "
|
|
63
|
+
"both 32-bit or both 64-bit", "Inject time out")
|
|
64
|
+
|
|
65
|
+
def _get_dll_proc_address(self, proc_name):
|
|
66
|
+
lib = cfuncs.LoadLibraryW(self.dll_path) if self.is_unicode else cfuncs.LoadLibraryA(self.dll_path)
|
|
67
|
+
return cfuncs.GetProcAddress(lib, proc_name)
|
|
68
|
+
|
|
69
|
+
def remote_call_void_func(self, func_name):
|
|
70
|
+
proc_address = self._get_dll_proc_address(func_name)
|
|
71
|
+
|
|
72
|
+
if not cfuncs.CreateRemoteThread(self.h_process, None, 0, proc_address, 0, 0, None):
|
|
73
|
+
raise RuntimeError("Couldn't create remote thread, dll not injected, inject and try again!")
|
|
74
|
+
|
|
75
|
+
def remote_call_int_param_func(self, func_name, param):
|
|
76
|
+
# Resolve param type for different applications
|
|
77
|
+
a = ctypes.c_int64(param) if sysinfo.is64_bitprocess(self.pid) else ctypes.c_int32(param)
|
|
78
|
+
|
|
79
|
+
arg_address = cfuncs.VirtualAllocEx(self.h_process, 0, ctypes.sizeof(a),
|
|
80
|
+
cfuncs.VIRTUAL_MEM, cfuncs.PAGE_READWRITE)
|
|
81
|
+
if not cfuncs.WriteProcessMemory(self.h_process, arg_address, ctypes.byref(a), ctypes.sizeof(a), 0):
|
|
82
|
+
raise AttributeError("Couldn't write data to process memory, check python access.")
|
|
83
|
+
|
|
84
|
+
proc_address = self._get_dll_proc_address(func_name)
|
|
85
|
+
|
|
86
|
+
self._create_remote_thread_with_timeout(proc_address, arg_address, 1000,
|
|
87
|
+
"Couldn't create remote thread, dll not injected, "
|
|
88
|
+
"inject it and try again!",
|
|
89
|
+
"{0}(int) function call time out".format(func_name))
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
injectlib/sysinfo.py
ADDED
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
"""Simple module for checking whether Python and Windows are 32-bit or 64-bit"""
|
|
2
|
+
import sys
|
|
3
|
+
import os
|
|
4
|
+
import platform
|
|
5
|
+
import ctypes
|
|
6
|
+
import win32process
|
|
7
|
+
import win32api
|
|
8
|
+
import win32con
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
def os_arch():
|
|
12
|
+
architecture_map = {
|
|
13
|
+
'x86': 'x86',
|
|
14
|
+
'i386': 'x86',
|
|
15
|
+
'i486': 'x86',
|
|
16
|
+
'i586': 'x86',
|
|
17
|
+
'i686': 'x86',
|
|
18
|
+
'x64': 'x86_64',
|
|
19
|
+
'AMD64': 'x86_64',
|
|
20
|
+
'amd64': 'x86_64',
|
|
21
|
+
'em64t': 'x86_64',
|
|
22
|
+
'EM64T': 'x86_64',
|
|
23
|
+
'x86_64': 'x86_64',
|
|
24
|
+
'IA64': 'ia64',
|
|
25
|
+
'ia64': 'ia64'
|
|
26
|
+
}
|
|
27
|
+
if sys.platform == 'win32':
|
|
28
|
+
architecture_var = os.environ.get('PROCESSOR_ARCHITEW6432', '')
|
|
29
|
+
if architecture_var == '':
|
|
30
|
+
architecture_var = os.environ.get('PROCESSOR_ARCHITECTURE', '')
|
|
31
|
+
return architecture_map.get(architecture_var, 'Unknown')
|
|
32
|
+
else:
|
|
33
|
+
return architecture_map.get(platform.machine(), '')
|
|
34
|
+
|
|
35
|
+
|
|
36
|
+
def python_bitness():
|
|
37
|
+
return ctypes.sizeof(ctypes.POINTER(ctypes.c_int)) * 8
|
|
38
|
+
|
|
39
|
+
|
|
40
|
+
def is_x64_python():
|
|
41
|
+
return python_bitness() == 64
|
|
42
|
+
|
|
43
|
+
|
|
44
|
+
def is_x64_os():
|
|
45
|
+
return os_arch() in ['x86_64', 'ia64']
|
|
46
|
+
|
|
47
|
+
|
|
48
|
+
def is64_bitprocess(process_id):
|
|
49
|
+
"""Return True if the specified process is a 64-bit one
|
|
50
|
+
|
|
51
|
+
Return False if it is only a 32-bit process running under Wow64.
|
|
52
|
+
Always return False for x86.
|
|
53
|
+
"""
|
|
54
|
+
|
|
55
|
+
if is_x64_os():
|
|
56
|
+
phndl = win32api.OpenProcess(win32con.MAXIMUM_ALLOWED, 0, process_id)
|
|
57
|
+
if not phndl:
|
|
58
|
+
raise OSError(f'OpenProcess is failed for PID = {process_id}')
|
|
59
|
+
return not win32process.IsWow64Process(phndl)
|
|
60
|
+
|
|
61
|
+
return False
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: injectlib
|
|
3
|
+
Version: 0.0.1
|
|
4
|
+
Summary: A set of Python modules to inject DLLs into applications for the Microsoft Windows
|
|
5
|
+
Home-page: https://github.com/pywinauto/injectlib
|
|
6
|
+
Author: Vasily Ryabov, Ilya Naumov, Boris Galochkin, Alexander Makarov
|
|
7
|
+
Author-email: vasily.v.ryabov@gmail.com
|
|
8
|
+
License: BSD 3-clause
|
|
9
|
+
Keywords: windows gui .net inject testing test desktop dll wpf qt
|
|
10
|
+
Platform: win32
|
|
11
|
+
Classifier: Development Status :: 5 - Production/Stable
|
|
12
|
+
Classifier: Environment :: Console
|
|
13
|
+
Classifier: Intended Audience :: Developers
|
|
14
|
+
Classifier: License :: OSI Approved :: BSD License
|
|
15
|
+
Classifier: Operating System :: Microsoft :: Windows
|
|
16
|
+
Classifier: Programming Language :: Python
|
|
17
|
+
Classifier: Programming Language :: Python :: 3.7
|
|
18
|
+
Classifier: Programming Language :: Python :: 3.8
|
|
19
|
+
Classifier: Programming Language :: Python :: 3.9
|
|
20
|
+
Classifier: Programming Language :: Python :: 3.10
|
|
21
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
22
|
+
Classifier: Programming Language :: Python :: Implementation :: CPython
|
|
23
|
+
Classifier: Topic :: Software Development :: Libraries :: Python Modules
|
|
24
|
+
Classifier: Topic :: Software Development :: Testing
|
|
25
|
+
Requires-Python: >=3.7
|
|
26
|
+
License-File: LICENSE
|
|
27
|
+
Requires-Dist: pywin32
|
|
28
|
+
Dynamic: author
|
|
29
|
+
Dynamic: author-email
|
|
30
|
+
Dynamic: classifier
|
|
31
|
+
Dynamic: description
|
|
32
|
+
Dynamic: home-page
|
|
33
|
+
Dynamic: keywords
|
|
34
|
+
Dynamic: license
|
|
35
|
+
Dynamic: license-file
|
|
36
|
+
Dynamic: platform
|
|
37
|
+
Dynamic: requires-dist
|
|
38
|
+
Dynamic: requires-python
|
|
39
|
+
Dynamic: summary
|
|
40
|
+
|
|
41
|
+
|
|
42
|
+
It allows to inject DLls into applications for the Microsoft Windows.
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
injectlib/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
2
|
+
injectlib/api.py,sha256=JjHgMkUptTZ50MD9iZyYLO6SgmdypAIIs9Kemc-EyVk,2620
|
|
3
|
+
injectlib/cfuncs.py,sha256=Q4xgmRJwrcFF44QXg3ASP1IyUdzTJY0Buabq0lPeJLs,2700
|
|
4
|
+
injectlib/channel.py,sha256=DUGmQAEPWypptNgmI9YTBqkWpVN51hoRCuIq-Vij-sA,2487
|
|
5
|
+
injectlib/injector.py,sha256=qvSd7SBCHbBu8rzuNcupVYy29vAdGRwCEB7Q8agID8U,4854
|
|
6
|
+
injectlib/sysinfo.py,sha256=yNGGlU1GYWiavJWpo41DZyB1jfXl-63zTeRBZGoAEe4,1641
|
|
7
|
+
injectlib/libs/dotnet/x64/Newtonsoft.Json.dll,sha256=tiSUnfiw46YVP9-3MKfG9JkLZZLuDZIuF4hDPSdmEPM,701992
|
|
8
|
+
injectlib/libs/dotnet/x64/bootstrap.dll,sha256=C7Wzdc5IZCThvCVqK43heK6XjJnWQjIu8nh52ilcyH8,33280
|
|
9
|
+
injectlib/libs/dotnet/x64/worker_wpf.dll,sha256=FIyXcT1AAnoVCOzSYE6plM58qSzawoFWi4Oo7stxR78,44032
|
|
10
|
+
injectlib/libs/dotnet/x86/Newtonsoft.Json.dll,sha256=tiSUnfiw46YVP9-3MKfG9JkLZZLuDZIuF4hDPSdmEPM,701992
|
|
11
|
+
injectlib/libs/dotnet/x86/bootstrap.dll,sha256=gIZm6b0SRUSrta-2cMeBtaq5uHkhqf-Z4cmqj5zw5f4,26112
|
|
12
|
+
injectlib/libs/dotnet/x86/worker_wpf.dll,sha256=O37VXoHzxUK3YSdfBIsFyTJMrgbx2bGy2pgbuJ_-EiQ,44544
|
|
13
|
+
injectlib/libs/hook/x64/pywinmsg64.dll,sha256=kzQoE6evywmIOhI7On--ntISTKBgHVRplfQNJ9kpqmA,20480
|
|
14
|
+
injectlib/libs/hook/x64/pywinmsg64u.dll,sha256=0Yi3QsnbZJkEKLk8tzgWZEHtTL4LRZqtScd4rGcnVGg,45056
|
|
15
|
+
injectlib/libs/hook/x86/pywinmsg32.dll,sha256=G1JidmQK4wNDHDeF5DtgjERg_tmMyIaDWmTpvy2IHmA,36864
|
|
16
|
+
injectlib/libs/hook/x86/pywinmsg32u.dll,sha256=4vbB3lQXGny6zy9P-6hSyMzSPT8NAv1ERew_KsJ2Tfg,36864
|
|
17
|
+
injectlib/libs/qt/x64/qt_srv.dll,sha256=7EAldJ48u2uTtzR3A501yXU943UJvHVj4CeqCcGfbRI,76288
|
|
18
|
+
injectlib-0.0.1.dist-info/licenses/LICENSE,sha256=WzT-MnvTQkd_NDKvfKi7ZiDYosFzqKfEt_rWh7oxPg4,1650
|
|
19
|
+
injectlib-0.0.1.dist-info/METADATA,sha256=5SeppRdVeLQzS5oV6PcGc4zggKfK0vOw5LKxUk28uy4,1562
|
|
20
|
+
injectlib-0.0.1.dist-info/WHEEL,sha256=TdQ5LtNwLuxTCjgxN51AgdU5w-KkB9ttmLbzjTH02pg,109
|
|
21
|
+
injectlib-0.0.1.dist-info/top_level.txt,sha256=_cnZuwXRGkD8hyZ8IT3_9k6_k8DZQe4fQejUz1KaBUM,10
|
|
22
|
+
injectlib-0.0.1.dist-info/RECORD,,
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
BSD 3-Clause License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Vasily Ryabov, Ilya Naumov, Boris Galochkin, Alexander Makarov
|
|
4
|
+
https://github.com/pywinauto/injectlib/graphs/contributors
|
|
5
|
+
All rights reserved.
|
|
6
|
+
|
|
7
|
+
Redistribution and use in source and binary forms, with or without
|
|
8
|
+
modification, are permitted provided that the following conditions are met:
|
|
9
|
+
|
|
10
|
+
* Redistributions of source code must retain the above copyright notice, this
|
|
11
|
+
list of conditions and the following disclaimer.
|
|
12
|
+
|
|
13
|
+
* Redistributions in binary form must reproduce the above copyright notice,
|
|
14
|
+
this list of conditions and the following disclaimer in the documentation
|
|
15
|
+
and/or other materials provided with the distribution.
|
|
16
|
+
|
|
17
|
+
* Neither the name of the copyright holder nor the names of its
|
|
18
|
+
contributors may be used to endorse or promote products derived from
|
|
19
|
+
this software without specific prior written permission.
|
|
20
|
+
|
|
21
|
+
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
|
22
|
+
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
|
23
|
+
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
|
24
|
+
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
|
|
25
|
+
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
|
26
|
+
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
|
27
|
+
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
|
28
|
+
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
|
29
|
+
OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
|
30
|
+
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
injectlib
|