Python Forum
Windows Python Memory Scanner
Thread Rating:
  • 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
Windows Python Memory Scanner
#1
Hi all, I trying to write a Python Windows Memory Scanner, that finds the addresses of a specific value. The complete code is at the bottom, and I'll explain how it works.

First, System info is called, and the values of

sysinfo.lpMinimumApplicationAddress
sysinfo.lpMaximumApplicationAddress

are obtained, so I can feed it to my loop which has VirtualQueryEx()
Kernel32.OpenProcess is used to be fed to ReadMemoryProcess.

Then finally, A loop is used to get VirtualQueryEx() to return base address to scan and it's
mbi.RegionSize.

And then:

I have the following code, and somehow I must have fed the read process
Memory incorrectly. what the code does is to check a region of memory to see
whether or not it can be scanned.

mbi.Protect == PAGE_READWRITE and mbi.State == MEM_COMMIT

If this is true,then it proceeds to scan the memory fro current_address to
current_address + mbi.RegionSize.

However, a strange thing happens: The loop runs twice successfully, and then it
pops:

raise ctypes.WinError(ctypes.get_last_error())
OSError: [WinError 299] Only part of a ReadProcessMemory or WriteProcessMemory request was completed.

Now, I know the problem is not with VirtualQueryEx, because if I comment out
the red part and just run VirtualQueryEx, it would actually skim through all regions
without a single error.

Somehow, if I use this:

index = current_address
end = current_address + mbi.RegionSize - 7

Where the end is less by 7, the loop would not pop any error and it would finish
the loop

What did I do wrong?

thanks!















This is the full code.

import ctypes
from ctypes.wintypes import WORD, DWORD, LPVOID

PVOID = LPVOID
SIZE_T = ctypes.c_size_t

# https://msdn.microsoft.com/en-us/library/aa383751#DWORD_PTR
if ctypes.sizeof(ctypes.c_void_p) == ctypes.sizeof(ctypes.c_ulonglong):
    DWORD_PTR = ctypes.c_ulonglong
elif ctypes.sizeof(ctypes.c_void_p) == ctypes.sizeof(ctypes.c_ulong):
    DWORD_PTR = ctypes.c_ulong

class SYSTEM_INFO(ctypes.Structure):
    """https://msdn.microsoft.com/en-us/library/ms724958"""
    class _U(ctypes.Union):
        class _S(ctypes.Structure):
            _fields_ = (('wProcessorArchitecture', WORD),
                        ('wReserved', WORD))
        _fields_ = (('dwOemId', DWORD), # obsolete
                    ('_s', _S))
        _anonymous_ = ('_s',)
    _fields_ = (('_u', _U),
                ('dwPageSize', DWORD),
                ('lpMinimumApplicationAddress', LPVOID),
                ('lpMaximumApplicationAddress', LPVOID),
                ('dwActiveProcessorMask',   DWORD_PTR),
                ('dwNumberOfProcessors',    DWORD),
                ('dwProcessorType',         DWORD),
                ('dwAllocationGranularity', DWORD),
                ('wProcessorLevel',    WORD),
                ('wProcessorRevision', WORD))
    _anonymous_ = ('_u',)

LPSYSTEM_INFO = ctypes.POINTER(SYSTEM_INFO)



Kernel32 = ctypes.WinDLL('kernel32', use_last_error=True)
Kernel32.GetSystemInfo.restype = None
Kernel32.GetSystemInfo.argtypes = (LPSYSTEM_INFO,)

sysinfo = SYSTEM_INFO()
Kernel32.GetSystemInfo(ctypes.byref(sysinfo))

print(sysinfo.lpMinimumApplicationAddress)
print(sysinfo.lpMaximumApplicationAddress)


# maybe it will change, maybe it won't. Assuming it won't.

# 2nd, get Open process.
import psutil
import sys

PID = 1234
        
PROCESS_QUERY_INFORMATION = 0x0400
PROCESS_VM_READ = 0x0010

Process = Kernel32.OpenProcess(PROCESS_QUERY_INFORMATION|PROCESS_VM_READ, False, PID)
print('process:', Process)



# 3rd

class MEMORY_BASIC_INFORMATION(ctypes.Structure):
    """https://msdn.microsoft.com/en-us/library/aa366775"""
    _fields_ = (('BaseAddress', PVOID),
                ('AllocationBase',    PVOID),
                ('AllocationProtect', DWORD),
                ('RegionSize', SIZE_T),
                ('State',   DWORD),
                ('Protect', DWORD),
                ('Type',    DWORD))

##PMEMORY_BASIC_INFORMATION = ctypes.POINTER(MEMORY_BASIC_INFORMATION)

mbi = MEMORY_BASIC_INFORMATION()
##sysinfo.lpMinimumApplicationAddress

print('VirtualQueryEx ran properly?',Kernel32.VirtualQueryEx(Process, \
    sysinfo.lpMinimumApplicationAddress, ctypes.byref(mbi),ctypes.sizeof(mbi)))


ReadProcessMemory = Kernel32.ReadProcessMemory

##
MEM_COMMIT = 0x00001000;
PAGE_READWRITE = 0x04;

##buffer = ctypes.c_uint()
buffer = ctypes.c_double()

nread = SIZE_T()

start = ctypes.c_void_p(mbi.BaseAddress)

current_address = sysinfo.lpMinimumApplicationAddress
end_address = sysinfo.lpMaximumApplicationAddress

while current_address < end_address:
    Kernel32.VirtualQueryEx(Process, \
    current_address, ctypes.byref(mbi),ctypes.sizeof(mbi))

    if mbi.Protect == PAGE_READWRITE and mbi.State == MEM_COMMIT :
        print('This region can be scanned!')
        index = current_address
        end = current_address + mbi.RegionSize

        while index < end:
            if ReadProcessMemory(Process, index, ctypes.byref(buffer), \
                                 ctypes.sizeof(buffer), ctypes.byref(nread)):
                ## value comparison to be implemented.
                pass   
            else:
                print('else happend.')
##                pass
##                raise ctypes.WinError(ctypes.get_last_error())

            index += 1
            
    current_address += mbi.RegionSize
Reply
#2
(Oct-08-2017, 10:39 PM)Awesometech Wrote: Hi all, I trying to write a Python Windows Memory Scanner, that finds the addresses....
You read ctypes.sizeof(buffer) bytes, but your increment and check (index < end, inndex += 1) about 1 byte.
So fix is simple:
index += ctypes.sizeof(buffer)

p.s. thx for code :)
Reply


Possibly Related Threads…
Thread Author Replies Views Last Post
  python list out top 10 Memory utilisation mg24 0 809 Nov-20-2022, 10:51 PM
Last Post: mg24
Bug Embedded Python Memory Leaks Alexei 1 1,033 Sep-16-2022, 01:15 PM
Last Post: Alexei
  Use Barcode Scanner With Python Extra 2 1,606 Jul-14-2022, 09:52 AM
Last Post: Gribouillis
  port scanner Than999 0 1,203 Feb-01-2022, 12:24 PM
Last Post: Than999
  Python BLE Scanner not detecting device alexanderDennisEnviro500 0 2,011 Aug-01-2021, 02:29 AM
Last Post: alexanderDennisEnviro500
  python memory rd_rakesh 1 1,653 Jul-14-2021, 11:15 AM
Last Post: jefsummers
  waiting for barcode scanner output, while main program continues to run lightframe109 3 4,656 Sep-03-2020, 02:19 PM
Last Post: DeaD_EyE
  memory leak on embedded python in c++ asdf3721 3 3,386 Jul-16-2020, 06:33 AM
Last Post: Gribouillis
  keyboad scanner routine(linux and windows) 1885 0 1,912 Oct-26-2019, 03:34 PM
Last Post: 1885
  How to get memory usage and execution time of each line in python SriRajesh 2 3,124 Mar-07-2019, 12:59 PM
Last Post: SriRajesh

Forum Jump:

User Panel Messages

Announcements
Announcement #1 8/1/2020
Announcement #2 8/2/2020
Announcement #3 8/6/2020