diff --git a/src/pystack/_pystack/cpython/string.h b/src/pystack/_pystack/cpython/string.h index a0967c2..eb18e34 100644 --- a/src/pystack/_pystack/cpython/string.h +++ b/src/pystack/_pystack/cpython/string.h @@ -12,11 +12,13 @@ typedef uint8_t Py_UCS1; typedef Py_UCS4 Py_UNICODE; typedef Py_ssize_t Py_hash_t; +namespace Python3 { typedef struct { PyObject_VAR_HEAD Py_hash_t ob_shash; char ob_sval[1]; } PyBytesObject; +} // namespace Python3 namespace Python2 { typedef struct @@ -107,6 +109,10 @@ typedef struct } // namespace Python3_12 +typedef union { + Python3::PyBytesObject v3; +} PyBytesObject; + typedef union { Python2::PyUnicodeObject v2; Python3::PyUnicodeObject v3; diff --git a/src/pystack/_pystack/process.cpp b/src/pystack/_pystack/process.cpp index 6299bf0..4b7dd3f 100644 --- a/src/pystack/_pystack/process.cpp +++ b/src/pystack/_pystack/process.cpp @@ -471,13 +471,14 @@ AbstractProcessManager::getBytesFromAddress(remote_addr_t addr) const << addr; PyBytesObject bytes; - copyObjectFromProcess(addr, &bytes); - - if ((len = bytes.ob_base.ob_size + 1) < 1) { - throw std::runtime_error("Incorrect size of the fetches bytes object"); + copyMemoryFromProcess(addr, offsets().py_bytes.size, &bytes); + len = getField(bytes, &py_bytes_v::o_ob_size) + 1; + if (len < 1) { + throw std::runtime_error("Incorrect size of the fetched bytes object"); } buffer.resize(len); - data_addr = (remote_addr_t)((char*)addr + offsetof(PyBytesObject, ob_sval)); + data_addr = addr + getFieldOffset(&py_bytes_v::o_ob_sval); + LOG(DEBUG) << std::hex << std::showbase << "Copying data for bytes object from address " << data_addr; copyMemoryFromProcess(data_addr, len, buffer.data()); diff --git a/src/pystack/_pystack/version.cpp b/src/pystack/_pystack/version.cpp index b2d5ec0..69ba621 100644 --- a/src/pystack/_pystack/version.cpp +++ b/src/pystack/_pystack/version.cpp @@ -297,6 +297,17 @@ py_object() }; } +template +constexpr py_bytes_v +py_bytes() +{ + return { + sizeof(T), + offsetof(T, ob_base.ob_size), + offsetof(T, ob_sval), + }; +} + template constexpr py_unicode_v py_unicode() @@ -410,6 +421,7 @@ python_v python_v2 = { py_float(), py_long<_PyLongObject>(), {}, + {}, py_object(), py_type(), py_code(), @@ -428,6 +440,7 @@ python_v python_v3_3 = { py_dictvalues(), py_float(), py_long<_PyLongObject>(), + py_bytes(), py_unicode(), py_object(), py_type(), @@ -447,6 +460,7 @@ python_v python_v3_4 = { py_dictvalues(), py_float(), py_long<_PyLongObject>(), + py_bytes(), py_unicode(), py_object(), py_type(), @@ -466,6 +480,7 @@ python_v python_v3_6 = { py_dictvalues(), py_float(), py_long<_PyLongObject>(), + py_bytes(), py_unicode(), py_object(), py_type(), @@ -485,6 +500,7 @@ python_v python_v3_7 = { py_dictvalues(), py_float(), py_long<_PyLongObject>(), + py_bytes(), py_unicode(), py_object(), py_type(), @@ -506,6 +522,7 @@ python_v python_v3_8 = { py_dictvalues(), py_float(), py_long<_PyLongObject>(), + py_bytes(), py_unicode(), py_object(), py_type(), @@ -527,6 +544,7 @@ python_v python_v3_9 = { py_dictvalues(), py_float(), py_long<_PyLongObject>(), + py_bytes(), py_unicode(), py_object(), py_type(), @@ -548,6 +566,7 @@ python_v python_v3_10 = { py_dictvalues(), py_float(), py_long<_PyLongObject>(), + py_bytes(), py_unicode(), py_object(), py_type(), @@ -569,6 +588,7 @@ python_v python_v3_11 = { py_dictvalues(), py_float(), py_long<_PyLongObject>(), + py_bytes(), py_unicode(), py_object(), py_type(), @@ -591,6 +611,7 @@ python_v python_v3_12 = { py_dictvalues(), py_float(), py_long<_PyLongObject>(), + py_bytes(), py_unicode(), py_object(), py_type(), @@ -613,6 +634,7 @@ python_v python_v3_13 = { py_dictvalues(), py_float(), py_long<_PyLongObject>(), + py_bytes(), py_unicode(), py_object(), py_type(), diff --git a/src/pystack/_pystack/version.h b/src/pystack/_pystack/version.h index 0f99161..3fc76c6 100644 --- a/src/pystack/_pystack/version.h +++ b/src/pystack/_pystack/version.h @@ -74,6 +74,14 @@ struct py_long_v FieldOffset o_ob_digit; }; +struct py_bytes_v +{ + typedef PyBytesObject Structure; + ssize_t size; + FieldOffset o_ob_size; + FieldOffset o_ob_sval; +}; + struct py_unicode_v { typedef PyUnicodeObject Structure; @@ -244,6 +252,7 @@ struct python_v py_dictvalues_v py_dictvalues; py_float_v py_float; py_long_v py_long; + py_bytes_v py_bytes; py_unicode_v py_unicode; py_object_v py_object; py_type_v py_type; @@ -273,6 +282,7 @@ define_python_v_get_specialization(py_dictkeys); define_python_v_get_specialization(py_dictvalues); define_python_v_get_specialization(py_float); define_python_v_get_specialization(py_long); +define_python_v_get_specialization(py_bytes); define_python_v_get_specialization(py_unicode); define_python_v_get_specialization(py_object); define_python_v_get_specialization(py_type);