提问人:Ali Can Gönüllü 提问时间:10/31/2023 最后编辑:Ali Can Gönüllü 更新时间:10/31/2023 访问量:65
Python ctypes 长整数错误,我该如何解决这个问题?
Python ctypes long integer error, how can i fix this?
问:
我正在使用 Python 开发内存快照/采集软件,因此我使用“pymem_snapshot”库和“winpmem”驱动程序。
import ctypes
import struct
import sys
import win32file
import win32service
import os
from ctypes import *
def CTL_CODE(DeviceType, Function, Method, Access):
return (DeviceType << 16) | (Access << 14) | (Function << 2) | Method
CTRL_IOCTRL = CTL_CODE(0x22, 0x101, 3, 3) # IOCTL_SET_MODE
INFO_IOCTRL = CTL_CODE(0x22, 0x103, 3, 3)
IOCTL_REVERSE_SEARCH_QUERY = CTL_CODE(0x22, 0x104, 3, 3)
class PyMem:
FIELDS = (["CR3", "NtBuildNumber", "KernBase", "KDBG"] +
["KPCR%02d" % i for i in range(32)] +
["PfnDataBase", "PsLoadedModuleList", "PsActiveProcessHead"] +
["Padding%s" % i for i in range(0xff)] +
["NumberOfRuns"])
def GetInfo(fd):
result = win32file.DeviceIoControl(fd, INFO_IOCTRL, b"", 102400, None)
fmt_string = "Q" * len(PyMem.FIELDS)
memory_parameters = dict(zip(PyMem.FIELDS, struct.unpack_from(fmt_string, result)))
for k, v in sorted(memory_parameters.items()):
if k.startswith("Pad"):
continue
if not v: continue
print("%s: \t%#08x (%s)" % (k, v, v))
def SetMode(fd, modeset = "pte"):
try:
if modeset == "iospace":
mode = 0
elif modeset == "physical":
mode = 1
elif modeset == "pte":
mode = 2
elif modeset == "pte_pci":
mode = 3
else:
raise RuntimeError("Mode %s not supported" % str(modeset))
win32file.DeviceIoControl(fd, CTRL_IOCTRL, struct.pack("I", mode), 0, None)
print(f"Mode has been set to {modeset}")
except Exception as e:
return str(e)
def service_create():
try:
os.system(f"net stop winpmem") # Stop any previous instance of the driver
os.system(f"sc delete winpmem") # Delete any previous instance of the driver
if ctypes.sizeof(ctypes.c_voidp) == 4:
if os.path.isfile("winpmem_x86.sys") is True:
driver_path = "winpmem_x86.sys"
else:
return "Driver file are not found"
else:
if os.path.isfile("winpmem_x64.sys") is True:
driver_path = "winpmem_x64.sys"
else:
return "Driver file are not found"
# Create a new instance of the driver
driver = os.path.join(os.getcwd(), driver_path)
hScm = win32service.OpenSCManager(None, None, win32service.SC_MANAGER_CREATE_SERVICE)
try:
hSvc = win32service.CreateService(hScm, "winpmem", "winpmem", win32service.SERVICE_ALL_ACCESS, win32service.SERVICE_KERNEL_DRIVER, win32service.SERVICE_DEMAND_START, win32service.SERVICE_ERROR_IGNORE, driver, None, 0, None, None, None)
except win32service.error as e:
print(e)
hSvc = win32service.OpenService(hScm, "winpmem", win32service.SERVICE_ALL_ACCESS)
try:
win32service.ControlService(hSvc, win32service.SERVICE_CONTROL_STOP)
except win32service.error:
pass
try:
win32service.StartService(hSvc, [])
except win32service.error as e:
print("%s: will try to continue" % e)
print("WinPMEM Started")
except Exception as e:
print("ERROR : WinPMEM can not created. Reason : " + str(e))
@staticmethod
def dump_and_save_memory(filename, memsize = int(1024 * 1024)):
print("Creating AFF4 (Rekall) file")
device_handle = win32file.CreateFile(
"\\\\.\\pmem",
win32file.GENERIC_READ | win32file.GENERIC_WRITE,
win32file.FILE_SHARE_READ | win32file.FILE_SHARE_WRITE,
None,
win32file.OPEN_EXISTING,
win32file.FILE_ATTRIBUTE_NORMAL,
None)
# Set Modes and get informations
if device_handle is True:
print("Error: open device failed.\n")
else:
PyMem.SetMode(device_handle)
PyMem.GetInfo(device_handle)
print("\nMEMSIZE : " + str(memsize))
with open(filename + ".aff", "wb") as f:
mem_addr = 0
while mem_addr < memsize:
win32file.SetFilePointer(device_handle, mem_addr, 0) # Setting pointer
data = win32file.ReadFile(device_handle, memsize)[1] # Reading memory...
f.write(data) # Writing to file
mem_addr += memsize
offset_in_mb = mem_addr / 1024 / 1024
if not offset_in_mb % 50:
sys.stdout.write("\n%04dMB\t" % offset_in_mb)
sys.stdout.flush()
print(f"Dumped {mem_addr} / {memsize} bytes and {offset_in_mb} MB/offset ({mem_addr * 100 / memsize:.2f}%)")
f.close()
win32file.CloseHandle(device_handle)
但是当我想获得大容量内存(超过 2GB)时,我会出现整数错误。
我的程序(稳定版)
from src.pymem_class import PyMem
if __name__ == "__main__":
PyMem.service_create()
# Drivers: https://github.com/Velocidex/WinPmem/tree/master/kernel/binaries
# Run "bcdedit /set testsigning on" command
# Check Memory Compression with "Get-MMAgent" command
# Disable Memory Compression with "Disable-MMAgent -mc" command
# Restart computer
PyMem.dump_and_save_memory("demo", int(1024 * 1024 * 1024)) # 1 GB Memory Image WORKING
我的程序(崩溃)
from src.pymem_class import PyMem
if __name__ == "__main__":
PyMem.service_create()
# Drivers: https://github.com/Velocidex/WinPmem/tree/master/kernel/binaries
# Run "bcdedit /set testsigning on" command
# Check Memory Compression with "Get-MMAgent" command
# Disable Memory Compression with "Disable-MMAgent -mc" command
# Restart computer
PyMem.dump_and_save_memory("demo", int(8 * 1024 * 1024 * 1024)) # 8 GB Memory Image CRASH
崩溃日志
Traceback (most recent call last):
File "C:\Users\dfnss\OneDrive\Desktop\pymem_snapshot\example.py", line 11, in <module>
PyMem.dump_and_save_memory("demo", memsize)
File "C:\Users\dfnss\OneDrive\Desktop\pymem_snapshot\src\pymem_class.py", line 51, in dump_and_save_memory
data = win32file.ReadFile(device_handle, memsize)[1] # Reading memory...
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
TypeError: Second param must be an integer or writeable buffer object
我该如何解决这个问题?我什至尝试了 ChatGPT 的帮助,但没有用
感谢您的回答
答:
-1赞
Schnitte
10/31/2023
#1
Pymem 需要一个整数 (of ) 类型作为内存大小的参数。Python 上的数据类型范围从 -2,147,483,648 到 + 2,147,483,647
(来源:在此处输入链接描述)。这意味着您的方程在此范围内,但并非如此。int
int
1024 * 1024 * 1024
8 * 1024 * 1024 * 1024
评论
0赞
Ali Can Gönüllü
10/31/2023
谢谢你的回答,我忘了这个。当然,有一个整数限制:)
0赞
CristiFati
10/31/2023
不對。整数是无限的:docs.python.org/3/library/...。
0赞
Ali Can Gönüllü
10/31/2023
那么,我可以生产什么作为这种方法的替代品呢?坦率地说,我正在寻找更清晰的答案。因为程序有点复杂
评论
memsize