Skip to content

Latest commit

 

History

History
139 lines (96 loc) · 3.74 KB

File metadata and controls

139 lines (96 loc) · 3.74 KB

Pystrector

The Py(thon) Str(uct) (Refl)ector

icon


Пакет для отображения и изменения внутренних структур Python.
Хотите увидеть, как объекты Python устроены внутри?
Тогда этот пакет для вас.

from pystrector import Binder
binder = Binder()
some_object = 1
reflector = binder.bind(some_object)
print(reflector.ob_base.ob_refcnt.pretty_value)

Python

Чтобы установить pystrector введите команду.

python3 -m pip install pystrector

Git

git clone https://github.com/bontail/pystrector.git

Documentation

Чтобы получить доступ к представлению основных структур, вам необходимо создать объект привязки

from pystrector import Binder
binder = Binder()

Теперь вы можете вызвать метод привязки, чтобы получить объект класса, представляющий структуру.

some_object = 1
reflector = binder.bind(some_object)

Объект отображателя имеет все те же поля, что и внутренняя структура

// core structure
struct _longobject {
     PyObject ob_base;
    _PyLongValue long_value;
};
class _longobject(DataType, is_union=False):
    ob_base = _object()
    long_value = _PyLongValue()

Если объект содержит anonymous_var, то можно сразу переходить к полям этого объекта

class anonymous_1(DataType, is_union=True):
    ob_refcnt = LongLong()
    ob_refcnt_split = UnsignedInt[2]

    
class _object(DataType, is_union=False):
    anonymous_var_1 = anonymous_1()
    ob_type = Pointer(datatype="_typeobject")


some_object = 1
reflector = binder.bind(some_object).cast_to(_object)
# print(reflector.anonymous_var_1.ob_refcnt.pretty_value)
print(reflector.ob_refcnt.pretty_value)

Для каждого типа вы можете вызвать pretty_value и bytes_value
pretty_value - приведет к наиболее похожему типу в Python
bytes_value - всегда возвращает bytearray

print(reflector.long_value.lv_tag.pretty_value)
print(reflector.long_value.lv_tag.bytes_value)

Вы также можете устанавливать значения
bytes_value - принимает только bytearray
pretty_value - принимает аналогичный тип Python
без параметров - берет другой объект отображателя

reflector.ob_base.ob_refcnt.bytes_value = bytearray(1)
reflector.ob_base.ob_refcnt.pretty_value = 1000
reflector.ob_base.ob_refcnt = binder.bind(7).ob_base.ob_refcnt

Также есть работа с указателями и массивами как в Cи

x = [1, 2, 3]
print(binder.bind(x).ob_item[j][1])
print(+(binder.bind(x).ob_item[j]))
print(+(binder.bind(x).ob_item[j] + 1))

Вы можете преобразовать отображатели одних типов данных в другие

from pystrector.core_datatypes import _longobject

x = [1, 2, 3]

binder.bind(x).ob_item[0][0].cast_to(_longobject) # need to cast because list saves PyObjects

Или использовать auto каст (работает только с PyObject)

x = [1, 2, 3]

binder.bind(x).ob_item[0][0].cast()

Больше примеров можно увидеть в тестах