我正在使用
ctypes
并尝试使用 PEB
函数获取 NtQueryInformationProcess
地址。
返回值为0,表示函数成功完成。 但是
PROCESS_BASIC_INFORMATION
结构(作为第三个参数给出)不包含 PEB
地址。
class PROCESS_BASIC_INFORMATION(Structure):
_fields_ = [
("Reserved1", c_void_p),
("PebBaseAddress", DWORD),
("Reserved2", c_void_p * 2),
("UniqueProcessId", DWORD),
("Reserved3", c_void_p)]
ntdll = WinDLL('ntdll')
NTSTATUS = LONG
ntdll.argtypes = [HANDLE, DWORD, c_void_p, DWORD, PDWORD]
ntdll.restype = NTSTATUS
processInformation = PROCESS_BASIC_INFORMATION()
processInformationLength = sizeof(PROCESS_BASIC_INFORMATION)
result = ntdll.NtQueryInformationProcess(hProcess, 0, processInformation, processInformationLength, byref(DWORD(0)))
考虑一下返回值为0,这可能是什么问题?
清单 [Python.Docs]:ctypes - Python 的外部函数库。
您为 wrong 对象 (ntdll) 定义了 argtypes 和 restype。您应该为 ntdll.NtQueryInformationProcess 定义它们。这就是 Undefined Behavior。检查[SO]:通过 ctypes 从 Python 调用的 C 函数返回不正确的值(@CristiFati 的答案),了解使用 CTypes(调用函数)时的常见陷阱。
当我们在这里时,很明显您喜欢DWORD。即使在这种情况下没有区别,请保持函数签名与 C:
ntdll.NtQueryInformationProcess.argtypes = (HANDLE, c_int, c_void_p, ULONG, PULONG)
ntdll.NtQueryInformationProcess.restype = NTSTATUS
根据[MS.Learn]:NtQueryInformationProcess函数(winternl.h)(强调是我的):
ProcessInformation
指向调用应用程序提供的缓冲区的指针,函数将请求的信息写入其中。
因此,您的调用应该类似于(通过引用传递 processInformation):
result = ntdll.NtQueryInformationProcess(hProcess, 0, byref(processInformation), processInformationLength, byref(DWORD(0)))
根据同一页面,您的结构定义不正确。应该是:
class PROCESS_BASIC_INFORMATION(Structure):
_fields_ = (
("Reserved1", c_void_p),
("PebBaseAddress", c_void_p),
("Reserved2", c_void_p * 2),
("UniqueProcessId", c_void_p),
("Reserved3", c_void_p),
)
您的版本(在 064bit 上)短了 8 个字节(因为 DWORD 和指针之间的(2)大小差异),导致传递给函数的缓冲区太短,即 Undefined B行为(可能导致崩溃)