2 回答

TA貢獻1719條經驗 獲得超6個贊
清單[Python 3.Docs]:ctypes - Python 的外部函數庫。
有很多問題(除了缺少一些信息的問題):
在使用ctypes函數(例如
ctypes.addressof
)時,您應該考慮到它們對ctypes(而不是Python)類型進行操作。因此,number必須轉換為ctypes類型(應該適合其值)。從其值創建指針是災難的秘訣通常,導入當前命名空間中的所有內容不是一個好主意([SO]:使用通配符導入的原因是什么?(@CristiFati 的回答))
您的[MS.Docs]: WriteProcessMemory 函數定義有點錯誤(不是關鍵),但最好使用現有別名(為了便于閱讀)
這是一個工作變體。
代碼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.
備注:
可以看到,指定地址的內存內容被成功寫入
唯一“異?!钡氖虑槭窃摂底志哂蠥SCII代碼['H' .. 'A'],但在緩沖區中它們看起來是相反的。那是因為我的電腦是Little-endian。如果您愿意看一下,我在[SO] 中介紹了這個主題:Python struct.pack() 行為(@CristiFati 的回答)

TA貢獻1874條經驗 獲得超12個贊
第一的, sizeof(c_void_p) = 4;
因為0x140000000
超過四個字節,會被截斷。
可以看到,在同樣的環境下,0x40000000和的結果0x140000000是一樣的。
您需要更改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]
最后,這是修改后的代碼。
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()
注意:在檢查* address1時hProcess,還要注意類型,使用長類型檢查address1。
添加回答
舉報