从python读取存储在绝对内存地址中的值 [英] Reading value stored in absolute memory address from python
问题描述
我使用了作弊引擎来查找绝对地址(请参见下面的图片)
内存地址
I used cheat engine to find an absolute address (See the attached image below) Memory address
现在我想知道如何从地址 0x14340A654中读取值为 1的
Now I would like to know how can I read the value which is "1" from an address which is "0x14340A654"
我试图在StackOverflow上找到相同的东西,这就是我可以收集的东西。
I tried finding the same on StackOverflow and this is what I could gather.
from ctypes import string_at
from sys import getsizeof
from binascii import hexlify
a = 0x14340A654
print(hexlify(string_at(id(a), getsizeof(a))))
但这会返回一些乱码,例如
But this returns some gibberish like
b'030000000000000010bcabf2f87f0000020000000000000054a6400305000000'
推荐答案
code.py :
#!/usr/bin/env python3
import sys
import ctypes
def get_long_data(long_obj):
py_obj_header_size = sys.getsizeof(0)
number_size = sys.getsizeof(long_obj) - py_obj_header_size
number_address = id(long_obj) + py_obj_header_size
return number_address, number_size, long_obj < 0
def hex_repr(number, size=0):
format_base = "0x{{:0{:d}X}}".format(size)
if number < 0:
return ("-" + format_base).format(-number)
else:
return format_base.format(number)
def main():
numbers = [0x00,
0x01,
-0x01,
0xFF,
0xFFFF,
0x00FFFFFF,
0x12345678,
0x3FFFFFFF,
0x40000000,
0x1111111111
]
for number in numbers:
address, size, negative = get_long_data(number)
print("Number: {:s}".format(hex_repr(number, size), size, negative))
buf = ctypes.string_at(address, size)
print(" Address: {:s}, Size: {:d}, Negative: {:},\n Data: {:}".format(hex_repr(address, size=16), size, negative, buf))
print(" ({:d}).to_bytes(): {:}".format(number, number.to_bytes(size, sys.byteorder, signed=(number < 0))))
if __name__ == "__main__":
print("Python {:s} on {:s}\n".format(sys.version, sys.platform))
main()
注释:
- get_long_data 是完成工作的函数(其他仅用于显示/测试目的)
- 仅地址是一种无用的东西(如果要重构数字),这就是为什么大小(以字节为单位)和数字的符号是还返回了
-
代码依赖于 [Python 3]: PyLongObject 的结构(大多数 int 功能位于 [GitHub]:python / cpython-(主)cpython / Objects / longobject.c )。在其定义下方:
- get_long_data is the function that does the work (everything else it's just for display / test purposes)
- The address alone is kind of useless (if one wants to be able to reconstruct the number), that's why the size (in bytes), and the sign of the number are returned as well
The code relies on [Python 3]: PyLongObject's structure (most of int functionality is located in [GitHub]: python/cpython - (master) cpython/Objects/longobject.c). Below it's its definition:
struct _longobject {
PyObject_VAR_HEAD
digit ob_digit[1];
};
- 最后的数组保留实际数字值(这就是为什么数字在 Python 中会变得很大)
- 对于 0 ,
sys。 getsizeof
仅返回 PyObject_VAR_HEAD 的大小,该大小用于获取结构内部的数组偏移量 - The array at the end holds the actual number value (that's why numbers in Python can get so big)
- For 0,
sys.getsizeof
only returns PyObject_VAR_HEAD's size, that's used to get the array offset inside the structure
输出:
(py35x64_test) e:\Work\Dev\StackOverflow\q053657865>"e:\Work\Dev\VEnvs\py35x64_test\Scripts\python.exe" code.py
Python 3.5.4 (v3.5.4:3f56838, Aug 8 2017, 02:17:05) [MSC v.1900 64 bit (AMD64)] on win32
Number: 0x0
Address: 0x0000000074C55318, Size: 0, Negative: False,
Data: b''
(0).to_bytes(): b''
Number: 0x0001
Address: 0x0000000074C55338, Size: 4, Negative: False,
Data: b'\x01\x00\x00\x00'
(1).to_bytes(): b'\x01\x00\x00\x00'
Number: -0x0001
Address: 0x0000000074C552F8, Size: 4, Negative: True,
Data: b'\x01\x00\x00\x00'
(-1).to_bytes(): b'\xff\xff\xff\xff'
Number: 0x00FF
Address: 0x0000000074C572F8, Size: 4, Negative: False,
Data: b'\xff\x00\x00\x00'
(255).to_bytes(): b'\xff\x00\x00\x00'
Number: 0xFFFF
Address: 0x0000023286E3A6C8, Size: 4, Negative: False,
Data: b'\xff\xff\x00\x00'
(65535).to_bytes(): b'\xff\xff\x00\x00'
Number: 0xFFFFFF
Address: 0x0000023286C14FA8, Size: 4, Negative: False,
Data: b'\xff\xff\xff\x00'
(16777215).to_bytes(): b'\xff\xff\xff\x00'
Number: 0x12345678
Address: 0x0000023286DE4E88, Size: 4, Negative: False,
Data: b'xV4\x12'
(305419896).to_bytes(): b'xV4\x12'
Number: 0x3FFFFFFF
Address: 0x000002328710C128, Size: 4, Negative: False,
Data: b'\xff\xff\xff?'
(1073741823).to_bytes(): b'\xff\xff\xff?'
Number: 0x40000000
Address: 0x000002328710C108, Size: 8, Negative: False,
Data: b'\x00\x00\x00\x00\x01\x00\x00\x00'
(1073741824).to_bytes(): b'\x00\x00\x00@\x00\x00\x00\x00'
Number: 0x1111111111
Address: 0x000002328710C148, Size: 8, Negative: False,
Data: b'\x11\x11\x11\x11D\x00\x00\x00'
(73300775185).to_bytes(): b'\x11\x11\x11\x11\x11\x00\x00\x00'
这篇关于从python读取存储在绝对内存地址中的值的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!