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
:
example-embed.c
:
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:
example-target
und alle Abschnitte von example-embed
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.
ibfd
bis obfd
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. 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. 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:
Auf meinem System ist objdump
von 1708
:
elf.c
ist ein Makro in elf_dynsymtab
für:
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.
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?