Die Sache mit GetModuleFileNameEx

Der folgende Artikel bezieht sich auf die Betriebsysteme Windows2000/XP/Vista/Windows7.

In der MSDN Dokumentation ist folgendes zu lesen:

Zitat:
To retrieve the name of the main executable module for a remote process, use the GetProcessImageFileName or QueryFullProcessImageName function. This is more efficient and more reliable than calling the GetModuleFileNameEx function with a NULL module handle.


Microsoft rät hier also von der Nutzung von GetModuleFileNameEx zur Ermittlung des processerzeugenden Moduls ab und verweist auf zwei andere APIs - eine davon gibt es erst ab Windows Vista, die andere wurde erst unter XP eingeführt. Aber warum dieser Verweis?
Ein Blick in den PEB (Process Environment Block) verschaft darüber etwas Klarheit. Aber was ist überhaupt der PEB? Der PEB ist eine Struktur mit Daten über den aktuellen Prozess, die sich im
Usermode befindet - das heißt im privaten virtuellen Speicherbereich des jeweiligen Prozesses. Startet man einen Prozess kann dieser natürlich jederzeit alle Daten lesen und auch ändern, die sich in seinem eigenen privaten Speicherbereich befinden - das ist wichtig und das sollten wir uns merken.
Der PEB enthält eine Pointer auf eine Struktur mit dem Namen RTL_USER_PROCESS_PARAMETERS. Schauen wir uns die Struktur RTL_USER_PROCESS_PARAMETERS also einmal an.
Auch die RTL_USER_PROCESS_PARAMETERS Struktur befindet sich im Usermode. Diese Struktur wiederum liefert einen Pointer auf den Unicodestring
ImagePathName.
ImagePathName ist der Pfad zum Prozesserzeugenden Modul, und genau von dort liest GetModuleFileNameEx den Pfad auch aus - auch dieser String befindet sich im privaten Speicherbereich (Usermode) des jeweiligen Prozesses.

Was kann nun passieren???
Da jeder Prozess natürlich das Recht hat, seinen privaten Speicherbereich lesend und schreibend zu nutzen, könnte zum Beispiel ein Prozess mit dem Dateinamen
C:\Eigene Dateien\svchost.exe seinen "angezeigten" Pfad durch das Umschreiben dieses Unicodestrings so manipulieren, dass GetModuleFileNameEx stattdessen C:\Windows\System32\svchost.exe anzeigt (siehe hier ). Malware kann dem User also vorspielen, sie befände sich an einem ganz anderen Ort als in Wirklichkeit - aber nicht nur das!...
Um sich die Dateiinfos (Hersteller, Dateiversion, Dateibeschreibung...) anzeigen zu lassen, gibt es die API GetFileVersionInfo. Diese API benötigt als ersten Parameter den Pfad zur Datei. Da der Dateipfad in unserem "
svchost-" Beispiel aber nicht stimmt, werden auch hier die falschen Infos zurückgeliefert - nämlich nicht die der Malware, sondern die der Windows-System-Datei mit dem gleichen Namen!

Was machen nun aber GetProcessImageFileName und QueryFullProcessImageName da anders? Ganz einfach: Diese APIs holen sich den Pfad nicht aus dem Usermode, sondern aus dem viel sichereren Kernelbereich, wobei QueryFullProcessImageName auch noch wesentlich weniger Rechte benötigt und deshalb auch mit einem "Protected Process" funktioniert.

In Sicherheitsprogrammen sollte ab XP eigentlich zum Ermitteln des Prozesspfades auf GetModuleFileNameEx verzichtet werden, doch kaum ein Programm nutzt hier bislang die API GetProcessImageFileName oder weicht ab Vista auf QueryFullProcessImageName aus......



________________________________________________________________________

Vielen Dank an Frank Abbing für seine Mithilfe an den Test und besten Dank an Horst Horn, der mit mir das Programm Path-Scout entwickelt hat!

Impressum