I know title isn't very clear so here is an example of a code I'm trying to disassemble:

struct Inner {
  int field1;
  int field2;
struct Outer {
  int some_data[16];
  struct Inner the_array[16];

int x(struct Outer* s, int id) {
  return s->the_array[id - 1].field2;

A compiler fuses all the offsets (positive offset of Inner within Outer, negative offset of -1 index and positive offset of field2 in Inner) into single offset. The complete function code follows:

movsxd  rax, esi
mov     eax, [rdi+rax*8+3Ch]

IDA and Hex-rays obviously think it is an offset into Outer::some_data and not into Outer::the_array. Corresponding pseudocode is:

__int64 __fastcall x(Outer *s, int id)
  return (unsigned int)s->some_data[2 * id + 15];

Is there any way to manually select which nested structure member is being accessed?

If someone wants to reproduce this example to play with it themselves, that code sample is a complete TU and Linux x86-64 clang 10 or newer produces the assembly code I shown (-O1 is enough for this optimization). Same source file can be then loaded into IDA as a C header to get the structures.


1 Answer 1


In the Pseudocode view, try to play with shifted pointers to account for the 8-byte offset (sizeof(*Inner))

If you declare s like this:

Outer *__shifted(Outer,8) s

You might get something looking like that:

return ADJ(s)->the_array[id].field2;
  • It kinda works for this example; -1 gets lost but I could live with that, and I'll be sure to use this. It's only a partial solution though: a) smaller issue - __shifted cast will be plastered all over all the callsites, if lucky; if unlucky, same __shifted type will be propagated upstream and will require manual overrides; b) this one is much worse - it doesn't work if the function happens to touch not only the_array but also some other fields of Outer. Commented Apr 11, 2022 at 9:04

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.