python 读取内存地址_从python读取存储在绝对内存地址中的值

代码.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中的数字会变得这么大)

对于0,sys.getsizeof只返回PyObject_VAR_HEAD的大小,用于获取结构内部的数组偏移量

[Python 3]: int.to_bytes(length, byteorder, *, signed=False)用于验证,但请注意,只有当:0 <= n < 2 ** 30时,它才会匹配我们的输出(该方法对数组内容进行一些处理,它不会直接将原始数据存储到返回的字节流中)

很明显,与数字的十六进制表示相比,输出缓冲区中的字节(4字节)反转了(0x12345678是最有说服力的例子);这是因为小endianness(可以查看[SO]: Python struct.pack() behavior (@CristiFati's answer)了解更多详细信息)

输出:(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'


版权声明:本文为weixin_42287030原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。