Ctypes将整数的地址传递给WriteProcessMemory

2024-07-08 10:46:09 发布

您现在位置:Python中文网/ 问答频道 /正文

我想把address1的值写入number1,它是一个整数。我试图使用addressof,但仍然不起作用。c++中的&的等价物是什么?在

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,但它包含其他值


Tags: sizeif整数intcharvoidnumber1address1
2条回答

首先,sizeof(c_void_p) = 4;

因为0x140000000超过四个字节,它将被截断。在

1

您可以看到,在相同的环境下,0x40000000和{}的结果是相同的。在

您需要将sizeof(c_void_p)更改为sizeof(c_longlong)

其次,根据WriteProcessMemory的功能原型

BOOL WriteProcessMemory(
  HANDLE  hProcess,
  LPVOID  lpBaseAddress,
  LPCVOID lpBuffer,
  SIZE_T  nSize,
  SIZE_T  *lpNumberOfBytesWritten
);

您可以看到lpBuffer的类型是VOID*

所以您需要将windll.kernel32.WriteProcessMemory.argtypes = [c_void_p, c_void_p, c_char_p, c_int, c_void_p]更改为windll.kernel32.WriteProcessMemory.argtypes = [c_void_p, c_void_p, c_void_p, c_int, c_void_p]

最后,这是修改后的代码。

^{pr2}$

注意:hProcess检查* address1时,还应注意类型,并使用长类型来检查address1。在

清单[Python 3.Docs]: ctypes - A foreign function library for Python。在

有很多问题(除了缺少一些信息的问题):

这是一个工作变体。在

代码00.py

#!/usr/bin/env python3

import sys
import ctypes
from ctypes import wintypes


def main():
    kernel32 = ctypes.WinDLL("kernel32.dll")

    GetCurrentProcess = kernel32.GetCurrentProcess

    GetCurrentProcess.argtypes = []
    GetCurrentProcess.restype = wintypes.HANDLE

    WriteProcessMemory = kernel32.WriteProcessMemory
    WriteProcessMemory.argtypes = [wintypes.HANDLE, wintypes.LPVOID, wintypes.LPCVOID, ctypes.c_size_t, ctypes.POINTER(ctypes.c_size_t)]
    WriteProcessMemory.restypes = wintypes.BOOL

    buf = ctypes.create_string_buffer(b"0123456789")
    print("Buffer INITIAL contents: [{0:}]".format(buf.value))
    number = ctypes.c_ulonglong(0x4847464544434241)  # 8 bytes: ASCII codes H .. A
    address = ctypes.addressof(buf)  # Mimic your address - which is the above buffer's
    bytes_to_write = ctypes.sizeof(number)
    bytes_written = ctypes.c_size_t(0)
    print("Attempting to write ({0:d} bytes) number {1:d} (0x{2:016X}) to address {3:} (0x{4:016X}) ...".format(bytes_to_write, number.value, number.value, address, address))

    res = WriteProcessMemory(GetCurrentProcess(), address, ctypes.addressof(number), bytes_to_write, ctypes.byref(bytes_written))
    if res:
        print("Wrote {0:d} bytes".format(bytes_written.value))
        print("Buffer FINAL contents: [{0:}]".format(buf.value))



if __name__ == "__main__":
    print("Python {0:s} {1:d}bit on {2:s}\n".format(" ".join(item.strip() for item in sys.version.split("\n")), 64 if sys.maxsize > 0x100000000 else 32, sys.platform))
    main()
    print("\nDone.")

输出

[cfati@CFATI-5510-0:e:\Work\Dev\StackOverflow\q057768711]> "e:\Work\Dev\VEnvs\py_064_03.07.03_test0\Scripts\python.exe" code00.py
Python 3.7.3 (v3.7.3:ef4ec6ed12, Mar 25 2019, 22:22:05) [MSC v.1916 64 bit (AMD64)] 64bit on win32

Buffer INITIAL contents: [b'0123456789']
Attempting to write (8 bytes) number 5208208757389214273 (0x4847464544434241) to address 1807564046992 (0x000001A4DB368290) ...
Wrote 8 bytes
Buffer FINAL contents: [b'ABCDEFGH89']

Done.

注意事项

  • 如图所示,指定地址的内存内容已成功写入
  • 唯一“不正常”的事情是这个数字有ASCII代码['H'…'一个'],但在缓冲区中它们显示为相反的。那是因为我的电脑是小端。如果你想看一看,我在[SO]: Python struct.pack() behavior (@CristiFati's answer)中讨论过这个主题

相关问题 更多 >

    热门问题