Video Tutorial NtQueryInformationProcess - How to loop through Peb Ldr Module List

Hexui Undetected CSGO Cheats Sinkicheat PUBG Cheat

Rake

Cesspool Admin
Administrator
Jan 21, 2014
12,349
78,998
2,412
Game Name
N/A
Anticheat
N/A
How long you been coding/hacking?
5 years
Coding Language
C++
What you need
Visual Studio
You may be familiar with ToolHelp32Snapshot for getting a list of loaded modules in a target process. There are 3 methods in total, ToolHelp32Snapshot, Peb LDR module linked list and EnumModules.

With this video you will learn how to use NtQueryInformationProcess to parse the PEB Ldr module linked list. You can use this method as an alternative to using ToolHelp32Snapshot

You can find the NtQueryInformationProcess function exported by ntdll.dll and call the function. This will give you a PROCESS_BASIC_INFORMATION structure which contains the PEB address. The PEB contains the Ldr, the Ldr contains the linked list full of modules. The modules are defined as LDR_DATA_TABLE_ENTRY and contain many useful variables such as dll name, address and size.

C++:
typedef NTSTATUS(__stdcall* tNtQueryInformationProcess)
(
    HANDLE ProcessHandle,
    PROCESSINFOCLASS ProcessInformationClass,
    PVOID ProcessInformation,
    ULONG ProcessInformationLength,
    PULONG ReturnLength
    );
C++:
typedef struct _PROCESS_BASIC_INFORMATION
{
    NTSTATUS ExitStatus;
    PPEB PebBaseAddress;
    ULONG_PTR AffinityMask;
    KPRIORITY BasePriority;
    HANDLE UniqueProcessId;
    HANDLE InheritedFromUniqueProcessId;
} PROCESS_BASIC_INFORMATION, * PPROCESS_BASIC_INFORMATION;

This NtQueryInformationProcess tutorial will teach you how to use undocumented windows structures, of which there are many. Using NtQueryInformationProcess and PROCESS_BASIC_INFORMATION is an alternative to using toolhelp32snapshot.


Sample of the code:
C++:
PEB* GetPEBInternal()
{
#ifdef _WIN64
    PEB* peb = (PEB*)__readgsqword(0x60);

#else
    PEB* peb = (PEB*)__readfsdword(0x30);
#endif

    return peb;
}

LDR_DATA_TABLE_ENTRY* GetLDREntryInternal(const wchar_t* modName)
{
    LDR_DATA_TABLE_ENTRY* modEntry = nullptr;

    PEB* peb = GetPEBInternal();

    LIST_ENTRY head = peb->Ldr->InMemoryOrderModuleList;

    LIST_ENTRY curr = head;

    for (auto curr = head; curr.Flink != &peb->Ldr->InMemoryOrderModuleList; curr = *curr.Flink)
    {
        LDR_DATA_TABLE_ENTRY* mod = (LDR_DATA_TABLE_ENTRY*)CONTAINING_RECORD(curr.Flink, LDR_DATA_TABLE_ENTRY, InMemoryOrderLinks);

        if (mod->BaseDllName.Buffer)
        {
            if (_wcsicmp(modName, mod->BaseDllName.Buffer) == 0)
            {
                modEntry = mod;
                break;
            }
        }
    }
    return modEntry;
}

char* GetModuleBaseAddressInternalPEB(const wchar_t* modName)
{
    LDR_DATA_TABLE_ENTRY* modEntry = GetLDREntryInternal(modName);

    return (char*)modEntry->DllBase;
}
Resources
 

Attachments

Last edited:
Attention! Before you post:

Read the How to Ask Questions Guide
99% of questions are answered in the Beginner's Guide, do it before asking a question.

No Hack Requests. Post in the correct section.  Search the forum first. Read the rules.

How to make a good post:

  • Fill out the form correctly
  • Tell us the game name & coding language
  • Post everything we need to know to help you
  • Ask specific questions, be descriptive
  • Post errors, line numbers & screenshots
  • Post code snippets using code tags
  • If it's a large project, zip it up and attach it

If you do not comply, your post may be deleted.  We want to help, please make a good post and we will do our best to help you.

Community Mods