0

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

struct LDR_DATA_TABLE_ENTRY {
    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;
LDR_DATA_TABLE_ENTRY *Node = CONTAINING_RECORD(i, LDR_DATA_TABLE_ENTRY, InMemoryOrderLinks);
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

0

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).

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