Skip to content

Commit 45119b6

Browse files
committed
feat: support structs with pointers to not-yet-inflated structs
1 parent bcb864a commit 45119b6

2 files changed

Lines changed: 19 additions & 16 deletions

File tree

libdestruct/common/type_inflater.py

Lines changed: 19 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,9 @@ def inflate_field(self: TypeInflater, own: type, field: StructField, address: in
4949
if not field.backing_type:
5050
field.backing_type = own
5151
elif issubclass(field.backing_type, struct) and not issubclass(field.backing_type, struct_impl):
52+
if not hasattr(field.backing_type, "_type_impl"):
53+
self._inflate_struct_type(field.backing_type)
54+
5255
field.backing_type = field.backing_type._type_impl
5356

5457
return field.inflate(self.memory, address)
@@ -63,20 +66,10 @@ def inflate_struct(self: TypeInflater, reference_type: type, address: int | tupl
6366
Returns:
6467
The inflated struct.
6568
"""
66-
if hasattr(reference_type, "_type_impl"):
67-
type_impl = reference_type._type_impl
68-
instance = type_impl(self.memory, address)
69-
else:
70-
type_impl = type(reference_type.__name__, (struct_impl,), {"_members": {}})
71-
72-
type_impl._reference_struct = None
69+
self._inflate_struct_type(reference_type)
7370

74-
instance = type_impl(self.memory, address)
75-
76-
type_impl._reference_struct = reference_type
77-
type_impl._inflater = self
78-
79-
reference_type._type_impl = type_impl
71+
type_impl = reference_type._type_impl
72+
instance = type_impl(self.memory, address)
8073

8174
self._inflate_struct_instance(instance, reference_type)
8275

@@ -100,3 +93,16 @@ def _inflate_struct_instance(self: TypeInflater, instance: struct_impl, referenc
10093
current_offset += annotation.size
10194

10295
instance.size = current_offset
96+
97+
def _inflate_struct_type(self: TypeInflater, reference_type: type) -> None:
98+
if hasattr(reference_type, "_type_impl"):
99+
return
100+
101+
type_impl = type(reference_type.__name__, (struct_impl,), {"_members": {}})
102+
103+
type_impl._reference_struct = None
104+
105+
reference_type._type_impl = type_impl
106+
107+
type_impl._reference_struct = reference_type
108+
type_impl._inflater = self

test/scripts/basic_struct_test.py

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -230,9 +230,6 @@ class test8(struct):
230230

231231
struct_ptr = d.regs.rdi
232232

233-
# TODO: this is a hack, fix
234-
_ = libdestruct.inflate(test5, 0x0)
235-
236233
test = libdestruct.inflate(test8, struct_ptr)
237234

238235
self.assertEqual(test.a.unwrap().a.value, 0x5eadbeef)

0 commit comments

Comments
 (0)