reykit 1.0.0__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.
- reykit/__init__.py +41 -0
- reykit/rall.py +33 -0
- reykit/rcomm.py +431 -0
- reykit/rdata.py +395 -0
- reykit/rdll/__init__.py +17 -0
- reykit/rdll/rdll_inject.py +41 -0
- reykit/rdll/rdll_inject_core.py +202 -0
- reykit/remail.py +276 -0
- reykit/rexception.py +339 -0
- reykit/rimage.py +261 -0
- reykit/rlog.py +1061 -0
- reykit/rmonkey.py +341 -0
- reykit/rmultitask.py +871 -0
- reykit/rnumber.py +161 -0
- reykit/ros.py +1917 -0
- reykit/rrandom.py +351 -0
- reykit/rregex.py +293 -0
- reykit/rschedule.py +272 -0
- reykit/rstdout.py +356 -0
- reykit/rsystem.py +1180 -0
- reykit/rtable.py +511 -0
- reykit/rtext.py +458 -0
- reykit/rtime.py +678 -0
- reykit/rtype.py +106 -0
- reykit/rwrap.py +613 -0
- reykit/rzip.py +137 -0
- reykit-1.0.0.dist-info/METADATA +29 -0
- reykit-1.0.0.dist-info/RECORD +30 -0
- reykit-1.0.0.dist-info/WHEEL +5 -0
- reykit-1.0.0.dist-info/top_level.txt +1 -0
reykit/rdata.py
ADDED
@@ -0,0 +1,395 @@
|
|
1
|
+
# !/usr/bin/env python
|
2
|
+
# -*- coding: utf-8 -*-
|
3
|
+
|
4
|
+
"""
|
5
|
+
@Time : 2022-12-05 14:10:42
|
6
|
+
@Author : Rey
|
7
|
+
@Contact : reyxbo@163.com
|
8
|
+
@Explain : Data methods.
|
9
|
+
"""
|
10
|
+
|
11
|
+
|
12
|
+
from typing import Any, TypedDict, Optional, Literal, NoReturn, TypeVar, overload
|
13
|
+
from collections.abc import Callable, Iterable, Generator
|
14
|
+
|
15
|
+
from .rexception import check_least_one, check_most_one
|
16
|
+
from .rsystem import is_iterable
|
17
|
+
|
18
|
+
|
19
|
+
__all__ = (
|
20
|
+
'count',
|
21
|
+
'flatten',
|
22
|
+
'split',
|
23
|
+
'unique',
|
24
|
+
'in_arrs',
|
25
|
+
'objs_in',
|
26
|
+
'RGenerator'
|
27
|
+
)
|
28
|
+
|
29
|
+
|
30
|
+
CountResult = TypedDict('CountResult', {'value': Any, 'count': int})
|
31
|
+
Element = TypeVar('Element')
|
32
|
+
|
33
|
+
|
34
|
+
def count(
|
35
|
+
data: Iterable,
|
36
|
+
ascend: bool = False
|
37
|
+
) -> list[CountResult]:
|
38
|
+
"""
|
39
|
+
Group count data element value.
|
40
|
+
|
41
|
+
Parameters
|
42
|
+
----------
|
43
|
+
data : Data.
|
44
|
+
ascend : Whether ascending by count, otherwise descending order.
|
45
|
+
|
46
|
+
Returns
|
47
|
+
-------
|
48
|
+
Count result.
|
49
|
+
|
50
|
+
Examples
|
51
|
+
--------
|
52
|
+
>>> count([1, True, 1, '1', (2, 3)])
|
53
|
+
[{'value': 1, 'count': 2}, {'value': True, 'count': 1}, {'value': '1', 'count': 1}, {'value': (2, 3), 'count': 1}]
|
54
|
+
"""
|
55
|
+
|
56
|
+
# Set parameter.
|
57
|
+
value_list = []
|
58
|
+
count_list = []
|
59
|
+
|
60
|
+
# Count.
|
61
|
+
for element in data:
|
62
|
+
for index, value in enumerate(value_list):
|
63
|
+
element_str = str(element)
|
64
|
+
value_str = str(value)
|
65
|
+
if element_str == value_str:
|
66
|
+
count_list[index] += 1
|
67
|
+
break
|
68
|
+
else:
|
69
|
+
value_list.append(element)
|
70
|
+
count_list.append(1)
|
71
|
+
|
72
|
+
# Convert.
|
73
|
+
result = [
|
74
|
+
{
|
75
|
+
'value': value,
|
76
|
+
'count': count
|
77
|
+
}
|
78
|
+
for value, count in zip(value_list, count_list)
|
79
|
+
]
|
80
|
+
|
81
|
+
# Sort.
|
82
|
+
result.sort(
|
83
|
+
key=lambda info: info['count'],
|
84
|
+
reverse=not ascend
|
85
|
+
)
|
86
|
+
|
87
|
+
return result
|
88
|
+
|
89
|
+
|
90
|
+
def flatten(data: Any, *, _flattern_data: Optional[list] = None) -> list:
|
91
|
+
"""
|
92
|
+
Flatten data.
|
93
|
+
|
94
|
+
Parameters
|
95
|
+
----------
|
96
|
+
data : Data.
|
97
|
+
_flattern_data : Recursion cumulative data.
|
98
|
+
|
99
|
+
Returns
|
100
|
+
-------
|
101
|
+
Data after flatten.
|
102
|
+
"""
|
103
|
+
|
104
|
+
# Handle parameter.
|
105
|
+
_flattern_data = _flattern_data or []
|
106
|
+
|
107
|
+
# Flatten.
|
108
|
+
|
109
|
+
## Recursion dict object.
|
110
|
+
if data.__class__ == dict:
|
111
|
+
for element in data.values():
|
112
|
+
_flattern_data = flatten(
|
113
|
+
element,
|
114
|
+
_flattern_data = _flattern_data
|
115
|
+
)
|
116
|
+
|
117
|
+
## Recursion iterator.
|
118
|
+
elif is_iterable(data):
|
119
|
+
for element in data:
|
120
|
+
_flattern_data = flatten(
|
121
|
+
element,
|
122
|
+
_flattern_data = _flattern_data
|
123
|
+
)
|
124
|
+
|
125
|
+
## Other.
|
126
|
+
else:
|
127
|
+
_flattern_data.append(data)
|
128
|
+
|
129
|
+
return _flattern_data
|
130
|
+
|
131
|
+
|
132
|
+
@overload
|
133
|
+
def split(data: Iterable[Element], share: None = None, bin_size: None = None) -> NoReturn: ...
|
134
|
+
|
135
|
+
@overload
|
136
|
+
def split(data: Iterable[Element], share: int = None, bin_size: int = None) -> NoReturn: ...
|
137
|
+
|
138
|
+
@overload
|
139
|
+
def split(data: Iterable[Element], share: Optional[int] = None, bin_size: Optional[int] = None) -> list[list[Element]]: ...
|
140
|
+
|
141
|
+
def split(data: Iterable[Element], share: Optional[int] = None, bin_size: Optional[int] = None) -> list[list[Element]]:
|
142
|
+
"""
|
143
|
+
Split data into multiple data.
|
144
|
+
|
145
|
+
Parameters
|
146
|
+
----------
|
147
|
+
data : Data.
|
148
|
+
share : Number of split share.
|
149
|
+
bin_size : Size of each bin.
|
150
|
+
|
151
|
+
Returns
|
152
|
+
-------
|
153
|
+
Split data.
|
154
|
+
"""
|
155
|
+
|
156
|
+
# Check parameter.
|
157
|
+
check_least_one(share, bin_size)
|
158
|
+
check_most_one(share, bin_size)
|
159
|
+
|
160
|
+
# Handle parameter.
|
161
|
+
data = list(data)
|
162
|
+
|
163
|
+
# Split.
|
164
|
+
data_len = len(data)
|
165
|
+
_data = []
|
166
|
+
_data_len = 0
|
167
|
+
|
168
|
+
## by number of share.
|
169
|
+
if share is not None:
|
170
|
+
average = data_len / share
|
171
|
+
for n in range(share):
|
172
|
+
bin_size = int(average * (n + 1)) - int(average * n)
|
173
|
+
_data = data[_data_len:_data_len + bin_size]
|
174
|
+
_data.append(_data)
|
175
|
+
_data_len += bin_size
|
176
|
+
|
177
|
+
## By size of bin.
|
178
|
+
elif bin_size is not None:
|
179
|
+
while True:
|
180
|
+
_data = data[_data_len:_data_len + bin_size]
|
181
|
+
_data.append(_data)
|
182
|
+
_data_len += bin_size
|
183
|
+
if _data_len > data_len:
|
184
|
+
break
|
185
|
+
|
186
|
+
return _data
|
187
|
+
|
188
|
+
|
189
|
+
def unique(data: Iterable[Element]) -> list[Element]:
|
190
|
+
"""
|
191
|
+
De duplication of data.
|
192
|
+
|
193
|
+
Parameters
|
194
|
+
----------
|
195
|
+
data : Data.
|
196
|
+
|
197
|
+
Returns
|
198
|
+
-------
|
199
|
+
List after de duplication.
|
200
|
+
"""
|
201
|
+
|
202
|
+
# Handle parameter.
|
203
|
+
data = tuple(data)
|
204
|
+
|
205
|
+
# Delete duplicate.
|
206
|
+
data_unique = list(set(data))
|
207
|
+
data_unique.sort(key=data.index)
|
208
|
+
return data_unique
|
209
|
+
|
210
|
+
|
211
|
+
def in_arrs(ojb: Any, *arrs: Iterable, mode: Literal['or', 'and'] = 'or') -> bool:
|
212
|
+
"""
|
213
|
+
Judge whether the one object is in multiple arrays.
|
214
|
+
|
215
|
+
Parameters
|
216
|
+
----------
|
217
|
+
obj : One object.
|
218
|
+
arrs : Multiple arrays.
|
219
|
+
mode : Judge mode.
|
220
|
+
- `Literal['or']`: Judge whether the in a certain array.
|
221
|
+
- `Literal['and']`: Judge whether the in all arrays.
|
222
|
+
|
223
|
+
Returns
|
224
|
+
-------
|
225
|
+
Judge result.
|
226
|
+
"""
|
227
|
+
|
228
|
+
# Judge.
|
229
|
+
match mode:
|
230
|
+
|
231
|
+
## Or.
|
232
|
+
case 'or':
|
233
|
+
for arr in arrs:
|
234
|
+
if ojb in arr:
|
235
|
+
return True
|
236
|
+
|
237
|
+
return False
|
238
|
+
|
239
|
+
## And.
|
240
|
+
case 'and':
|
241
|
+
for arr in arrs:
|
242
|
+
if ojb not in arr:
|
243
|
+
return False
|
244
|
+
|
245
|
+
return True
|
246
|
+
|
247
|
+
|
248
|
+
def objs_in(arr: Iterable, *objs: Any, mode: Literal['or', 'and'] = 'or') -> bool:
|
249
|
+
"""
|
250
|
+
Judge whether the multiple objects is in one array.
|
251
|
+
|
252
|
+
Parameters
|
253
|
+
----------
|
254
|
+
arr : One array.
|
255
|
+
objs : Multiple objects.
|
256
|
+
mode : Judge mode.
|
257
|
+
- `Literal['or']`: Judge whether contain a certain object.
|
258
|
+
- `Literal['and']`: Judge whether contain all objects.
|
259
|
+
|
260
|
+
Returns
|
261
|
+
-------
|
262
|
+
Judge result.
|
263
|
+
"""
|
264
|
+
|
265
|
+
# Judge.
|
266
|
+
match mode:
|
267
|
+
|
268
|
+
## Or.
|
269
|
+
case 'or':
|
270
|
+
for obj in objs:
|
271
|
+
if obj in arr:
|
272
|
+
return True
|
273
|
+
|
274
|
+
return False
|
275
|
+
|
276
|
+
## And.
|
277
|
+
case 'and':
|
278
|
+
for obj in objs:
|
279
|
+
if obj not in arr:
|
280
|
+
return False
|
281
|
+
|
282
|
+
return True
|
283
|
+
|
284
|
+
|
285
|
+
class RGenerator(object):
|
286
|
+
"""
|
287
|
+
Rey's `generator` type.
|
288
|
+
"""
|
289
|
+
|
290
|
+
|
291
|
+
def __init__(
|
292
|
+
self,
|
293
|
+
func: Callable,
|
294
|
+
*args: Any,
|
295
|
+
**kwargs: Any
|
296
|
+
) -> None:
|
297
|
+
"""
|
298
|
+
Build `generator` attributes.
|
299
|
+
|
300
|
+
Parameters
|
301
|
+
----------
|
302
|
+
func : Generate function.
|
303
|
+
args : Function default position arguments.
|
304
|
+
kwargs : Function default keyword arguments.
|
305
|
+
"""
|
306
|
+
|
307
|
+
# Set attribute.
|
308
|
+
self.func = func
|
309
|
+
self.args = args
|
310
|
+
self.kwargs = kwargs
|
311
|
+
self.params: list[tuple[tuple, dict]] = []
|
312
|
+
self.generator = self._generator()
|
313
|
+
|
314
|
+
|
315
|
+
def _generator(self) -> Generator[Any, Any, None]:
|
316
|
+
"""
|
317
|
+
Create generator.
|
318
|
+
|
319
|
+
Parameters
|
320
|
+
----------
|
321
|
+
Generator.
|
322
|
+
"""
|
323
|
+
|
324
|
+
# Loop.
|
325
|
+
while True:
|
326
|
+
|
327
|
+
# Break.
|
328
|
+
if self.params == []:
|
329
|
+
break
|
330
|
+
|
331
|
+
# Generate.
|
332
|
+
args, kwargs = self.params.pop(0)
|
333
|
+
result = self.func(*args, **kwargs)
|
334
|
+
|
335
|
+
# Return.
|
336
|
+
yield result
|
337
|
+
|
338
|
+
|
339
|
+
def add(
|
340
|
+
self,
|
341
|
+
*args: Any,
|
342
|
+
**kwargs: Any
|
343
|
+
) -> None:
|
344
|
+
"""
|
345
|
+
Add once generate.
|
346
|
+
|
347
|
+
Parameters
|
348
|
+
----------
|
349
|
+
args : Function position arguments.
|
350
|
+
kwargs : Function keyword arguments.
|
351
|
+
"""
|
352
|
+
|
353
|
+
# Set parameter.
|
354
|
+
func_args = (
|
355
|
+
*self.args,
|
356
|
+
*args
|
357
|
+
)
|
358
|
+
func_kwargs = {
|
359
|
+
**self.kwargs,
|
360
|
+
**kwargs
|
361
|
+
}
|
362
|
+
|
363
|
+
# Add.
|
364
|
+
item = (
|
365
|
+
func_args,
|
366
|
+
func_kwargs
|
367
|
+
)
|
368
|
+
self.params.append(item)
|
369
|
+
|
370
|
+
|
371
|
+
__call__ = add
|
372
|
+
|
373
|
+
|
374
|
+
def __next__(self) -> Any:
|
375
|
+
"""
|
376
|
+
Generate once from generator.
|
377
|
+
|
378
|
+
Returns
|
379
|
+
-------
|
380
|
+
Generate value.
|
381
|
+
"""
|
382
|
+
|
383
|
+
# Generate.
|
384
|
+
result = next(self.generator)
|
385
|
+
|
386
|
+
return result
|
387
|
+
|
388
|
+
|
389
|
+
def __iter__(self) -> Generator[Any, Any, None]:
|
390
|
+
"""
|
391
|
+
Iterating generator.
|
392
|
+
"""
|
393
|
+
|
394
|
+
# Iterating.
|
395
|
+
return self.generator
|
reykit/rdll/__init__.py
ADDED
@@ -0,0 +1,17 @@
|
|
1
|
+
# !/usr/bin/env python
|
2
|
+
# -*- coding: utf-8 -*-
|
3
|
+
|
4
|
+
"""
|
5
|
+
@Time : 2023-12-06 16:14:11
|
6
|
+
@Author : Rey
|
7
|
+
@Contact : reyxbo@163.com
|
8
|
+
@Explain : DLL file methods.
|
9
|
+
|
10
|
+
Modules
|
11
|
+
-------
|
12
|
+
rdll_inject_core : DLL file inject method code.
|
13
|
+
rdll_inject : DLL file inject method.
|
14
|
+
"""
|
15
|
+
|
16
|
+
|
17
|
+
from .rdll_inject import *
|
@@ -0,0 +1,41 @@
|
|
1
|
+
# !/usr/bin/env python
|
2
|
+
# -*- coding: utf-8 -*-
|
3
|
+
|
4
|
+
"""
|
5
|
+
@Time : 2023-12-06 16:09:59
|
6
|
+
@Author : Rey
|
7
|
+
@Contact : reyxbo@163.com
|
8
|
+
@Explain : Inject DLL file methods.
|
9
|
+
"""
|
10
|
+
|
11
|
+
|
12
|
+
__all__ = (
|
13
|
+
'inject_dll',
|
14
|
+
)
|
15
|
+
|
16
|
+
|
17
|
+
def inject_dll(
|
18
|
+
id_: int,
|
19
|
+
path: str
|
20
|
+
) -> None:
|
21
|
+
"""
|
22
|
+
Inject DLL file.
|
23
|
+
|
24
|
+
Parameters
|
25
|
+
----------
|
26
|
+
id_ : Process ID.
|
27
|
+
path : DLL file path.
|
28
|
+
"""
|
29
|
+
|
30
|
+
|
31
|
+
from ctypes import create_string_buffer
|
32
|
+
|
33
|
+
from .rdll_inject_core import InjectDLL
|
34
|
+
|
35
|
+
|
36
|
+
# Get parameter.
|
37
|
+
path_bytes = path.encode()
|
38
|
+
buffer = create_string_buffer(path_bytes)
|
39
|
+
|
40
|
+
# Inject.
|
41
|
+
InjectDLL(id_, buffer)
|
@@ -0,0 +1,202 @@
|
|
1
|
+
# !/usr/bin/env python
|
2
|
+
# -*- coding: utf-8 -*-
|
3
|
+
|
4
|
+
"""
|
5
|
+
@Time : 2023-12-06 16:17:04
|
6
|
+
@Author : Rey
|
7
|
+
@Contact : reyxbo@163.com
|
8
|
+
@Explain : DLL file inject method code.
|
9
|
+
"""
|
10
|
+
|
11
|
+
|
12
|
+
import ctypes
|
13
|
+
from ctypes.wintypes import (
|
14
|
+
HANDLE,
|
15
|
+
LPVOID,
|
16
|
+
DWORD,
|
17
|
+
BOOL,
|
18
|
+
LPCVOID,
|
19
|
+
HMODULE,
|
20
|
+
LPCSTR,
|
21
|
+
LPDWORD
|
22
|
+
)
|
23
|
+
import enum
|
24
|
+
|
25
|
+
|
26
|
+
def LPVOID_errcheck(result, func, args):
|
27
|
+
if not result:
|
28
|
+
raise ctypes.WinError()
|
29
|
+
return result
|
30
|
+
|
31
|
+
|
32
|
+
def Win32API_errcheck(result, func, args):
|
33
|
+
if not result:
|
34
|
+
raise ctypes.WinError()
|
35
|
+
|
36
|
+
|
37
|
+
class SECURITY_ATTRIBUTES(ctypes.Structure):
|
38
|
+
_fields_ = [
|
39
|
+
('nLength', DWORD),
|
40
|
+
('lpSecurityDescriptor', LPVOID),
|
41
|
+
('bInheritHandle', BOOL)
|
42
|
+
]
|
43
|
+
|
44
|
+
|
45
|
+
INFINITE = ctypes.c_uint(-1)
|
46
|
+
SIZE_T = ctypes.c_size_t
|
47
|
+
FARPROC = ctypes.CFUNCTYPE(ctypes.c_int, LPVOID)
|
48
|
+
LPTHREAD_START_ROUTINE = ctypes.CFUNCTYPE(DWORD, LPVOID)
|
49
|
+
|
50
|
+
VirtualAllocEx = ctypes.windll.kernel32.VirtualAllocEx
|
51
|
+
VirtualAllocEx.argtypes = [HANDLE, LPVOID, SIZE_T, DWORD, DWORD]
|
52
|
+
VirtualAllocEx.restype = LPVOID
|
53
|
+
VirtualAllocEx.errcheck = LPVOID_errcheck
|
54
|
+
|
55
|
+
VirtualFreeEx = ctypes.windll.kernel32.VirtualFreeEx
|
56
|
+
VirtualFreeEx.argtypes = [HANDLE, LPVOID, SIZE_T, DWORD]
|
57
|
+
VirtualFreeEx.restype = BOOL
|
58
|
+
VirtualFreeEx.errcheck = Win32API_errcheck
|
59
|
+
|
60
|
+
WriteProcessMemory = ctypes.windll.kernel32.WriteProcessMemory
|
61
|
+
WriteProcessMemory.argtypes = [HANDLE, LPVOID, LPCVOID, SIZE_T, ctypes.POINTER(SIZE_T)]
|
62
|
+
WriteProcessMemory.restype = BOOL
|
63
|
+
WriteProcessMemory.errcheck = Win32API_errcheck
|
64
|
+
|
65
|
+
GetProcAddress = ctypes.windll.kernel32.GetProcAddress
|
66
|
+
GetProcAddress.argtypes = [HMODULE, LPCSTR]
|
67
|
+
GetProcAddress.restype = FARPROC
|
68
|
+
|
69
|
+
OpenProcess = ctypes.windll.kernel32.OpenProcess
|
70
|
+
OpenProcess.argtypes = [DWORD, BOOL, DWORD]
|
71
|
+
OpenProcess.restype = HANDLE
|
72
|
+
OpenProcess.errcheck = LPVOID_errcheck
|
73
|
+
|
74
|
+
GetModuleHandleA = ctypes.windll.kernel32.GetModuleHandleA
|
75
|
+
GetModuleHandleA.argtypes = [LPCSTR]
|
76
|
+
GetModuleHandleA.restype = HMODULE
|
77
|
+
GetModuleHandleA.errcheck = LPVOID_errcheck
|
78
|
+
|
79
|
+
CloseHandle = ctypes.windll.kernel32.CloseHandle
|
80
|
+
CloseHandle.argtypes = [HANDLE]
|
81
|
+
CloseHandle.restype = BOOL
|
82
|
+
CloseHandle.errcheck = Win32API_errcheck
|
83
|
+
|
84
|
+
LPSECURITY_ATTRIBUTES = ctypes.POINTER(SECURITY_ATTRIBUTES)
|
85
|
+
CreateRemoteThread = ctypes.windll.kernel32.CreateRemoteThread
|
86
|
+
CreateRemoteThread.argtypes = [HANDLE, LPSECURITY_ATTRIBUTES, SIZE_T, LPTHREAD_START_ROUTINE, LPVOID, DWORD, LPDWORD]
|
87
|
+
CreateRemoteThread.restype = HANDLE
|
88
|
+
CreateRemoteThread.errcheck = LPVOID_errcheck
|
89
|
+
|
90
|
+
WaitForSingleObject = ctypes.windll.kernel32.WaitForSingleObject
|
91
|
+
WaitForSingleObject.argtypes = [HANDLE, DWORD]
|
92
|
+
WaitForSingleObject.restype = DWORD
|
93
|
+
|
94
|
+
GetExitCodeThread = ctypes.windll.kernel32.GetExitCodeThread
|
95
|
+
GetExitCodeThread.argtypes = [HANDLE, LPDWORD]
|
96
|
+
GetExitCodeThread.restype = BOOL
|
97
|
+
GetExitCodeThread.errcheck = Win32API_errcheck
|
98
|
+
|
99
|
+
|
100
|
+
class Process(enum.IntFlag):
|
101
|
+
CREATE_PROCESS = 0x0080
|
102
|
+
CREATE_THREAD = 0x0002
|
103
|
+
DUP_HANDLE = 0x0002
|
104
|
+
QUERY_INFORMATION = 0x0400
|
105
|
+
QUERY_LIMITED_INFORMATION = 0x1000
|
106
|
+
SET_INFORMATION = 0x0200
|
107
|
+
SET_QUOTA = 0x0100
|
108
|
+
SUSPEND_RESUME = 0x0800
|
109
|
+
TERMINATE = 0x0001
|
110
|
+
VM_OPERATION = 0x0008
|
111
|
+
VM_READ = 0x0010
|
112
|
+
VM_WRITE = 0x0020
|
113
|
+
SYNCHRONIZE = 0x00100000
|
114
|
+
|
115
|
+
|
116
|
+
class AllocationType(enum.IntFlag):
|
117
|
+
COMMIT = 0x00001000
|
118
|
+
RESERVE = 0x00002000
|
119
|
+
RESET = 0x00080000
|
120
|
+
RESET_UNDO = 0x1000000
|
121
|
+
LARGE_PAGES = 0x20000000
|
122
|
+
PHYSICAL = 0x00400000
|
123
|
+
TOP_DOWN = 0x00100000
|
124
|
+
|
125
|
+
|
126
|
+
class FreeType(enum.IntFlag):
|
127
|
+
COALESCE_PLACEHOLDERS = 0x1
|
128
|
+
PRESERVE_PLACEHOLDER = 0x2
|
129
|
+
DECOMMIT = 0x4000
|
130
|
+
RELEASE = 0x8000
|
131
|
+
|
132
|
+
|
133
|
+
class PageProtection(enum.IntFlag):
|
134
|
+
EXECUTE = 0x10
|
135
|
+
EXECUTE_READ = 0x20
|
136
|
+
EXECUTE_READWRITE = 0x40
|
137
|
+
EXECUTE_WRITECOPY = 0x80
|
138
|
+
NOACCESS = 0x01
|
139
|
+
READONLY = 0x02
|
140
|
+
READWRITE = 0x04
|
141
|
+
WRITECOPY = 0x08
|
142
|
+
TARGETS_INVALID = 0x40000000
|
143
|
+
TARGETS_NO_UPDATE = 0x40000000
|
144
|
+
GUARD = 0x100
|
145
|
+
NOCACHE = 0x200
|
146
|
+
WRITECOMBINE = 0x400
|
147
|
+
|
148
|
+
|
149
|
+
def InjectDLL(
|
150
|
+
target_pid,
|
151
|
+
filename_dll
|
152
|
+
):
|
153
|
+
|
154
|
+
target_handle = OpenProcess(
|
155
|
+
Process.CREATE_THREAD | Process.VM_OPERATION | Process.VM_READ | Process.VM_WRITE,
|
156
|
+
False,
|
157
|
+
target_pid
|
158
|
+
)
|
159
|
+
|
160
|
+
dll_path_addr = VirtualAllocEx(
|
161
|
+
target_handle,
|
162
|
+
None,
|
163
|
+
len(filename_dll),
|
164
|
+
AllocationType.COMMIT | AllocationType.RESERVE,
|
165
|
+
PageProtection.READWRITE
|
166
|
+
)
|
167
|
+
|
168
|
+
WriteProcessMemory(
|
169
|
+
target_handle,
|
170
|
+
dll_path_addr,
|
171
|
+
filename_dll,
|
172
|
+
len(filename_dll),
|
173
|
+
None
|
174
|
+
)
|
175
|
+
|
176
|
+
module_handle = GetModuleHandleA(b'Kernel32')
|
177
|
+
target_LoadLibraryA = GetProcAddress(module_handle, b'LoadLibraryA')
|
178
|
+
|
179
|
+
thread_handle = CreateRemoteThread(
|
180
|
+
target_handle,
|
181
|
+
None,
|
182
|
+
0,
|
183
|
+
ctypes.cast(
|
184
|
+
target_LoadLibraryA,
|
185
|
+
LPTHREAD_START_ROUTINE
|
186
|
+
),
|
187
|
+
dll_path_addr,
|
188
|
+
0,
|
189
|
+
None
|
190
|
+
)
|
191
|
+
|
192
|
+
WaitForSingleObject(thread_handle, INFINITE)
|
193
|
+
|
194
|
+
exit_code = DWORD()
|
195
|
+
GetExitCodeThread(thread_handle, ctypes.byref(exit_code))
|
196
|
+
|
197
|
+
try:
|
198
|
+
CloseHandle(thread_handle)
|
199
|
+
VirtualFreeEx(thread_handle, dll_path_addr, 0, FreeType.RELEASE)
|
200
|
+
CloseHandle(target_handle)
|
201
|
+
except OSError:
|
202
|
+
pass
|