使用 kernel32 中的 ReadProcessMemory 时 Python 程序意外关闭

Unexpected closure of Python program while using ReadProcessMemory from kernel32

我的 python 程序有一个非常奇怪的行为,我需要你的帮助来了解在哪里搜索。

我使用 rpm(来自 kernel32 windows DLL 的 ReadProcessMemory)制作了一个相当大的程序。

我的问题是我的程序有时会在没有任何 Traceback 或错误的情况下关闭。 它不会走到尽头,只是停止 运行.

让我们展示一段简单的代码:

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")

有时会在#30 处停止,有时会在#45 处停止,等等... 有时它完全没有任何错误并走到最后,当 运行 一个失败的程序再次经过这个循环并在另一个循环中失败。

我正在读取的内存在两次不同的执行之间是相同的。

我怎么知道关闭的原因?我试过 try: except: 但从未进入 except 捕手。

我在 windows 中使用 python 3.9.1。

你有什么提示吗,我真的不明白为什么也无法修复:(

谢谢!

编辑:

经过更多调查,崩溃并不总是在 rpm 功能上,有时是在使用 struct.unpack 时,有时(甚至是陌生人!)是在 return 语句期间!

我在 windows 错误日志中发现了很多 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

但我仍然不知道它为什么会崩溃,我检查了我计算机的内存和 CPU 使用率,并没有超过 60%。 我也尝试(如您所见)将我的 python 版本更改为另一个版本。

谢谢,终于找到问题了!

第一步是添加:

faulthandler.enable()

它可以捕获 windows 崩溃事件并将其显示在 std.err 或文件中。

它给了我和@Mark Tolonen 说的一样的东西。读取访问冲突!

在知道我仔细检查了我的 ReadMemory 后发现缓冲区大小比预期的要大。这意味着有时我试图阅读的不仅仅是进程内存,还试图阅读“其他地方”:Eureka !

感谢马克的提示,我从中学到了很多东西!