geladene dll's finden

hab am we mal nen bisschen mit code-injection rumgespielt. Mein ziel war es festzustellen, welche module porgramm x lädt. hab dazu den prozess suspended created und folgende dll injectet:

Code:
#include <windows.h>
#include <stdio.h>

#define MODULE "kernel32.dll"
#define FUNCTION "LoadLibraryA"

char restore[5];

FILE* file;

void APIENTRY patch();
void APIENTRY unpatch();

HMODULE WINAPI hook(LPCSTR lpLibFileName)
{
	unpatch();
	fprintf(file,"%s\n",lpLibFileName);
	HMODULE ret = LoadLibraryA(lpLibFileName);
	patch();
	return ret;
}



void APIENTRY patch()
{
	unsigned hookedAddr = (unsigned) GetProcAddress(LoadLibrary(TEXT(MODULE)),FUNCTION);
	unsigned hookAddr = (unsigned) &hook;
	unsigned offset = hookAddr - hookedAddr - 5;
	unsigned char jmp = 0xE9;

	ReadProcessMemory(GetCurrentProcess(),(void*) hookedAddr,restore,5,NULL);
	WriteProcessMemory(GetCurrentProcess(),(void*) hookedAddr,&jmp,1,NULL);
	WriteProcessMemory(GetCurrentProcess(),(void*) (hookedAddr+1),&offset,4,NULL);
}

void APIENTRY unpatch()
{
	unsigned hookedAddr = (unsigned) GetProcAddress(GetModuleHandle(TEXT(MODULE)),FUNCTION);
	WriteProcessMemory(GetCurrentProcess(),(void*) hookedAddr,restore,5,NULL);
}

BOOL APIENTRY DllMain( HMODULE hModule,
                       DWORD  ul_reason_for_call,
                       LPVOID lpReserved
					 )
{
	switch(ul_reason_for_call)
	{
		case DLL_PROCESS_ATTACH:
			file = fopen("modules.txt","w");
			patch();
			break;
		case DLL_PROCESS_DETACH:
			fclose(file);
			break;
	}
    return TRUE;
}

Das ganze dann nochmal für LoadLibraryW. Der output war fast identisch.

Danach hab ich mir im Debugger mal angesehen, welche module wirklich geladen werden und festgestellt, dass mir mit der injection so einige entgangen sind. Das waren so ziemlich alles .NET - dll's, die ich da verpasst habe. Kann sein, dass noch nen paar aus sxs dabei waren. Wie werden diese Module geladen und wie kann ich das mit nem ähnlichen Programm überwachen?
 
Es gibt da noch LoadLibraryExW/LoadLibraryExA. Dabei ruft LoadLibraryA erstmal LoadLibraryExA auf und diese wiederum LoadLibraryExW (LoadLibraryW ->LoadLibraryExW). Sind also nur Wrapper, die auf LoadLibraryExW verweisen.Und es kann gut sein, dass einge "modernere" DLLs oder auch der PE Loader diese Extended Version nutzen.
Notfalls könnte man auch versuchen LdrLoadDLL zu hooken (ntdll). Sollte aber imho nicht nötig sein (achtung: den pe-Loader habe ich nicht debuggt, kann also nicht 100% was dazu sagen ;) ).
Falls der Hook auf LoadLibraryExW nicht hilft - etwas länger, aber informativ:
http://msdn.microsoft.com/en-us/magazine/cc301727.aspx
 
Mit der ToolHelp32 - Library kann man Windows auch einfach alle Module eines bestimmten Prozesses enumerieren lassen (wie ich es bei fbProcMon gemacht habe...)
 
Danke, die LoadLibraryExW macht ne vermutlich vollständige Liste. Werd jetzt mal versuchen noch nen hook für GetProcAddress() zu bauen. Ich hoffe, da gibt's nicht auch wieder mehrere Varianten von.

Eine Verständnisfrage zum Thema dll-loading bleibt mir allerdings noch. Meines Wissens nach existiert der dll-code ja nur einmal im physischen Speicher und wird in den virtuellen speicher der prozesse gemapped. Allerdings lässt sich damit nicht erklären, warum sich so ein hook wie oben, nur auf einzelne Prozesse auswirkt. Kann das hier jemand erklären?
 
Sobald Schreibzugriff auf die DLL erfolgt (und die Section nicht als Shared deklariert ist) erstellt der Speichermanager eine lokale Kopie. Da auf die meisten DLLs nicht schreibend zugegriffen wird, erspart diese Strategie im Normalfall viel Overhead.
Das Ganze nennt sich Copy-on-write Protection:
http://msdn.microsoft.com/en-us/library/aa366785(VS.85).aspx
 
Sowas in der Art hab ich mir schon gedacht. Danke für den Artikel, da kann ich mir den Mechanismus nochmal genau ansehen.
 
Zurück
Oben