Значение чтения хранится в абсолютном адресе памяти из python - PullRequest
0 голосов
/ 06 декабря 2018

Я использовал чит-движок, чтобы найти абсолютный адрес (см. Прикрепленное изображение ниже) Адрес памяти

Теперь я хотел бы узнать, как я могу прочитать значение, равное «1»с адреса "0x14340A654"

Я попытался найти то же самое в StackOverflow, и это то, что я мог бы собрать.

from ctypes import string_at
from sys import getsizeof
from binascii import hexlify
a = 0x14340A654
print(hexlify(string_at(id(a), getsizeof(a))))

Но это возвращает некоторый бред, такой как

b'030000000000000010bcabf2f87f0000020000000000000054a6400305000000'

1 Ответ

0 голосов
/ 13 декабря 2018

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 - (master) cpython / Objects / longobject.c ).Ниже приводится его определение:

    struct _longobject {
        PyObject_VAR_HEAD
        digit ob_digit[1];
    };
    
    • Массив в конце содержит фактическое числовое значение (поэтому числа в Python могут быть такими большими)
    • Для 0 , sys.getsizeof возвращает только PyObject_VAR_HEAD размер, который используется для получения смещения массива внутри структуры
  • [Python 3]: int. to_bytes ( length, byteorder, *, signature = False ) используется для проверки, но обратите внимание, что она будет совпадатьнаш вывод только если : 0 <= n < 2 ** 30 (метод выполняет некоторую обработку содержимого массива, он напрямую не сохраняет необработанные данные в возвращенный поток байтов)
  • Видно, что байты (4 байт ) обращены в выходном буфере ( 0x12345678 - наиболее красноречивый пример) по сравнению с числом hex представление;это из-за немного порядка байтов (можно проверить [SO]: поведение Python struct.pack () (ответ @ CristiFati) для более подробной информации)

Выход :

(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'
...