What is the trick to get this working with Appcall? Both 32 and 64 bit do not seem to work.
def get_struct_info(struct_name: str):
sid = idaapi.get_named_type_tid(struct_name)
tif = idaapi.tinfo_t(tid=sid)
udt = idaapi.udt_type_data_t()
tif.get_udt_details(udt)
members_info = [{
"name": member.name,
"offset": member.offset//8,
"size": member.type.get_size(),
"type": member.type.dstr()
} for member in udt ]
return tif.get_size(), members_info
example_struct_ea = 0x7E758366E8
size, members = get_struct_info('example_struct')
mem_bytes = idaapi.get_bytes(example_struct_ea, size)
print(f'{mem_bytes=}')
for member in members:
offset = member["offset"]
size = member["size"]
print(f'{member=} {mem_bytes[offset: offset+size].hex()}')
mem_bytes=b'Q\x00\x00\x00\x00\x00\x00\n@\x00\x00\x00#\x01\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00'
member={'name': 'arg1', 'offset': 0, 'size': 4, 'type': 'uint32_t'} 51000000
member={'name': 'arg2', 'offset': 4, 'size': 2, 'type': 'uint16_t'} 0000
member={'name': 'arg3', 'offset': 6, 'size': 2, 'type': 'uint16_t'} 000a
member={'name': 'arg4', 'offset': 8, 'size': 1, 'type': 'uint8_t'} 40
member={'name': 'arg5', 'offset': 12, 'size': 4, 'type': 'uint32_t'} 23010000
member={'name': 'arg6', 'offset': 16, 'size': 2, 'type': 'uint16_t'} 0100
member={'name': 'arg7', 'offset': 20, 'size': 8, 'type': 'void *'} 0100000000000000
example_struct_typedobj = idaapi.Appcall.typedobj("example_struct;")
ok, header = example_struct_typedobj.retrieve(example_struct_ea)
print(f'{ok}, {header}')
0, -1
print(example_struct_typedobj.size)
28
print(idaapi.inf_is_64bit())
True
I can manually parse structures, but I’d love to use Appcalls dot notation. I had code that worked for this (32 bit) on 8.4 but maybe the API changed a bit on 9.0?
1 Like
I suppose I could do this
args = dict()
for member in members:
offset = member["offset"]
size = member["size"]
args.update({member["name"]: mem_bytes[offset: offset+size]})
and then call with this to get what I want.
idaapi.Appcall.obj(**args).arg1
idaapi.Appcall.obj(**args).arg2
...
...
1 Like
Ok… well. I can’t explain why but
Python>idaapi.Appcall.typedobj('example_struct;').retrieve(0x7E758366E8)[1].arg1
0x51
Python>idaapi.Appcall.typedobj('example_struct;').retrieve(0x7E758366E8)[1].arg2
0x0
Python>idaapi.Appcall.typedobj('example_struct;').retrieve(0x7E758366E8)[1].arg3
0xa00
Works in the GUI but when running CLI (headless) None of this works. Glad I wasn’t going crazy.
Any thoughts?
1 Like
I realize the namespace is different between “idapro headless module” and GUI but I’m still curious if this is a bug or intended behavior.
1 Like
igor
February 27, 2025, 3:31pm
5
Could you prepare a small binary and exact steps to reproduce the issue? Unfortunately, it’s a bit difficult to say what could be the problem from just this description.
1 Like
For any ARM ELF 32bit/64bit binary, if you can simply create an appcall typedobj and retrieve arbitrary data like in my example above using idapro.open_database (headless) then I’ll consider the issue on my end. for example
idaapi.Appcall.typedobj('example_struct;').retrieve(0x7E758366E8)
Where example_struct
is some structure and 0x7E758366E8
is whatever address you have with whatever bytes for the typedobj to “retrieve” and interpret/disaply.
For the same ARM ELF 32 or 64 bit database:
1 Like
It’s possible in 9.1 this is fixed per change log:
BUGFIX: idalib: Python plugins or processsor modules would not work in idalib context started from an external Python process
I’ll give it a go and report back!
1 Like
igor
March 5, 2025, 9:58am
8
IIRC Appcall requires an active debugger. I think debuggers do not yet work properly in idalib, but you may be able to use the “classic” batch mode (ida -Sscript.py
).
1 Like
I opened up the db I was working in, in 9.1 and instead of
print(f'{ok}, {header}')
0, -1
I now get
print(f'{ok}, {header}')
1, <ida_idaapi.object_t object at 0x13b4867b0>
In summary, my solution for Appcall not returning an object for typedobj retrieve was to update to 9.1
We’re all good now! Thanks team!
1 Like
igor
March 10, 2025, 9:48pm
10
Great, thanks for the update!