//PEB=process env block

#include <stdio.h>
#include <stdlib.h>
#include <windows.h>


typedef struct _UNICODE_STRING
{
    USHORT Length;
    USHORT MaximumLength;
    PWSTR Buffer;
} UNICODE_STRING, *PUNICODE_STRING;

typedef struct _LDR_MODULE
{
	LIST_ENTRY              InLoadOrderModuleList;
	LIST_ENTRY              InMemoryOrderModuleList;
	LIST_ENTRY              InInitializationOrderModuleList;
	PVOID                   BaseAddress;
	PVOID                   EntryPoint;
	ULONG                   SizeOfImage;
	UNICODE_STRING          FullDllName;
	UNICODE_STRING          BaseDllName;
	ULONG                   Flags;
	SHORT                   LoadCount;
	SHORT                   TlsIndex;
	LIST_ENTRY              HashTableEntry;
	ULONG                   TimeDateStamp;
} LDR_DATA_ENTRY , *PLDR_DATA_ENTRY;

typedef struct _PEB_LDR_DATA
{
    ULONG               Length;
    BOOLEAN             Initialized;
    PVOID               SsHandle;
    LIST_ENTRY          InLoadOrderModuleList; //celle qui nous interesse , listentry qui pointe sur des structs de type LDR_DATA_ENTRY.
    LIST_ENTRY          InMemoryOrderModuleList;
    LIST_ENTRY          InInitializationOrderModuleList;
} PEB_LDR_DATA, *PPEB_LDR_DATA;


typedef struct _PEB
{
    BOOLEAN                      InheritedAddressSpace;             /*  00 */
    BOOLEAN                      ReadImageFileExecOptions;          /*  01 */
    BOOLEAN                      BeingDebugged;                     /*  02 */
    BOOLEAN                      SpareBool;                         /*  03 */
    HANDLE                       Mutant;                            /*  04 */
    HMODULE                      ImageBaseAddress;                  /*  08 */
    PPEB_LDR_DATA                LdrData;                           /*  0c */
} PEB, *PPEB;


int main()
{
    PPEB structPEB; //pointeur sur une structure contenant infos sur PEB
    PPEB_LDR_DATA structLdrData;
    LIST_ENTRY structModuleLoad ;
    PLIST_ENTRY stockFlink , stockBlink ;
    PLDR_DATA_ENTRY structDataEntry;
    UNICODE_STRING dllName ;
    int i ;

    PVOID (*rtGetCurrentPeb)(); // pointeur de fonction , pour call RtGetCurrentPeb dans ntdll.

    printf("Liste des noms des dll load par le proc en utilisant le peb par 0vercl0k\n\n");

    rtGetCurrentPeb = (PVOID*)GetProcAddress(GetModuleHandle("ntdll.dll"), "RtlGetCurrentPeb");

    structPEB = (PPEB)(*rtGetCurrentPeb)(); //ptr sur le peb
    structLdrData = structPEB->LdrData; // ptr sur la struct ldr_data qui contient notre liste chained
    structModuleLoad = structLdrData->InLoadOrderModuleList; // notre liste chained

    stockFlink = structModuleLoad.Flink;
    stockBlink = structModuleLoad.Blink;

    while(stockFlink != stockBlink)
    {
        structDataEntry = (PLDR_DATA_ENTRY)stockFlink; // notre struct sur lequel pointe la liste chained
        dllName = structDataEntry->BaseDllName; //le nom de la dll enfin :)))
        wprintf(L"DllName : %s\n", dllName.Buffer);
        stockFlink = stockFlink->Flink;
    }
    return 0;
}