ntmemoryapi 2.2.2__tar.gz → 2.2.4__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.
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.3
2
2
  Name: ntmemoryapi
3
- Version: 2.2.2
3
+ Version: 2.2.4
4
4
  Summary: Simple library for Windows to manipulate process virtual memory with stelthy syscall wraps.
5
5
  Author: Xenely
6
6
  Requires-Dist: psutil>=7.1.3
@@ -1,6 +1,6 @@
1
1
  [project]
2
2
  name = "ntmemoryapi"
3
- version = "2.2.2"
3
+ version = "2.2.4"
4
4
  description = "Simple library for Windows to manipulate process virtual memory with stelthy syscall wraps."
5
5
  authors = [
6
6
  {name = "Xenely"}
@@ -489,7 +489,7 @@ class Process:
489
489
 
490
490
  return memory_old_protect.value or 0
491
491
 
492
- 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]:
492
+ 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, finalize_regions_callback: typing.Callable[[list[MEMORY_BASIC_INFORMATION]], None] | None = None) -> list[int]:
493
493
  """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"."""
494
494
 
495
495
  # Validate given pattern
@@ -527,25 +527,25 @@ class Process:
527
527
  if end_address is not None and region_start >= end_address:
528
528
  continue
529
529
 
530
- # Scan params
531
- scan_adderss = max(region_start, start_address) if start_address is not None else region_start
532
- scan_size = min(region_end, end_address) - scan_adderss if end_address is not None else region_end - scan_adderss
533
-
534
530
  # Save region information to scan later
535
- to_scan_regions.append((scan_adderss, scan_size))
531
+ to_scan_regions.append(region)
536
532
 
537
533
  # If no regions to scan presented
538
534
  if not to_scan_regions:
539
535
  return []
540
536
 
537
+ # If finalize scan regions callback is provided
538
+ if finalize_regions_callback:
539
+ finalize_regions_callback(to_scan_regions)
540
+
541
541
  # Result list of found addresses
542
542
  found_addresses = []
543
543
 
544
544
  # Pre-allocated buffer to hold read memory
545
- read_memory_buffer = (ctypes.c_byte * (max(item[-1] for item in to_scan_regions) + 1))()
545
+ read_memory_buffer = (ctypes.c_byte * (max(item.size for item in to_scan_regions) + 1))()
546
546
 
547
547
  # Iterate regions to scan read them and find pattern
548
- for scan_adderss, scan_size in to_scan_regions:
548
+ for region in to_scan_regions:
549
549
 
550
550
  # If required amount of addresses found
551
551
  if return_first is not None and return_first <= 0:
@@ -554,13 +554,13 @@ class Process:
554
554
  try:
555
555
 
556
556
  # Read bytes into pre-allocated buffer
557
- self.read_into_buffer(scan_adderss, scan_size, ctypes.c_void_p(ctypes.addressof(read_memory_buffer)))
557
+ self.read_into_buffer(region.base_address, region.size, ctypes.c_void_p(ctypes.addressof(read_memory_buffer)))
558
558
 
559
559
  except Exception:
560
560
  pass
561
561
 
562
562
  # Pattern scan region using SIMD KMP algorithm
563
- self.__kmp.scanAOB(ctypes.c_void_p(ctypes.addressof(read_memory_buffer)), scan_size, pattern.strip().encode(), ctypes.c_uint64(scan_adderss), ctypes.c_uint64(return_first if return_first is not None else 0), ctypes.byref(scan_result := PatternScanBuffer()))
563
+ self.__kmp.scanAOB(ctypes.c_void_p(ctypes.addressof(read_memory_buffer)), region.size, pattern.strip().encode(), ctypes.c_uint64(region.base_address), ctypes.c_uint64(return_first if return_first is not None else 0), ctypes.byref(scan_result := PatternScanBuffer()))
564
564
 
565
565
  # Read result addresses
566
566
  addresses = scan_result.read()
File without changes