Forum > Coding >

Parsing through the PEB LDR data list entries to find and output information about modules

Posts: 224

Threads: 43

Joined: May, 2022

Reputation: -5

Posted

This code gets the process environment block (PEB) and goes through its ldr (loader) data list which contains entries for each loaded module in memory then outputs information about said module, including itself.

 

#include <iostream>
#include <Windows.h>
#include <winternl.h>
#include <thread>

namespace peb_structs
{

	struct peb_ldr_data
	{
		const std::uint32_t pad_00[ 3 ];
		LIST_ENTRY* module_list;
	};

	struct ldr_data_list_entry32
	{
		LIST_ENTRY links;

		std::uint8_t pad_00[ 16 ];

		std::uintptr_t module_base;
		std::uintptr_t module_entry_point;
		std::size_t module_image_sz;

		UNICODE_STRING module_path;
		UNICODE_STRING module_name;

	};
}


void main_thread( HMODULE dll_module )
{
	// getting the thread environment block address from the file segment
	const auto teb_address = __readfsdword( reinterpret_cast< std::uint32_t >( &static_cast< NT_TIB* >( nullptr )->Self ) );

	// making our thread environment block pointer.
	const auto teb = reinterpret_cast< TEB* >( teb_address );

	// populating our peb ldr data structure by casting the teb ldr and caching it in peb_ldr
	const auto peb_ldr = reinterpret_cast< peb_structs::peb_ldr_data* >( teb->ProcessEnvironmentBlock->Ldr );

	// the LIST_ENTRY pointer in the peb ldr data structure has the Blink and Flink LIST_ENTRY pointers, the Blink pointer points to the last module and the
	// Flink pointer points to the first module.
	// const auto last_module = reinterpret_cast< peb_structs::ldr_data_list_entry32* >( peb_ldr->module_list->Blink );

	//we have our linked list and now can access the next module with Flink and the previous module with Blink
	auto current_module = reinterpret_cast< peb_structs::ldr_data_list_entry32* >( peb_ldr->module_list->Flink );

	// checking if the current module base is valid so that we arent looping eternally...
	while( current_module->module_base )
	{
		std::printf( "module name: %ls\nmodule path: %ls\nmodule entry point: %x\nmodule base: %x\nmodule image size: %u\n\n", current_module->module_name.Buffer, current_module->module_path.Buffer, current_module->module_entry_point, current_module->module_base, current_module->module_image_sz );

		// updating current_module to the next module in the list
		current_module = reinterpret_cast< peb_structs::ldr_data_list_entry32* >( current_module->links.Flink );
	}

	FreeLibrary( dll_module );

}


bool __stdcall DllMain( HMODULE dll_module, const std::uint32_t reason_for_call, void* )
{
	if( reason_for_call == DLL_PROCESS_ATTACH )
	{
		std::thread{ main_thread, dll_module }.detach( );
	}
	return true;
}

I left comments explaining each line and what it does, if you have questions about what certain things mean search them up

after doing so if you still do not understand feel free to leave a question in the replies.

 

https://media.discordapp.net/attachments/988849296336126053/1005567404774011041/unknown.png

 

  • 0

https://media.discordapp.net/attachments/1044764388546068510/1051935933836050482/Signature_4.png

pepsi

PePsIDeveloper

vip

Posts: 259

Threads: 4

Joined: Apr, 2021

Reputation: 13

Replied

vouch expression ontop

  • 0

https://cdn.discordapp.com/attachments/661621789591470090/1013919752294498314/Untitled_1366_768_px_1546_202_px_2.gif

Users viewing this thread:

( Members: 0, Guests: 1, Total: 1 )