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.