Ich stieß auf dasselbe Problem, allerdings nicht mit Steam. Was ich wollte, wollte 2.15
für fdelt_chk
während mein System hatte 2.14
. Ich habe eine Lösung für einfache Fälle wie unsere gefunden, in denen wir leicht eine eigene Implementierung für die fehlende Funktionalität bereitstellen können.
Ich begann von Ihrer versuchten Lösung der Implementierung der Funktionalität und LD_PRELOAD
ing es. Die Verwendung von (wie von OSGX vorgeschlagen) zeigte, dass der Linker immer noch nach 2.15
suchte, also war es nicht genug, das richtige Symbol zu haben, und irgendwo gab es einen anderen Versionierungsmechanismus. Ich bemerkte, dass objdump -p
und readelf -V
beide Referenzen auf 2.15
zeigten, also suchte ich nach Dokumentation über ELF und fand information on version requirements.
Also mein neues Ziel war, Referenzen auf in Verweise auf etwas anderes zu transformieren. Es schien vernünftig, dass ich einfach Strukturen überschreiben konnte, die sich auf mit den Strukturen bezogen, die sich auf eine niedrigere Version bezogen, wie 2.1
. Am Ende, nach einigem Versuch und Irrtum, fand ich gerade das Bearbeiten der richtigen Elfxx_Vernaux
(es?) In .gnu.version_r
war ausreichend, aber Vorsicht Hacker, schätze ich.
Der .gnu.version_r
Abschnitt ist eine Liste von 16-Byte Elfxx_Verneed
s und 16-Byte Elfxx_Vernaux
es.Jedem Eintrag Elfxx_Verneed
folgt der zugehörige Eintrag Elfxx_Vernaux
es. Soweit ich sagen konnte, ist vn_file
tatsächlich, wie viele assoziierte Elfxx_Vernaux
es gibt, obwohl die Dokumente sagen number of associated verneed array entries
. Es könnte jedoch nur ein Missverständnis sein.
Also, um die Bearbeitungen zu starten, schauen wir uns einige Informationen von readelf -V
an. Ich habe Teile herausgeschnitten, die uns nicht interessieren.
$ readelf -V mybinary
<snip stuff before .gnu.version_r>
Version needs section '.gnu.version_r' contains 5 entries:
Addr: 0x00000000000021ac Offset: 0x0021ac Link: 4 (.dynstr)
<snip libraries that don't refer to GLIBC_2.15>
0x00c0: Version: 1 File: libc.so.6 Cnt: 10
0x00d0: Name: GLIBC_2.3 Flags: none Version: 19
0x00e0: Name: GLIBC_2.7 Flags: none Version: 16
0x00f0: Name: GLIBC_2.2 Flags: none Version: 15
0x0100: Name: GLIBC_2.2.4 Flags: none Version: 14
0x0110: Name: GLIBC_2.1.3 Flags: none Version: 13
0x0120: Name: GLIBC_2.15 Flags: none Version: 12
0x0130: Name: GLIBC_2.4 Flags: none Version: 10
0x0140: Name: GLIBC_2.1 Flags: none Version: 9
0x0150: Name: GLIBC_2.3.4 Flags: none Version: 4
0x0160: Name: GLIBC_2.0 Flags: none Version: 2
Daraus sehen wir, dass der Abschnitt in 0x21ac
beginnt. Jede aufgelistete Datei hat einen Elfxx_Verneed
gefolgt von einem Elfxx_Vernaux
für jeden der Untereinträge (wie GLIBC_2.3
). Ich nehme an, dass die Reihenfolge der Informationen in der Ausgabe immer der Reihenfolge in der Datei entspricht, da readelf
nur die Strukturen ausgibt. Hier ist meine gesamte.gnu.version_r
Abschnitt.
000021A0 01 00 02 00
000021B0 A3 0C 00 00 10 00 00 00 30 00 00 00 11 69 69 0D
000021C0 00 00 11 00 32 0D 00 00 10 00 00 00 10 69 69 0D
000021D0 00 00 0B 00 3C 0D 00 00 00 00 00 00 01 00 02 00
000021E0 BE 0C 00 00 10 00 00 00 30 00 00 00 13 69 69 0D
000021F0 00 00 08 00 46 0D 00 00 10 00 00 00 10 69 69 0D
00002200 00 00 07 00 3C 0D 00 00 00 00 00 00 01 00 02 00
00002210 99 0C 00 00 10 00 00 00 30 00 00 00 11 69 69 0D
00002220 00 00 06 00 32 0D 00 00 10 00 00 00 10 69 69 0D
00002230 00 00 05 00 3C 0D 00 00 00 00 00 00 01 00 02 00
00002240 AE 0C 00 00 10 00 00 00 30 00 00 00 11 69 69 0D
00002250 00 00 12 00 32 0D 00 00 10 00 00 00 10 69 69 0D
00002260 00 00 03 00 3C 0D 00 00 00 00 00 00 01 00 0A 00
00002270 FF 0C 00 00 10 00 00 00 00 00 00 00 13 69 69 0D
00002280 00 00 13 00 46 0D 00 00 10 00 00 00 17 69 69 0D
00002290 00 00 10 00 50 0D 00 00 10 00 00 00 12 69 69 0D
000022A0 00 00 0F 00 5A 0D 00 00 10 00 00 00 74 1A 69 09
000022B0 00 00 0E 00 64 0D 00 00 10 00 00 00 73 1F 69 09
000022C0 00 00 0D 00 70 0D 00 00 10 00 00 00 95 91 96 06
000022D0 00 00 0C 00 7C 0D 00 00 10 00 00 00 14 69 69 0D
000022E0 00 00 0A 00 87 0D 00 00 10 00 00 00 11 69 69 0D
000022F0 00 00 09 00 32 0D 00 00 10 00 00 00 74 19 69 09
00002300 00 00 04 00 91 0D 00 00 10 00 00 00 10 69 69 0D
00002310 00 00 02 00 3C 0D 00 00 00 00 00 00
Um kurz über die Struktur zu sprechen hier, es beginnt mit einem Elfxx_Verneed
aus. Laut der Dokumentation können wir sehen, es wird 2 Elfxx_Vernaux
es, ein Offset 16 Bytes, und der nächste Elfxx_Verneed
ist Offset 48 Bytes. Diese Offsets sind vom Anfang der aktuellen Struktur. Es sieht aus wie technisch die verbundenen Elfxx_Vernaux
es möglicherweise nicht angrenzend nach der aktuellen Elfxx_Verneed
aber es war eigentlich so in allen Dateien stocherte ich in.
Von diesem können wir die Datei finden, die wir wollen (libc.so.6) auf ein paar verschiedene Arten. Querverweis auf die Zeichenfolge (die ich nicht bekommen werde), finden Sie die Elfxx_Verneed
mit einer Zählung von 0A 00
(10, passend zu unserem readelf
Ausgang oben), oder finden Sie die letzte Elfxx_Verneed
, da es die letzte readelf
Ausgabe ist. In jedem Fall ist der richtige für meine Datei unter 0x226C
. Seine erste Elfxx_Vernaux
beginnt bei 0x227C
.
Wir wollen die Elfxx_Vernaux
mit einer Version von (12, wieder passend zu unserem readelf
Ausgang oben) finden. Wir sehen die Elfxx_Vernaux
, die passt, ist 0x22CC
und die gesamte Struktur ist 95 91 96 06 00 00 0C 00 7C 0D 00 00 10 00 00 00
. Wir werden die ersten 12 Bytes überschreiben, um den Offset alleine zu lassen. Wir modifizieren nur die Daten, bewegen uns nicht um die Strukturen herum.
Um die Daten zum Überschreiben mit auszuwählen, kopieren wir es einfach von einem anderen Elfxx_Vernaux
für eine Version von glibc, die wir erfüllen können. Ich wählte eine für 2.1
, die unter 0x22EC
in meiner Datei ist, mit den Daten 11 69 69 0D 00 00 09 00 32 0D 00 00 10 00 00 00
. Also nimm die ersten 12 Bytes davon und überschreibe die ersten 12 Bytes oben, und das war's für die Hex-Bearbeitung.
Natürlich könnten Sie mehrere Referenzen haben, mit denen Sie umgehen müssen. Ihr Programm könnte mehrere Binärdateien zum Bearbeiten haben.
An diesem Punkt wird unser Programm immer noch nicht ausgeführt. Aber statt etwas wie GLIBC_2.15 not found
gesagt werden, sollte es über fehlende __fdelt_chk
beschweren. Jetzt machen wir die Shim und LD_PRELOAD
in der Frage beschrieben, außer, anstatt unsere Implementierung als 2.15
Versionierung, verwenden wir die Version, die wir während der Hex-Bearbeitung ausgewählt. An diesem Punkt sollte das Programm laufen.
Diese Methode hängt davon ab, eine Implementierung für alles, was fehlt, bereitstellen zu können. Unsere __fdelt_chk
ist extrem einfach, aber ich bezweifle nicht, dass in einigen Fällen die Bereitstellung einer Implementierung schwieriger sein könnte, als nur die libc des Systems zu aktualisieren.
Versuchen zu ermöglichen [LD_DEBUG] (http://www.bnikolic.co .uk/blog/linux-ld-debug.html) '= all' und überprüfe, wie rtld (ld-linux.so) nach' __fdelt' und '@@ GLIBC_2.15' sucht. – osgx
So viel logspam. Es sieht so aus, als würde man nur '/ lib/i386-linux-gnu/i686/cmov/libc.so.6' betrachten und sofort aufgeben. Vielleicht muss ich ein geeignetes Soname für fdelt_chk.so ... –
Einstellung '-Wl, -soname, libc.so.6' tötet alles, denn jetzt wird es nicht weiter als meine eigene Bibliothek suchen. Wäre es möglich, die tatsächliche 'libc' durch den absoluten Soname zu importieren und alle anderen Symbole wieder zu exportieren? –