Python Ctypes-将整数的地址传递给WriteProcessMemory
我想写入Python Ctypes-将整数的地址传递给WriteProcessMemory,python,python-3.x,pointers,winapi,ctypes,Python,Python 3.x,Pointers,Winapi,Ctypes,我想写入address1整数number1的值。我尝试使用addressof,但仍然不起作用。什么是等同于和从C++?< /p> windll.kernel32.WriteProcessMemory.argtypes = [c_void_p, c_void_p, c_char_p, c_int, c_void_p] windll.kernel32.WriteProcessMemory.restype = c_void_p address1 = 0xa9a010 number1 = 0x14000
address1
整数number1
的值。我尝试使用addressof
,但仍然不起作用。什么是等同于<代码>和<代码>从C++?< /p>
windll.kernel32.WriteProcessMemory.argtypes = [c_void_p, c_void_p, c_char_p, c_int, c_void_p]
windll.kernel32.WriteProcessMemory.restype = c_void_p
address1 = 0xa9a010
number1 = 0x140000000
lpNumberOfBytesWritten = c_size_t(0)
if windll.kernel32.WriteProcessMemory(
hProcess,
c_char_p(address1),
addressof(c_char_p(number1)),
sizeof(c_void_p),
byref(lpNumberOfBytesWritten)) == 0:
error()
所需输出为*address1=0x140000000,但它首先包含其他值,,
sizeof(c\u void\u p)=4代码>
因为0x140000000
超过了四个字节,它将被截断
您可以看到,在相同的环境下,0x40000000
和0x140000000
的结果是相同的
您需要将sizeof(c\u void\u p)
更改为sizeof(c\u longlong)
其次,根据的功能原型
BOOL WriteProcessMemory(
HANDLE hProcess,
LPVOID lpBaseAddress,
LPCVOID lpBuffer,
SIZE_T nSize,
SIZE_T *lpNumberOfBytesWritten
);
您可以看到lpBuffer
的类型是VOID*
因此,您需要将windell.kernel32.WriteProcessMemory.argtypes=[c\u void\u p,c\u void\u p,c\u char\u p,c\u int,c\u void\u p]
更改为windell.kernel32.WriteProcessMemory.argtypes=[c\u void\u p,c\u void\p,c\u void\p,c\u int,c\u void\p]
最后,这是修改后的代码。
windll.kernel32.WriteProcessMemory.argtypes = [c_void_p, c_void_p, c_void_p, c_int, c_void_p]
windll.kernel32.WriteProcessMemory.restype = c_void_p
address1 = 0xa9a010
number1 = 0x140000000
lpNumberOfBytesWritten = c_size_t(0)
if windll.kernel32.WriteProcessMemory(
hProcess,
c_char_p(address1),
addressof(c_longlong(number1)),
sizeof(c_longlong),
byref(lpNumberOfBytesWritten)) == 0:
error()
注意:在hProcess
中检查*地址1
时,还应注意类型,并使用长类型检查地址1列表
有许多问题(除了缺少一些信息的问题):
> p>当使用cType函数(例如,代码> cType。< /COD> >)时,应考虑它们在<强> cType < /强>(不Python)类型上的操作。因此,数字必须转换为ctypes类型(该类型应适合其值)。从指针的值创建指针会导致灾难
- 通常,导入当前名称空间中的所有内容不是一个好主意()
- 您的定义有点错误(不重要),但最好使用现有别名(为了可读性)
这是一个有效的变体
代码00.py:
#/usr/bin/env蟒蛇3
导入系统
导入ctypes
从ctypes导入wintypes
def main():
kernel32=ctypes.windell(“kernel32.dll”)
GetCurrentProcess=kernel32.GetCurrentProcess
GetCurrentProcess.argtypes=[]
GetCurrentProcess.restype=wintypes.HANDLE
WriteProcessMemory=kernel32.WriteProcessMemory
WriteProcessMemory.argtypes=[wintypes.HANDLE,wintypes.LPVOID,wintypes.LPCVOID,ctypes.c\u size\t,ctypes.POINTER(ctypes.c\u size\t)]
WriteProcessMemory.restypes=wintypes.BOOL
buf=ctypes.创建字符串缓冲区(b“0123456789”)
打印(“缓冲区初始内容:[{0:}].”格式(buf.value))
number=ctypes.c_ulonglong(0x4847464544434241)#8字节:ASCII码H。。A.
address=ctypes.addressof(buf)#模拟您的地址-这是上述缓冲区的
字节到写入=ctypes.sizeof(数字)
bytes\u Write=ctypes.c\u size\u t(0)
打印(“试图将({0:d}字节)编号{1:d}(0x{2:016X})写入地址{3:}(0x{4:016X})…..”。格式(字节_-to _-write,number.value,number.value,address,address))
res=WriteProcessMemory(GetCurrentProcess(),地址,ctypes.addressof(数字),字节到写入,ctypes.byref(字节写入))
如果有的话:
打印(“写入的{0:d}字节”。格式(字节\写入的.value))
打印(“缓冲区最终内容:[{0:}]”。格式(buf.value))
如果名称=“\uuuuu main\uuuuuuuu”:
打印(“Python{0:s}{1:d}位在{2:s}\n.format(“.join(sys.version.split(“\n”)中的项的item.strip()),如果sys.maxsize>0x100000000,则为64,否则为32,sys.platform))
main()
打印(“\n完成”)
输出:
[cfati@CFATI-5510-0:e:\Work\Dev\StackOverflow\q057768711]>“e:\Work\Dev\VEnvs\py\u 064\u 03.07.03\u test0\Scripts\python.exe”code00.py
Python 3.7.3(v3.7.3:ef4ec6ed12,2019年3月25日,22:22:05)[MSC v.1916 64位(AMD64)]win32上的64位
缓冲区初始内容:[b'0123456789']
正在尝试将(8字节)号码5208208757389214273(0x4847464544434241)写入地址1807564046992(0x000001A4DB368290)。。。
写了8个字节
缓冲区最终内容:[b'ABCDEFGH89']
完成。
注释:
- 如图所示,指定地址的内存内容已成功写入
- 唯一“不正常”的是,该数字的ASCII码是['H'..'A'],但在缓冲区中,它们看起来是相反的。那是因为我的电脑是小endian。如果你愿意看一看,我在
还请包括您的值(以及使用的任何变量)。@CristiFati address1=0xa9a010,number1=0x140000000。我想要-*address1=0x14000000你应该在问题中加上这个。还有lpNumberOfBytesWritten什么是lpNumberOfBytesWritten值?另一个价值是什么?和写之前一样吗。谢谢你的详细解释,它成功了!答案中有一些不正确的地方,从sizeof(c_void_p)=4开始,这只适用于(现在开始过时的)32位。