I'm working on a windows program which is walking PEB Ldr list. the related types are as follows:

    LIST_ENTRY InLoadOrderLinks;         // offset = 0, size = 0x10
    LIST_ENTRY InMemoryOrderLinks;   // offset = 0x10, size = 0x10
    // ...
    UNICODE_STRING FullDllName;       // offset = 0x48, size = 0x10
    UNICODE_STRING BaseDllName;     // offset = 0x58, size = 0x10

the pseudocode IDA generated is like that:

i = (LDR_DATA_TABLE_ENTRY *)NtCurrentPeb()->Ldr->InMemoryOrderModuleList.Flink;
CurDllName = i->FullDllName.Buffer;     // FullDllName should be BaseDllName!
CurDllNameLength = i->FullDllName.Length;

The problem is, i->FullDllName should be i->BaseDllName, because i is not LDR_DATA_TABLE_ENTRY * but actually LDR_DATA_TABLE_ENTRY * + 0x10 (address of LDR_DATA_TABLE_ENTRY.InMemoryOrderLinks).

The correct output should be like that:

i = NtCurrentPeb()->Ldr->InMemoryOrderModuleList.Flink;
CurDllName = Node->BaseDllName.Buffer;
CurDllNameLength = Node->BaseDllName.Length;

In case i is an offset, Is there any way I can do to change type of i to something correct (like struct members) or just add the variable Node in IDA? The Node pointer I wrote here seems to be optimized out.

I tried CONTAINING_RECORD but it seems not applicable here.

1 Answer 1


Right-click i and select either:

  • Create new struct type to create a new type deducted from function-scoped access to the variable
  • Convert to struct * to apply an existing type

You can inspect and manage structure types in Local Types tab (View/Open subviews/Local Types), including the types you already have (found in system APIs and debug symbols).

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.