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!