Search code examples
pythonctypes

Unexpected closure of Python program while using ReadProcessMemory from kernel32


I have a really weird behavior from my python program and I need your help to understand where to search.

I made quite a big a program using rpm (ReadProcessMemory from kernel32 windows DLL).

My issue is that my program sometimes closes without any Traceback nor Error. It does not go to the end and just stops running.

Let's show a simple piece of code :

rPM =ctypes.WinDLL('kernel32',use_last_error=True).ReadProcessMemory
rPM.argtypes = [wintypes.HANDLE,wintypes.LPCVOID,wintypes.LPVOID,ctypes.c_size_t,ctypes.POINTER(ctypes.c_size_t)]
rPM.restype = BOOL

def ReadMemory(self, pPath):
    pPath = int.from_bytes(pPath,"little")
    PathBuffer = ctypes.create_string_buffer(40)
    bytes_read = ctypes.c_size_t()
    if not rPM(self.handle,pPath,PathBuffer,40, bytes_read ):
        Logger.error("Cannot read Path from memory")
        return None
    DynamicX=struct.unpack("H", PathBuffer[0x02:0x02 + 2])[0]
    DynamicY=struct.unpack("H", PathBuffer[0x06:0x06 + 2])[0]
    StaticX=struct.unpack("H", PathBuffer[0x10:0x10 + 2])[0]
    StaticY=struct.unpack("H", PathBuffer[0x14:0x14 + 2])[0]
    return DynamicX, DynamicY, StaticX, StaticY

for i in range(50):
    Logger.debug("Read Info")
    ReadMemory()
    Logger.debug("Finished Read Info")
Logger.debug("End of program")

Sometimes it will stop at occurence #30, sometime # 45, etc... and sometimes it comes without any error at all and goes to the end, when running a failing program again it goes through this loop and fail in another one.

The memory I'm reading is the same between two different executions.

How could I get the reason for the closure ? I tried try: except: but never entering into the except catcher.

I'm using python 3.9.1 in windows.

Do you have a hint please, I really don't understand why and cannot fix it :(

Thanks !

Edit :

After more invetigation the crash is not always on rpm function, sometimes it's when using struct.unpack and sometimes (even stranger !) it's during the return statment !

I found on windows error logs a lot of APPCRASH :

Signature du problème
Nom d’événement du problème :   APPCRASH
Nom de l’application:   python.exe
Version de l’application:   3.7.6150.1013
Horodatage de l’application:    5dfac7ba
Nom du module défaillant:   python37.dll
Version du module défaillant:   3.7.6150.1013
Horodateur du module défaillant:    5dfac78b
Code de l’exception:    c0000005
Décalage de l’exception:    000000000004d547
Version du système: 10.0.19042.2.0.0.768.101
Identificateur de paramètres régionaux: 1036
Information supplémentaire n° 1:    c75e
Information supplémentaire n° 2:    c75e78fc0ea847c06758a77801e05e29
Information supplémentaire n° 3:    2730
Information supplémentaire n° 4:    27303d8be681197ea114e04ad6924f93

But I still don't know why it's crashing, I checked the memory and CPU usage of my computer and does not go higher than 60%. I tried (as you can see) also to change my python version to another one.


Solution

  • Thanks, finally found the issue !

    First step was to add :

    faulthandler.enable()
    

    It enables the windows crash event to be catched and display in std.err or a file.

    It has given me the same thing as @Mark Tolonen said. Read access violation !

    After knowing that I double checked my ReadMemory and the buffer size was bigger than expected. It means sometimes I tried to read more than the process memory and tried to read "somewhere else" : Eureka !

    Thanks for your tips Mark, I learnt a lot with this one !