Statische BIOS / UEFI-Analyse oder Abrufen eines Abhängigkeitsdiagramms

„Ich habe gestern das Schmieden beendet,
Ich habe zwei Pläne ausgetrickst ... "
... VS Vysotsky Lied ...

Vor fast 3 Jahren (Anfang 2016) erschien der Wunsch eines Benutzers zum Thema des UEFITool-Projekts auf GitHub: ein „Abhängigkeitsdiagramm“ für ausführbare Module zu erstellen, die in BIOS / UEFI enthalten sind.

Sogar eine kleine Diskussion folgte, wodurch klar wurde, dass diese Aufgabe keineswegs trivial ist, die verfügbare Funktionalität für ihre Lösung nicht ausreicht, die Aussichten in diesem Moment neblig sind ...

Und diese Frage blieb in der Schwebe, mit der Aussicht auf Verwirklichung in unbestimmter Zukunft (aber der Wunsch blieb wahrscheinlich bestehen, und die Hoffnung stirbt, wie Sie wissen, zuletzt!).

Es gibt einen Vorschlag: Finden Sie endlich eine Lösung für dieses Problem!

Definieren Sie die Begriffe


Es wird weiterhin angenommen, dass es sich um Intel 64- und IA-32-Architektur handelt.

Um eindeutig zu bestimmen, was wir bauen wollten, müssen wir uns eingehender mit der Funktionsweise der einzelnen Phasen des BIOS / UEFI-Vorgangs befassen.

Wenn Sie sich die Dateitypen in den FFS- Firmware-Volumes genau ansehen, stellt sich heraus, dass die meisten verfügbaren Dateien einen Abschnitt mit ausführbaren Modulen enthalten.

Selbst wenn wir die neue Firmware von ASUS oder ASRock betrachten, in der Sie mühelos bis zu eineinhalb hundert Dateien vom Typ EFI_FV_FILETYPE_FREEFORM finden können, die Bilder verschiedener Formate enthalten, gibt es auch in diesen Firmwares mehr ausführbare Dateien als Dateien anderer Typen.

+--------------------------------------------------------------------------+ | File Types Information | +--------------------------------------------------------------------------+ | EFI_FV_FILETYPE_RAW = 6 | | EFI_FV_FILETYPE_FREEFORM = 83 | | EFI_FV_FILETYPE_SECURITY_CORE = 1 | | EFI_FV_FILETYPE_PEI_CORE = 1 | | EFI_FV_FILETYPE_DXE_CORE = 1 | | EFI_FV_FILETYPE_PEIM = 57 | | EFI_FV_FILETYPE_DRIVER = 196 | | EFI_FV_FILETYPE_APPLICATION = 1 | | EFI_FV_FILETYPE_SMM = 60 | | EFI_FV_FILETYPE_SMM_CORE = 1 | | EFI_FV_FILETYPE_PAD = 4 | +--------------------------------------------------------------------------+ | Total Files : = 411 | +--------------------------------------------------------------------------+ 
Ein Beispiel für die Zusammensetzung einer gewöhnlichen (gewöhnlichen) Firmware.

Obwohl Dateien mit ausführbaren Modulen in dieser Tabelle nicht markiert sind, sind sie (per Definition) alle in dieser Liste enthalten, mit Ausnahme von Dateien mit den Suffixen RAW, FREEFORM und PAD.

Dateien mit dem Suffix "CORE" (SECURITY_CORE, PEI_CORE und DXE_CORE) sind die entsprechenden "Kernel" (Kopfmodule der entsprechenden Phase), die von anderen Phasen (oder nach dem Start) gesteuert werden. SMM_CORE ist eine Unterphase der DXE-Phase und wird während dieser aufgerufen Erfüllung. Die Anwendung kann nur auf Anfrage des Benutzers durchgeführt werden, es besteht keine spezifische Bindung an die Phasen.

Die häufigsten Dateitypen wurden nicht aufgeführt: PEIM (PEI-Phasenmodule), DRIVER (DXE-Phasenmodule) und SMM (DXE-Subphasenmodule). Die CORE-Module der PEI- und DXE-Phasen enthalten einen Dispatcher, der die Reihenfolge der Lade- / Startmodule der entsprechenden Phase steuert.

Im obigen Beispiel gibt es keine kombinierten Optionen, an die wir uns nicht erinnern werden: Obwohl sie in echter Firmware enthalten sind, ist dies ziemlich selten. Wer detailliertere und detailliertere Informationen erhalten möchte, wird gebeten , auf die CodeRush- Artikel 1 , 2 , 3 zu verweisen. Und zitieren Sie auch seinen Rat: „Für Fans der Originaldokumentation ist die UEFI PI-Spezifikation immer verfügbar, alles wird viel detaillierter beschrieben.“

Jedes ausführbare Firmware-Modul ist ein Modul im PE + -Format (Portable Executable) oder dessen Ableitung (Terse Executable: TE-Format). Das ausführbare Modul im PE + -Format besteht aus einer Reihe von "leicht" gepackten strukturierten Daten, die die Informationen enthalten, die der Loader benötigt, um dieses Modul dem Speicher zuzuordnen.

Das PE + -Format (Struktur) selbst hat keinen Interaktionsmechanismus zwischen einzelnen PE + -Modulen. Jedes ausführbare Modul nach dem Laden und Starten der Ausführung ist ein autonomer unabhängiger Prozess (nun, es sollte so sein!) , D.h. Das Modul sollte nichts darüber „annehmen“, was außerhalb des Moduls getan wird.

Die Organisation der Interaktion zwischen separaten ausführbaren Modulen einer UEFI-Phase wird mittels des CORE-Moduls der entsprechenden Phase organisiert. Einzelne ausführbare Module können Protokolle definieren (installieren), von anderen Modulen deklarierte Protokolle anfordern (lokalisieren) und verwenden, Ereignisse festlegen / deklarieren und Ereignishandler deklarieren (benachrichtigen).

Daher sind wir für jedes ausführbare Firmware-Modul an folgenden Artefakten interessiert:

  1. Liste der Protokolle, die dieses Modul definiert. (Jedes Protokoll ist durch eine eindeutige Nummer gekennzeichnet).
  2. Liste der Protokolle, die dieses Modul verwendet (versucht zu verwenden).
  3. Liste der Ereignisse, die dieses Modul ankündigt. (Die Veranstaltung hat eine eindeutige Nummer - Anleitung).
  4. Eine Liste der in diesem Modul vorhandenen (implementierten und installierbaren / initialisierbaren) Ereignishandler.
Ein statisches Abhängigkeitsdiagramm für eine bestimmte BIOS / UEFI-Phase gilt als definiert, wenn für jedes ausführbare Phasenmodul alle oben in den Abschnitten 1 bis 4 aufgeführten Artefakte bekannt sind. (Mit anderen Worten, wenn wir alle Informationen definiert haben, die die Abhängigkeiten zwischen den Modulen beschreiben).
Wir werden nur die Option der statischen Analyse betrachten. Dies bedeutet, dass einige Elemente des Codes, die die Elemente 1 bis 4 implementieren, nicht erreichbar sein können (Fragmente des "toten" Codes sind) oder nur mit bestimmten Optionen für Eingabedaten / Parameter erreichbar sind.

Alles, was wir bisher berücksichtigt haben, basiert nur auf der BIOS / UEFI- Spezifikation. Und um die „Beziehungen“ der vorhandenen ausführbaren Module der betreffenden Firmware zu verstehen, müssen wir uns eingehender mit ihrer Struktur befassen, was bedeutet, dass wir sie zumindest teilweise umkehren sollten (Wiederherstellung der ursprünglichen Algorithmen).

Wie oben bereits erwähnt, ist das ausführbare Modul im PE + -Format nur eine Reihe von Strukturen für den Loader, die im Speicher ein Objekt erstellen, an das die Steuerung übertragen wird, und dieses Objekt besteht naturgemäß aus Prozessoranweisungen sowie Daten für diese Anweisungen.
Wir werden sagen, dass eine vollständige Demontage des ausführbaren Moduls vorgenommen wurde, wenn es möglich war, das Problem der Trennung der in diesem Modul dargestellten Befehle und Daten zu lösen.
Gleichzeitig werden wir keine Anforderungen an die Struktur und die Datentypen stellen. Es reicht aus, wenn wir für jedes Byte, das zum Image des vom Loader empfangenen ausführbaren Moduls gehört, klar sagen können, zu welcher der beiden Kategorien es gehört: Befehlsbyte oder Datenbyte.

Die Aufgabe, das ausführbare Modul selbst vollständig zu zerlegen, ist im Allgemeinen nicht trivial, außerdem ist es im allgemeinen Fall algorithmisch nicht lösbar. Wir werden nicht auf die Details dieser Ausgabe eingehen, auch die Speere brechen, wir betrachten diese Aussage als Axiom.

Angenommen,:

  1. Wir haben bereits das Problem der vollständigen Demontage für ein bestimmtes BIOS / UEFI-Ausführungsmodul gelöst, d. H. Es ist uns gelungen, Befehle und Daten zu trennen.
  2. Es gibt den Quellcode für das Modul in der Sprache „C“ (in der aktuellen BIOS / UEFI-Firmware werden die Module meist nur in der Sprache „C“ entwickelt).

Selbst in diesem Fall erfordert der einfache Vergleich der erzielten Ergebnisse (Assembler-Text ist nur eine Textdarstellung von Prozessoranweisungen) mit dem Quellcode in der Sprache „C“ fast immer gute Erfahrung / Qualifikation, mit Ausnahme absolut entarteter Fälle.

Eine vollständige Untersuchung von Beispielen, die Schwierigkeiten beim Identifizieren oder Vergleichen von Demontageergebnissen mit Quellcode zeigen, ist nicht Teil unserer aktuellen Pläne.
Betrachten wir nur ein Beispiel, wenn wir in der Assembler-Liste auf den Befehl "Indirekter Aufruf" stoßen - einen impliziten Prozeduraufruf.

Dies ist ein Beispiel für einen Prozeduraufruf, auf den in einer Tabelle verwiesen wird. Eine Tabelle mit Links zu verschiedenen Prozeduren ist ein typischer Fall für die Implementierung der Darstellung von Schnittstellen eines beliebigen Protokolls.

Eine solche Tabelle muss nicht nur aus Verweisen auf Prozeduren bestehen, niemand verbietet das Speichern beliebiger Daten in dieser Struktur (und dies ist ein Beispiel für eine typische C-Struktur).

Hier ist eine Form eines solchen Aufrufs (anstelle des ecx-Registers sind fast alle Varianten von 32-Bit-Prozessorregistern möglich):
FF 51 18 call dword ptr [ecx + 18h]
Nachdem bei der Analyse ein ähnlicher Befehl erhalten wurde, ist es möglich herauszufinden, welche Art von Prozedur aufgerufen wird. Eine Liste ihrer Parameter, der Typ und der Wert des zurückgegebenen Ergebnisses ist nur möglich, wenn wir den Objekttyp (Protokoll) kennen, dessen Schnittstelle von diesem Befehl aufgerufen wird.

Wenn wir wissen, dass im vorherigen Beispiel das Register „ecx“ einen Zeiger enthält (die Adresse am Anfang der Tabelle EFI_PEI_SERVICES), können wir diesen Befehl auf folgende verständlichere und „angenehmere“ Weise empfangen (präsentieren):
FF 51 18 call [exx + EFI_PEI_SERVICES.InstallPpi]
Das Abrufen von Informationen über den Inhalt des Registers, das am Befehl "Indirekter Aufruf" teilnimmt, geht meist über die Fähigkeiten eines "typischen" Disassemblers hinaus, dessen Aufgabe es ist, den Binärcode des Prozessors einfach zu analysieren und in eine für Menschen lesbare Form umzuwandeln - eine Textdarstellung des entsprechenden Prozessorbefehls.

Um dieses Problem zu lösen, müssen häufig zusätzliche (Meta-) Informationen verwendet werden, die im ausführbaren Binärmodul nicht verfügbar sind (verloren durch Kompilierung und Verknüpfung - sie werden bei Transformationen von einer Darstellung des Algorithmus zu einer anderen verwendet, aber der Prozessor muss die empfangenen Befehle nicht mehr ausführen).

Wenn uns diese Metadaten noch aus zusätzlichen Quellen zur Verfügung stehen, erhalten wir durch Verwendung dieser Metadaten und Durchführung zusätzlicher Analysen eine verständlichere (und genauere) Darstellung des Befehls „Indirekter Aufruf“ .

Tatsächlich erinnert diese erweiterte Analyse bereits mehr an den "Dekompilierungs" -Prozess, obwohl das Ergebnis nicht wie der Quellcode des Moduls in der "C" -Sprache aussieht. In Zukunft werden wir diesen Prozess jedoch als Dekompilierung von Befehlen bezeichnen, die "Indirekter Aufruf" oder " Indirekter Aufruf " sind teilweise "Dekompilierung .

Wir sind also bereit, die ausreichenden Bedingungen für die Erstellung des Diagramms der gegenseitigen Abhängigkeit der ausführbaren Firmware-Module für die gegebene BIOS / UEFI-Phase zu bestimmen:
Um ein statisches Abhängigkeitsdiagramm (eine der Phasen - PEI oder DXE) zu erhalten, reicht es aus , alle ausführbaren Module der entsprechenden Phase vollständig zu zerlegen (mindestens alle Befehle zu trennen) und die in den zerlegten Modulen vorhandenen Befehle "Indirekter Aufruf" zu dekompilieren.
Es gibt sofort viele Fragen darüber, wie unser Wissen über „Indirect Call“ -Teams mit Interaktionen zwischen Modulen verbunden ist.
Wie oben erwähnt, wird der gesamte Interaktionsverwaltungsdienst vom Modul "CORE" der entsprechenden Phase bereitgestellt, und die Dienste in den Phasen werden als "grundlegende" Diensttabellen entworfen.

Da die Interaktionsmodelle zwischen den Modulen in der PEI- und der DXE-Phase zwar ideologisch (strukturell) ähnlich, aber technisch immer noch unterschiedlich sind, wird vorgeschlagen, von einigen formalen Überlegungen zu einer spezifischen direkten Konstruktion eines statischen Abhängigkeitsgraphen für die PEI-Phase überzugehen.

Wir werden sogar in der Lage sein, die notwendigen und ausreichenden Bedingungen für die Möglichkeit der Erstellung eines statischen Abhängigkeitsgraphen für die PEI-Phase zu bestimmen und zu formulieren.

Erstellen eines statischen Abhängigkeitsdiagramms für die PEI-Phase


Beschreibungen der Lösung des Problems der vollständigen Demontage ausführbarer Module der PEI-Phase und der Dekompilierung der in diesen Modulen enthaltenen Indirect Call- Befehle gehen über den Rahmen unserer Erzählung hinaus und werden darin nicht gegeben. Die Darstellung dieses Materials in Umfang kann die Größe dieses Opus überschreiten.

Es ist möglich, dass dies im Laufe der Zeit als separates Material geschieht, aber vorerst - Know-how.

Wir stellen nur fest, dass die Verwendung von Metadaten sowie das Vorhandensein einer bestimmten Struktur zum Erstellen von Binärcode es in der Praxis ermöglicht, ausführbare BIOS / UEFI-Module vollständig zu zerlegen . Ein formaler Beweis dieser Tatsache wird weder jetzt noch in Zukunft angenommen. Zumindest bei der Analyse / Verarbeitung von mehr als hundert (100) BIOS / UEFI verschiedener Hersteller gab es keine Beispiele, bei denen eine vollständige Demontage nicht möglich war.

Weiter nur spezifische Ergebnisse (mit Erklärungen: was, wie und wie viel ...).

Die Struktur EFI_PEI_SERVICES ist die Grundstruktur der PEI-Phase, die als Parameter an den Einstiegspunkt jedes PEI-Moduls übergeben wird und Links zu den Basisdiensten enthält, die für die Funktion der PEI-Module erforderlich sind.

Wir werden uns nur für die Felder interessieren, die sich ganz am Anfang der Struktur befinden:



Ein Fragment einer realen Struktur vom Typ EFI_PEI_SERVICES im IDA Pro-Disassembler.

Und so erscheint es im Quellcode in der Sprache „C“ (denken Sie daran, dies ist nur ein Fragment der Struktur):

 struct EFI_PEI_SERVICES { EFI_TABLE_HEADER Hdr; EFI_PEI_INSTALL_PPI InstallPpi; EFI_PEI_REINSTALL_PPI ReInstallPpi; EFI_PEI_LOCATE_PPI LocatePpi; EFI_PEI_NOTIFY_PPI NotifyPpi; //...      ... }; 

Am Anfang der Struktur EFI_PEI_SERVICES steht wie in allen "grundlegenden" Servicetabellen (Servicetabellen) die Struktur EFI_TABLE_HEADER. Mit den in dieser Header-Struktur dargestellten Werten können wir eindeutig feststellen, dass, wenn die EFI_PEI_SERVICES-Struktur selbst tatsächlich auf dem Fragment des Disassemblers vorhanden ist (siehe Feld „Hdr.Signature“), zumindest die Vorlage dieser Struktur!

 struct EFI_TABLE_HEADER { UINT64 Signature; UINT32 Revision; UINT32 HeaderSize; UINT32 CRC32; UINT32 Reserved; }; 

Auf dem Weg dorthin können wir feststellen, dass die Firmware zu einem Zeitpunkt entwickelt wurde, als die Version der UEFI PI-Spezifikation 1,2 betrug, deren Relevanzzeitraum von 2009 bis 2013 betrug, aber im Moment (Anfang 2019) ist die aktuelle Version der Spezifikation bereits gewachsen (buchstäblich neulich gewachsen). auf Version 1.7.

Aus dem Feld "Hdr.HeaderSize" kann bestimmt werden, dass die Gesamtlänge der Struktur 78h beträgt (und dies ist nicht die Länge des Headers, wie der Name schon sagt, sondern die Länge der gesamten Struktur von EFI_PEI_SERVICES).

Schnittstellen EFI_PEI_SERVICES sind in 7 Kategorien / Klassen unterteilt. Wir listen sie nur auf:

  1. PPI-Dienste.
  2. Boot Mode Services.
  3. HOB-Dienstleistungen.
  4. Firmware Volume Services.
  5. PEI-Speicherdienste.
  6. Statuscode-Dienste.
  7. Dienste zurücksetzen.

Alle weiteren Erläuterungen beziehen sich direkt auf die Verfahren der Kategorie / Klasse der PPI-Dienste, die für die Organisation der Interaktion zwischen Modulen von ausführbaren Modulen in der PEI-Phase vorgesehen sind.

Und für die PEI-Phase gibt es nur vier.

Im Allgemeinen muss der Zweck jeder der Schnittstellen nicht erraten werden: Die Funktionalität wird vollständig durch den Namen der Schnittstelle bestimmt, alle Details sind in der Spezifikation enthalten .

Das Folgende sind Prototypen dieser Verfahren:

 typedef EFI_STATUS (__cdecl *EFI_PEI_INSTALL_PPI)( const EFI_PEI_SERVICES **PeiServices, const EFI_PEI_PPI_DESCRIPTOR *PpiList); typedef EFI_STATUS (__cdecl *EFI_PEI_REINSTALL_PPI)( const EFI_PEI_SERVICES **PeiServices, const EFI_PEI_PPI_DESCRIPTOR *OldPpi, const EFI_PEI_PPI_DESCRIPTOR *NewPpi); typedef EFI_STATUS (__cdecl *EFI_PEI_LOCATE_PPI)( const EFI_PEI_SERVICES **PeiServices, const EFI_GUID *Guid, UINTN Instance, EFI_PEI_PPI_DESCRIPTOR **PpiDescriptor, void **Ppi); typedef EFI_STATUS (__cdecl *EFI_PEI_NOTIFY_PPI)( const EFI_PEI_SERVICES **PeiServices, const EFI_PEI_NOTIFY_DESCRIPTOR *NotifyList); 

Wir stellen nur fest, dass zusätzlich zu den Befehlen "Indirekter Aufruf" , die die Prozeduren / Schnittstellen der Klasse "PPI Services" aufrufen, ein expliziter (direkter - nicht tabellarischer) Aufruf dieser Prozeduren möglich ist, der manchmal in den ausführenden Modulen erfolgt, in denen die Struktur EFI_PEI_SERVICES definiert / erstellt wird.

Ich werde Ihnen ein kleines Geheimnis verraten: Seltsamerweise ist dies zwar die "grundlegende" Tabelle der Dienste für die PEI-Phase, aber wie die Praxis zeigt, kann sie nicht nur im PEI_CORE-Modul definiert werden.

In der Realität gibt es Firmwares, in denen die Struktur EFI_PEI_SERVICES definiert / gebildet und in mehreren Modulen verwendet wurde, und dies waren keineswegs Kopien des Moduls PEI_CORE.

Somit sind folgende Codeoptionen möglich:

 seg000:00785F0D B8 8C A6 78+ mov eax, offset ppiList_78A68C seg000:00785F12 50 push eax ; PpiList seg000:00785F13 57 push edi ; PeiServices seg000:00785F14 89 86 40 0E+ mov [esi+0E40h], eax seg000:00785F1A E8 70 FC FF+ call InstallPpi 

Ein Beispiel für einen expliziten Aufruf der Prozedur "InstallPpi".

 seg000:00787CBB 8B 4D FC mov ecx, [ebp+PeiServices] seg000:00787CBE 50 push eax ; PpiList seg000:00787CBF C7 00 10 00+ mov dword ptr [eax], 80000010h seg000:00787CC5 C7 43 3C A8+ mov dword ptr [ebx+3Ch], offset guid_78A9A8 seg000:00787CCC 8B 11 mov edx, [ecx] seg000:00787CCE 51 push ecx ; PeiServices seg000:00787CCF FF 52 18 call [edx+EFI_PEI_SERVICES.InstallPpi] 

Ein Beispiel für einen impliziten Aufruf der InstallPpi-Schnittstelle.

 FF 51 18 call dword ptr [ecx+18h] FF 51 18 call [ex+EFI_PEI_SERVICES.InstallPpi] FF 51 1 call dword ptr [ecx+1Ch] FF 51 1C call [ex+EFI_PEI_SERVICES.ReInstallPpi] FF 51 20 call dword ptr [ecx+20h] FF 51 20 call [ex+EFI_PEI_SERVICES.LocatePpi] FF 51 24 call dword ptr [ecx+24h] FF 51 24 call [ex+EFI_PEI_SERVICES.NotifyPpi] 
Beispiele für implizite Schnittstellenaufrufe vor und nach der Authentifizierung.

Wir stellen ein charakteristisches Merkmal fest: Im Fall der PEI-Phase für die IA-32-Architektur weisen Schnittstellen der PPI Services-Klasse Offsets von 18h, 1Ch, 20h und 24h auf.

Und jetzt geben wir folgende Aussage an:
Um ein statisches Abhängigkeitsdiagramm der PEI-Phase zu erstellen, ist es notwendig und ausreichend , alle ausführbaren Module der Phase vollständig zu zerlegen (mindestens alle Befehle zu trennen) und die Befehle "Indirekter Aufruf" mit Offsets 18h, 1Ch, 20h, 24h in zerlegten Modulen zu dekompilieren.
Tatsächlich haben wir einen Algorithmus zur Lösung des Problems vollständig formuliert. Sobald es uns gelungen ist, alle Aufrufe der Schnittstellen / Prozeduren der PPI Services-Klasse zu isolieren, muss nur noch bestimmt werden, welche Parameter an diese Aufrufe übergeben werden. Die Aufgabe mag nicht die trivialste sein, aber wie die Praxis gezeigt hat, ist sie vollständig lösbar, wir haben alle Daten dafür.

Und jetzt echte Beispiele für echte Daten für echte PEI-Phasenmodule. Wir geben nicht wissentlich an, welche BIOS / UEFI-Ergebnisse des Unternehmens erzielt wurden, sondern geben nur Beispiele für deren Aussehen.

Zwei Beispiele für PEIM-Modulbeschreibungen mit vollständigen Informationen zur Verwendung der PPI Services-Schnittstellen in diesen Modulen


  -- File 04-047/0x02F/: "TcgPlatformSetupPeiPolicy" : [007CCAF0 - 007CD144] DEPENDENCY_START EFI_PEI_READ_ONLY_VARIABLE_ACCESS_PPI DEPENDENCY_END Install Protocols: [1] TCG_PLATFORM_SETUP_PEI_POLICY Locate Protocols: [2] EFI_PEI_READ_ONLY_VARIABLE_ACCESS_PPI 
 -- File 04-048/0x030/: "TcgPei" : [007CD160 - 007CF5DE] DEPENDENCY_START EFI_PEI_MASTER_BOOT_MODE_PEIM_PPI EFI_PEI_READ_ONLY_VARIABLE_ACCESS_PPI AND DEPENDENCY_END Install Protocols: [1] AMI_TCG_PLATFORM_PPI [2] EFI_PEI_TCG_PPI [2] PEI_TPM_PPI Locate Protocols: [1] EFI_PEI_TCG_PPI [1] EFI_PEI_READ_ONLY_VARIABLE_ACCESS_PPI [1] TCG_PLATFORM_SETUP_PEI_POLICY [5] PEI_TPM_PPI Notify Events: [1] AMI_TCM_CALLBACK ReInstall Protocols: [1] PEI_TPM_PPI 

Protokolllisten nach Schnittstellentypen, in denen sie verwendet wurden


Unter den Spoilern finden Sie abgekürzte Beispiele für Listen von PPIM-Protokollen für jede der Schnittstellen der PPI Services-Klasse.

Das Format der Listen ist wie folgt:
 |  Seriennummer |  name_PPI |  guid_PPI |  ausführbarer_name: benutzername |

***** Installiere 99 Ppi in "Firmware"


***** Suchen Sie 194 Ppi in "Firmware"


***** Installieren Sie 5 Ppi in "Firmware" neu


***** Benachrichtigen Sie 29 Ppi in "Firmware"


Die endgültige Liste aller Handbücher der Protokolle, auf die in einem bestimmten BIOS / UEFI verwiesen wird, mit einer Legende, die angibt, in welchen "PPI-Diensten" diese Protokolle enthalten sind


Unten finden Sie eine Spoiler-Liste von 97 PPi-Guids, die in einer bestimmten Firmware gefunden und explizit verwendet wurden, deren Daten zuvor angegeben wurden.

Vor jedem Element aus der Liste steht eine Legende, die alle Verwendungsarten eines bestimmten Protokolls widerspiegelt.

 "D" - in DEPENDENCY section used "I" - in "InstallPpi" functions used "L" - in "LocatePpi" functions used "R" - in "ReInstallPpi" functions used "N" - in "NotifyPpi" functions used 

***** Liste Ppi in "Firmware"




Die folgenden Protokolllistenintervalle sind in diesem BIOS / UEFI bemerkenswert:

  1. Nr. 38-50.
    Definieren von Protokollen / Ereignissen (InstallPpi), die von keinem Modul verwendet werden.
  2. Nr. 87-95.
    Versuchen Sie, Protokolle anzufordern, die von keinem Modul dieser Firmware installiert wurden.
  3. Nr. 96-97.
    Zwei "Benachrichtigungs" -Ereignisse, für die sich kein Modul die Mühe gemacht hat, die entsprechende Schnittstelle zu deklarieren. Obwohl diese Prozeduren in ausführbaren Modulen deklariert sind, funktionieren sie niemals.

Fazit


  • Ähnliche Ergebnisse wie oben wurden für BIOS / UEFI von verschiedenen Herstellern erhalten, weshalb alle Beispiele anonym sind.
  • Tatsächlich wurden allgemeinere Aufgaben zum Umkehren der Algorithmen ausführbarer BIOS / UEFI-Module gelöst, und das resultierende Diagramm ist ein Nebenergebnis, eine Art zusätzlicher Bonus.
  • Die korrekte Lösung der Aufgabe "Abrufen eines statischen Abhängigkeitsgraphen" für ausführbare BIOS / UEFI-Module erfordert eine statische Analyse des Binärcodes, die eine vollständige Demontage der ausführbaren Module und eine teilweise Dekompilierung der Indirect Call- Befehle dieser Module umfasst.

Source: https://habr.com/ru/post/de440052/


All Articles