C-Bibliothek zum Lesen der EXE-Version von Linux?

8

Gibt es eine Bibliothek, die ich in Linux verwenden kann, die die Eigenschaften einer Windows EXE-Datei zurückgibt, die in der Registerkarte Version von Explorer aufgeführt sind? Dies sind Felder wie Produktname, Produktversion, Beschreibung usw.

Für mein Projekt kann die EXE-Datei nur aus dem Speicher und nicht aus einer Datei gelesen werden. Ich möchte vermeiden, die EXE-Datei auf die Festplatte zu schreiben.

    
craig65535 12.09.2012, 21:53
quelle

6 Antworten

22

Die Version der Datei befindet sich in der VS_FIXEDFILEINFO struct, aber Sie müssen sie in den ausführbaren Daten finden. Es gibt zwei Möglichkeiten, das zu tun, was Sie wollen:

  1. Suchen Sie nach der VERSION_INFO-Signatur in der Datei und lesen Sie VS_FIXEDFILEINFO struct direkt.
  2. Suchen Sie den Abschnitt .rsrc , parsen Sie den Ressourcenbaum, suchen Sie die Ressource RT_VERSION , parsen Sie sie und extrahieren Sie die VS_FIXEDFILEINFO -Daten.

Der erste ist leichter, aber dafür anfällig, die Signatur zufällig am falschen Ort zu finden. Darüber hinaus sind die anderen Daten (Produktname, Beschreibung usw.) nicht in dieser Struktur enthalten, daher werde ich versuchen zu erklären, wie man die Daten auf die harte Art erhält.

Das PE-Format ist ein bisschen verschachtelt, also packe ich den Code Stück für Stück, mit Kommentaren und mit minimaler Fehlerprüfung. Ich schreibe eine einfache Funktion, die die Daten auf die Standardausgabe ablegt. Schreiben Sie es als eine ordnungsgemäße Funktion ist eine Übung für den Leser:)

Beachten Sie, dass ich Offsets im Puffer verwenden werde, anstatt die Strukturen direkt zuzuordnen, um Portabilitätsprobleme zu vermeiden, die mit der Ausrichtung oder Auffüllung der Strukturfelder zusammenhängen. Wie auch immer, ich habe den Typ der verwendeten Strukturen kommentiert (siehe Include-Datei winnt.h für Details).

Zuerst ein paar nützliche Erklärungen, sollten sie selbsterklärend sein:

%Vor%

Dann eine Funktion, die die Versionsressource im ausführbaren Bild findet (keine Größenprüfung).

%Vor%

Die erste Struktur in der EXE ist der MZ-Header (für die Kompatibilität mit MS-DOS).

%Vor%

Das einzige interessante Feld im MZ-Header ist der Offset des PE-Headers. Der PE-Header ist die echte Sache.

%Vor%

Eigentlich ist der PE-Header ziemlich langweilig, wir wollen den COFF-Header, der alle symbolischen Daten enthält.

%Vor%

Wir brauchen nur die folgenden Felder von diesem.

%Vor%

Der optionale Header ist in einer EXE tatsächlich obligatorisch und befindet sich unmittelbar nach dem COFF. Die Magie unterscheidet sich für 32 und 64 Bit Windows. Ich nehme von hier an 32 Bits an.

%Vor%

Hier kommt der interessante Teil: wir wollen den Ressourcenbereich finden. Es besteht aus zwei Teilen: 1. den Abschnittsdaten, 2. den Abschnittsmetadaten.

Der Datenspeicherort befindet sich in einer Tabelle am Ende des optionalen Headers, und jeder Abschnitt hat einen bekannten Index in dieser Tabelle. Der Ressourcenabschnitt befindet sich in Index 2, daher erhalten wir die virtuelle Adresse (VA) des Ressourcenabschnitts mit:

%Vor%

Um die Abschnittsmetadaten zu erhalten, müssen wir die Abschnittstabelle durchlaufen, um nach einem Abschnitt namens .rsrc zu suchen.

%Vor%

Die Sektion struct hat zwei relevante Elemente: die VA der Sektion und den Offset der Sektion in die Datei (auch die Größe der Sektion, aber ich überprüfe das nicht!):

%Vor%

Jetzt ist der Offset in der Datei, der der vaRes VA entspricht, die wir vorher bekommen haben, einfach.

%Vor%

Dies ist ein Zeiger auf die Ressourcendaten. Alle einzelnen Ressourcen sind in Form eines Baumes mit 3 Ebenen aufgebaut: 1) Art der Ressource, 2) Bezeichner der Ressource, 3) Sprache der Ressource. Für die Version erhalten wir die allererste vom richtigen Typ.

Zuerst haben wir ein Ressourcenverzeichnis (für den Typ der Ressource), wir erhalten die Anzahl der Einträge im Verzeichnis, sowohl named als auch unbenannt und iterieren:

%Vor%

Für jeden Ressourceneintrag erhalten wir den Typ der Ressource und verwerfen ihn, wenn es nicht die Konstante RT_VERSION (16) ist.

%Vor%

Wenn es sich um eine RT_VERSION handelt, gelangen wir zum nächsten Ressourcenverzeichnis in der Baumstruktur:

%Vor%

Und weiter zur nächsten Verzeichnisebene, die ID interessiert uns nicht. von diesem:

%Vor%

Die dritte Ebene hat die Sprache der Ressource. Es ist uns auch egal, also schnappen Sie sich den ersten:

%Vor%

Und wir kommen zur echten Ressource, nun, eigentlich zu einer Struktur, die den Ort und die Größe der realen Ressource enthält, aber die Größe interessiert uns nicht.

%Vor%

Das ist die VA der Version resouce, die leicht in einen Zeiger umgewandelt wird.

%Vor%

Und fertig! Wenn nicht gefunden, gebe NULL zurück.

%Vor%

Nachdem die Versionsressource gefunden wurde, müssen wir sie analysieren. Es ist eigentlich ein Baum (was sonst) von Paaren "Name" / "Wert". Einige Werte sind bekannt und genau das suchst du, teste einfach einen Test und du wirst herausfinden, welche.

HINWEIS : Alle Zeichenfolgen werden in UNICODE (UTF-16) gespeichert, aber mein Beispielcode führt die dumme Umwandlung in ASCII durch. Auch keine Überprüfung auf Überlauf.

Die Funktion nimmt den Zeiger auf die Versionsressource und den Offset in diesen Speicher (0 für Starter) und gibt die Anzahl der analysierten Bytes zurück.

%Vor%

Zuerst muss der Offset ein Vielfaches von 4 sein.

%Vor%

Dann erhalten wir die Eigenschaften des Versionsbaumknotens.

%Vor%

Der Name des Knotens ist eine mit Null abgeschlossene Unicode-Zeichenfolge.

%Vor%

Mehr Padding, falls nötig:

%Vor%

Wenn type nicht 0 ist, handelt es sich um eine String-Version.

%Vor%

Sonst, wenn der Name VS_VERSION_INFO ist, dann ist es ein VS_FIXEDFILEINFO struct. Sonst sind es Binärdaten.

%Vor%

Ich drucke nur die Version der Datei und des Produkts, aber Sie können die anderen Felder dieser Struktur leicht finden. Vorsicht vor der gemischten Endian Reihenfolge.

%Vor%

Führen Sie nun den rekursiven Aufruf durch, um den gesamten Baum zu drucken.

%Vor%

Und etwas mehr Polsterung vor der Rückkehr.

%Vor%

Schließlich, als Bonus, eine Funktion main .

%Vor%

Ich habe es mit ein paar zufälligen EXEs getestet und es scheint gut zu funktionieren.

    
rodrigo 18.09.2012, 23:51
quelle
2

Ich weiß, dass pev ein Tool unter Ubuntu ist, mit dem Sie diese Informationen zusammen mit vielen anderen PE-Header-Informationen sehen können. Ich weiß auch, dass es in C geschrieben ist. Vielleicht solltest du es dir ansehen . Ein bisschen von seinem Geschichte Abschnitt in den Dokumenten:

  

pev wurde 2010 aus einer einfachen Notwendigkeit geboren: ein Programm, um die   Version (File Version) einer PE32-Datei, die unter Linux ausgeführt werden kann.   Diese Versionsnummer wird im Abschnitt Resources (.rsrc) gespeichert, jedoch in der   Zeit haben wir beschlossen, einfach nach der Zeichenfolge im ganzen zu suchen   binär, ohne Optimierung.

     

Später haben wir uns entschieden, die PE32-Datei zu analysieren, bis wir .rsrc erreichen   Abschnitt und erhalten Sie das Feld Dateiversion. Um das zu tun, haben wir   realisierten wir müssen die gesamte Datei analysieren und wir dachten, wenn wir könnten   Drucke auch alle Felder und Werte aus ...

     

Bis Version 0.40 war PEV ein einzigartiges Programm zum Parsen der PE-Header   und Abschnitte (jetzt readpe ist dafür verantwortlich). In der Version 0.50 haben wir   konzentrierte sich auf Malware-Analyse und aufgeteilt in verschiedene Programme   jenseits einer Bibliothek, genannt libpe. Derzeit verwenden alle Pepp-Programme libpe.

    
djhaskin987 27.01.2016 19:17
quelle
1

Installieren Sie winelib Ссылка Dies ist der Port von MS Windows API für andere Systeme, einschließlich Linux.

Dann benutze MS Windows API. Wie GetFileVersionInfo Ссылка
Oder andere Funktionen.

Ich habe es nie getan, aber ich würde mit diesen Ergebnissen beginnen.

Was EXE-Datei in Speicherbeschränkung betrifft, können Sie es auf die RAM-Disk kopieren?

    
PiotrNycz 16.09.2012 23:24
quelle
1

Hier ist ein Patch für Code zur Unterstützung von PE32 +. Getestet auf einigen Dateien und scheint zu funktionieren.

%Vor%     
windead 17.07.2013 11:25
quelle
0

Wenn du es aus dem Gedächtnis lesen musst, denke ich, dass du etwas selbst implementieren musst. Ein guter Anfang ist das Wrestool:

%Vor%

Es ist auf Ubuntu auf icoutils verfügbar. Die Versionsinformationen bestehen nur aus einer Reihe von Zeichenfolgen in einer Ressourcendatei, die in die ausführbare Datei eingebettet ist. Ich denke, du kannst dir den Quellcode von Wrestool ansehen und nachsehen, wie sie den Start des Resource Blocks finden. Sobald Sie VERSION_INFO-Ressourcen gefunden haben, können Sie herausfinden, wie Sie diese in druckbare Informationen übersetzen (mit einem Hex-Editor, der lesbar ist).

icoutils ist GPL ... also können Sie nicht einfach einen Teil davon nehmen, nicht ohne Ihr Programm zu verunreinigen. Der Quellcode ist jedoch kostenlos. Sie können also überprüfen, was sie getan haben, und eine benutzerdefinierte Lösung schreiben.

Das PE-Dateiformat ist auch im Internet verfügbar. Sie können hier beginnen: Ссылка

    
nmenezes 18.09.2012 12:21
quelle
0

Hier ist ein Beispiel in der Tcl-Sprache, um eine .exe-Datei zu analysieren, um die Versionsinformationen abzurufen.

Lesen von Versionsinformationen von ausführbaren Win32-Dateien .

Diese Webseite beschreibt das .exe Header-Format . Ich bin mir nicht sicher über das Datum dieser Informationen oder darüber, ob es sich um neuere Windows-Versionen handelt oder nicht. Es ist jedoch ein Ausgangspunkt.

    
Richard Chambers 18.09.2012 17:40
quelle