Wie füge ich zwei ausführbare Binärdateien zusammen?

8

Diese Frage folgt aus einer weiteren Frage Ich habe vorher gefragt. Kurz gesagt, dies ist einer meiner Versuche, zwei vollständig verknüpfte ausführbare Dateien zu einer einzigen vollständig verknüpften ausführbaren Datei zusammenzuführen. Der Unterschied besteht darin, dass die vorherige Frage das Zusammenführen einer Objektdatei mit einer vollständigen verknüpften ausführbaren Datei betrifft, was noch schwieriger ist, da ich manuell mit Umlagerungen umgehen muss.

Was ich habe, sind die folgenden Dateien:

example-target.c :

%Vor%

example-embed.c :

%Vor%

Mein Ziel ist es, diese beiden ausführbaren Dateien zu einer endgültigen ausführbaren Datei zusammenzufassen, die mit example-target identisch ist, aber zusätzlich noch eine main und func1 hat.

Aus der Sicht der BFD-Bibliothek besteht jede Binärdatei (unter anderem) aus einer Reihe von Abschnitten. Eines der ersten Probleme, denen ich gegenüberstand, war, dass diese Abschnitte widersprüchliche Ladeadressen hatten (so dass sich die Abschnitte überschneiden würden, wenn ich sie zusammenführen würde).

Was ich getan habe, um das Problem zu lösen, war, example-target programmatisch zu analysieren, um eine Liste der Ladeadresse und der Größe jedes Abschnitts zu erhalten. Ich machte das gleiche für example-embed und verwendete diese Informationen, um dynamisch ein linker-Befehl für example-embed.c , das sicherstellt, dass alle seine Abschnitte mit Adressen verknüpft sind, die sich nicht mit den Abschnitten in example-target überschneiden. Daher ist example-embed in diesem Prozess tatsächlich zweimal vollständig verknüpft: einmal, um zu bestimmen, wie viele Abschnitte und welche Größen sie sind, und noch einmal, um zu garantieren, dass keine Abschnittskonflikte mit example-target auftreten.

Auf meinem System ist der erzeugte Linkerbefehl:

%Vor%

(Beachten Sie, dass ich Abschnittsnamen mit .new vorangestellt habe, indem Sie objcopy --prefix-sections=.new example-embedobj verwenden, um Zusammenstöße mit Abschnittsnamen zu vermeiden.)

Ich habe dann einen Code geschrieben, um eine neue ausführbare Datei zu erzeugen (ich habe mir Code aus objcopy und Security Warrior book ausgeliehen). Die neue ausführbare Datei sollte folgendes haben:

  • Alle Abschnitte von example-target und alle Abschnitte von example-embed
  • Eine Symboltabelle, die alle Symbole von example-target und alle Symbole von example-embed enthält

Der Code, den ich geschrieben habe, ist:

%Vor%

Um zusammenzufassen, was dieser Code macht, benötigt er 2 Eingabedateien ( ibfd und embedbfd ), um eine Ausgabedatei ( obfd ) zu erzeugen.

  • Kopiert Format / arch / mach / file Flags und startet die Adresse von ibfd bis obfd
  • Definiert Abschnitte von ibfd und embedbfd bis obfd . Die Auffüllung der Sektionen erfolgt separat, da BFD vorschreibt, dass alle Sektionen erstellt werden, bevor sie mit einem Eintrag beginnen.
  • Fügen Sie private Daten beider BFD-Inputs mit dem BFD-Output zusammen. Da BFD eine übliche Abstraktion über vielen Dateiformaten ist, ist es nicht unbedingt in der Lage, alles, was für das zugrundeliegende Dateiformat erforderlich ist, umfassend zu kapseln.
  • Erstellen Sie eine kombinierte Symboltabelle bestehend aus der Symboltabelle von ibfd und embedbfd und setzen Sie diese als Symboltabelle von obfd . Diese Symboltabelle wird gespeichert, damit sie später zum Erstellen von Verschiebungsinformationen verwendet werden kann.
  • Kopieren Sie die Abschnitte von ibfd nach obfd . Neben dem Kopieren des Abschnittsinhalts umfasst dieser Schritt auch das Erstellen und Festlegen der Umlagerungstabelle.

Im obigen Code sind einige Zeilen mit /******** */ auskommentiert. Diese Zeilen befassen sich mit der Zusammenführung von example-embed . Wenn sie auskommentiert sind, wird obfd einfach als Kopie von ibfd erstellt. Ich habe das getestet und es funktioniert gut. Sobald ich jedoch diese Zeilen zurückkommne, treten die Probleme auf.

Bei der unkommentierten Version, die die vollständige Zusammenführung ausführt, wird immer noch eine Ausgabedatei erzeugt. Diese Ausgabedatei kann mit objdump überprüft werden und enthält alle Abschnitte, Code- und Symboltabellen der beiden Eingaben. % Co_de% beschwert sich jedoch mit:

%Vor%

Auf meinem System ist objdump von 1708 :

%Vor%

elf.c ist ein Makro in elf_dynsymtab für:

%Vor%

Ich bin nicht mit der ELF-Ebene vertraut, aber ich glaube, das ist ein Problem beim Lesen der dynamischen Symboltabelle (oder vielleicht, dass sie nicht vorhanden ist). Für die Zeit versuche ich zu vermeiden, direkt in die ELF-Schicht hinuntergreifen zu müssen, wenn es nicht notwendig ist. Kann jemand mir sagen, was ich falsch mache, entweder in meinem Code oder konzeptionell?

Wenn es hilfreich ist, kann ich auch den Code für die Linker-Befehlsgenerierung oder kompilierte Versionen der Beispiel-Binärdateien veröffentlichen.

Ich weiß, dass dies eine sehr große Frage ist und aus diesem Grund möchte ich jeden, der mir dabei helfen kann, angemessen belohnen. Wenn ich dies mit Hilfe von jemandem lösen kann, bin ich glücklich, einen Bonus von 500+ zu vergeben.

    
Mike Kwan 15.03.2012, 14:36
quelle

1 Antwort

1

Warum machen Sie das alles manuell? Angesichts der Tatsache, dass Sie alle Symbolinformationen haben (die Sie benötigen, wenn Sie die Binärdatei auf vernünftige Weise bearbeiten möchten), wäre es nicht einfacher, die ausführbare Datei in separate Objektdateien (z. B. eine Objektdatei pro Funktion) zu zerlegen Bearbeiten und erneut verknüpfen?

    
zvrba 15.03.2012 16:03
quelle

Tags und Links