ntmemoryapi 1.6.3__tar.gz → 1.7.1__tar.gz
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.
- {ntmemoryapi-1.6.3 → ntmemoryapi-1.7.1}/PKG-INFO +1 -1
- {ntmemoryapi-1.6.3 → ntmemoryapi-1.7.1}/pyproject.toml +1 -1
- {ntmemoryapi-1.6.3 → ntmemoryapi-1.7.1}/src/ntmemoryapi/__init__.py +20 -32
- {ntmemoryapi-1.6.3 → ntmemoryapi-1.7.1}/README.md +0 -0
- {ntmemoryapi-1.6.3 → ntmemoryapi-1.7.1}/src/ntmemoryapi/embed.py +0 -0
- {ntmemoryapi-1.6.3 → ntmemoryapi-1.7.1}/src/ntmemoryapi/misc.py +0 -0
|
@@ -20,7 +20,6 @@ syscall_wrapper = DirectSyscallWrapper()
|
|
|
20
20
|
|
|
21
21
|
PROCESS_ID = 1
|
|
22
22
|
PROCESS_NAME = 2
|
|
23
|
-
PROCESS_USERNAME = 4
|
|
24
23
|
|
|
25
24
|
|
|
26
25
|
# ==-------------------------------------------------------------------== #
|
|
@@ -238,28 +237,21 @@ _nt_protect_virtual_memory = syscall_wrapper.wrap("NtProtectVirtualMemory", resu
|
|
|
238
237
|
# ==-------------------------------------------------------------------== #
|
|
239
238
|
# Functions #
|
|
240
239
|
# ==-------------------------------------------------------------------== #
|
|
241
|
-
def list_processes(include_process_information: int = PROCESS_ID | PROCESS_NAME
|
|
240
|
+
def list_processes(include_process_information: int = PROCESS_ID | PROCESS_NAME) -> list[dict[str, int | str]]:
|
|
242
241
|
"""List all of the currently active system processes."""
|
|
243
242
|
|
|
244
243
|
# If `include_id` and `include_name` disabled both
|
|
245
244
|
if not include_process_information & PROCESS_ID and not include_process_information & PROCESS_NAME:
|
|
246
245
|
raise Exception("Unable to disable ID and name including at once")
|
|
247
246
|
|
|
248
|
-
# Current process username
|
|
249
|
-
current_username = psutil.Process().username()
|
|
250
|
-
|
|
251
247
|
# Result list of processes
|
|
252
|
-
processes =
|
|
248
|
+
processes = []
|
|
253
249
|
|
|
254
250
|
# Process iteration
|
|
255
251
|
for process in psutil.process_iter():
|
|
256
252
|
|
|
257
|
-
# If process started not from current username
|
|
258
|
-
if current_username_only and process.username() != current_username:
|
|
259
|
-
continue
|
|
260
|
-
|
|
261
253
|
# Save process to list
|
|
262
|
-
process_dict =
|
|
254
|
+
process_dict = {}
|
|
263
255
|
|
|
264
256
|
# If process ID including required
|
|
265
257
|
if include_process_information & PROCESS_ID:
|
|
@@ -269,10 +261,6 @@ def list_processes(include_process_information: int = PROCESS_ID | PROCESS_NAME
|
|
|
269
261
|
if include_process_information & PROCESS_NAME:
|
|
270
262
|
process_dict |= {"name": process.name()}
|
|
271
263
|
|
|
272
|
-
# If process username including required
|
|
273
|
-
if include_process_information & PROCESS_USERNAME:
|
|
274
|
-
process_dict |= {"username": process.username()}
|
|
275
|
-
|
|
276
264
|
# Save process information to list
|
|
277
265
|
processes.append(process_dict)
|
|
278
266
|
|
|
@@ -289,17 +277,17 @@ class Process:
|
|
|
289
277
|
# Methods #
|
|
290
278
|
# ==-------------------------------------------------------------------== #
|
|
291
279
|
|
|
292
|
-
def __init__(self, name_or_pid: int | str, access: int = PROCESS_ALL_ACCESS
|
|
280
|
+
def __init__(self, name_or_pid: int | str, access: int = PROCESS_ALL_ACCESS) -> None:
|
|
293
281
|
"""Initialize instance to manipulate process."""
|
|
294
282
|
|
|
295
283
|
# Open process by it's ID or it's name
|
|
296
284
|
match name_or_pid:
|
|
297
285
|
|
|
298
|
-
case
|
|
299
|
-
self.handle, self.
|
|
286
|
+
case int():
|
|
287
|
+
self.handle, self.pid, self.name = self.__init_with_pid(name_or_pid, access)
|
|
300
288
|
|
|
301
|
-
case
|
|
302
|
-
self.handle, self.
|
|
289
|
+
case str():
|
|
290
|
+
self.handle, self.pid, self.name = self.__init_with_name(name_or_pid, access)
|
|
303
291
|
|
|
304
292
|
case _:
|
|
305
293
|
raise Exception("Invalid `pid_or_name` argument value, have to be `int` or `str` type")
|
|
@@ -331,7 +319,7 @@ class Process:
|
|
|
331
319
|
raise Exception("Unable to create snapshot to iterate process modules")
|
|
332
320
|
|
|
333
321
|
# Result list of process modules
|
|
334
|
-
process_modules =
|
|
322
|
+
process_modules = []
|
|
335
323
|
|
|
336
324
|
# Process modules enumeration
|
|
337
325
|
try:
|
|
@@ -364,11 +352,11 @@ class Process:
|
|
|
364
352
|
|
|
365
353
|
return process_modules
|
|
366
354
|
|
|
367
|
-
def list_memory_regions(self, allowed_states: list[int] =
|
|
355
|
+
def list_memory_regions(self, allowed_states: list[int] = [], allowed_protects: list[int] = [], allowed_types: list[int] = [], memory_regions_filter: typing.Callable[[MEMORY_BASIC_INFORMATION], bool] | None = None) -> list[MEMORY_BASIC_INFORMATION]:
|
|
368
356
|
"""List all of the aviable process memory regions."""
|
|
369
357
|
|
|
370
358
|
# Result list of memory regions
|
|
371
|
-
memory_regions =
|
|
359
|
+
memory_regions = []
|
|
372
360
|
|
|
373
361
|
# Iterate all of the process memory regions
|
|
374
362
|
current_address = 0
|
|
@@ -487,7 +475,7 @@ class Process:
|
|
|
487
475
|
|
|
488
476
|
return memory_old_protect.value or 0
|
|
489
477
|
|
|
490
|
-
def pattern_scan(self, pattern: str, allowed_states: list[int] = [MEM_COMMIT], allowed_protects: list[int] = [PAGE_READWRITE], allowed_types: list[int] =
|
|
478
|
+
def pattern_scan(self, pattern: str, allowed_states: list[int] = [MEM_COMMIT], allowed_protects: list[int] = [PAGE_READWRITE], allowed_types: list[int] = [], start_address: int | None = None, end_address: int | None = None, return_first: int | None = None, memory_regions_filter: typing.Callable[[MEMORY_BASIC_INFORMATION], bool] | None = None) -> list[int]:
|
|
491
479
|
"""Scan process and return address that validates given pattern hex byte mask, use `??` to wildcard byte, for example - "14 00 00 00 DB FF ?? ?? FF FF 00 00"."""
|
|
492
480
|
|
|
493
481
|
# Validate given pattern
|
|
@@ -504,7 +492,7 @@ class Process:
|
|
|
504
492
|
raise Exception("Invalid pattern: `%s`" % pattern)
|
|
505
493
|
|
|
506
494
|
# Result list of found addresses
|
|
507
|
-
found_addresses =
|
|
495
|
+
found_addresses = []
|
|
508
496
|
|
|
509
497
|
# iterate memory regions and finding addresses at them
|
|
510
498
|
for region in self.list_memory_regions(allowed_states, allowed_protects, allowed_types, memory_regions_filter):
|
|
@@ -758,11 +746,11 @@ class Process:
|
|
|
758
746
|
# ==-------------------------------------------------------------------== #
|
|
759
747
|
# Private methods #
|
|
760
748
|
# ==-------------------------------------------------------------------== #
|
|
761
|
-
def __init_with_pid(self, pid: int, access: int,
|
|
749
|
+
def __init_with_pid(self, pid: int, access: int, listed_processes: list[dict[str, int | str]] | None = None) -> tuple[int, int, str]:
|
|
762
750
|
"""Open process handle by it's ID with desired access."""
|
|
763
751
|
|
|
764
|
-
# Iterate all of the processes
|
|
765
|
-
for process in list_processes(
|
|
752
|
+
# Iterate all of the processes
|
|
753
|
+
for process in listed_processes if listed_processes is not None else list_processes():
|
|
766
754
|
|
|
767
755
|
# If process have a reqired name
|
|
768
756
|
if process["id"] == pid:
|
|
@@ -790,16 +778,16 @@ class Process:
|
|
|
790
778
|
else:
|
|
791
779
|
raise Exception("NtOpenProcess failed with status: 0x%s" % hex(result)[2:].upper())
|
|
792
780
|
|
|
793
|
-
return handle.value,
|
|
781
|
+
return handle.value, pid, process_name
|
|
794
782
|
|
|
795
|
-
def __init_with_name(self, name: str, access: int
|
|
783
|
+
def __init_with_name(self, name: str, access: int) -> tuple[int, int, str]:
|
|
796
784
|
"""Open process hanle by it's name with desired access."""
|
|
797
785
|
|
|
798
786
|
# Iterate all of the processes using snapshot
|
|
799
|
-
for process in list_processes(
|
|
787
|
+
for process in (listed_processes := list_processes()):
|
|
800
788
|
|
|
801
789
|
# If process have a reqired name
|
|
802
790
|
if process["name"].lower() == name.strip().lower():
|
|
803
|
-
return self.__init_with_pid(process["id"], access,
|
|
791
|
+
return self.__init_with_pid(process["id"], access, listed_processes)
|
|
804
792
|
|
|
805
793
|
raise Exception("Process with `%s` name not found" % name)
|
|
File without changes
|
|
File without changes
|
|
File without changes
|