Dieses Tool ermöglicht es, eine vollständig analyzbare .elf -Datei von einem VMlinux/VMlinuz/Bzimage/Zimage -Kernel -Bild (entweder ein roher binärer Blob oder eine bereits bestehende, aber strippierte .elf -Datei) mit wiederhergestellten Funktionen und variablen Symbolen zu erhalten.
Dafür scannt es Ihren Kernel nach einer Kernel -Symbol -Tabelle (Kallsyms), einer komprimierten Symboltabelle, die in fast jedem Kernel vorhanden ist, der größtenteils unverändert ist.
Da die betroffene Symboltabelle ursprünglich komprimiert ist, sollte sie Strings wiederherstellen, die im ursprünglichen Binär nicht sichtbar sind.
Es erzeugt eine .elf -Datei, die Sie mit IDA Pro und Ghidra analysieren können. Dieses Tool ist daher nützlich für eingebettete Systeme Reverse Engineering.
Verwendung:
./vmlinux-to-elf < input_kernel.bin > < output_kernel.elf > Systemweite Installation (der zweite Befehl ist möglicherweise nicht erforderlich, da PIP die Abhängigkeiten in der Datei setup.py finden sollte):
sudo apt install python3-pip liblzo2-dev
sudo pip3 install --upgrade lz4 zstandard git+https://github.com/clubby789/python-lzo@b4e39df
sudo pip3 install --upgrade git+https://github.com/marin-m/vmlinux-to-elfboot.img -Dateien, beginnend mit einem ANDROID! oder UNCOMPRESSED_IMG Magie [OK]Eine kurze Geschichte der "Kallsyms" -Symbol -Tabelle befindet sich oben in der Datei "kallsyms_finder.py". Kurz gesagt, dies wurde um 2004 im Linux -Kernel in seiner aktuellen Form eingeführt und wird verwendet, um die "Kernel oops" -Meldungen unter anderem zu drucken.
Es enthält Tupel von "Symbolname", "Symboladresse", "Symboltyp" (Symboltypen, die mit einem einzelnen Buchstaben in ähnlicher Weise wie dem nm -Dienstprogramm ausgewiesen werden), wobei diese Informationen mit einem einfachen Komprimierungsalgorithmus eng gepackt sind.
Das folgende Schema zeigt an, wie diese Informationen in den Kernel serialisiert werden, wobei der Versatz jeder jeweiligen Struktur durch Heuristik von vmlinux-to-elf erkannt wird:
| Array -Name | Beschreibung | Probeninhalt |
|---|---|---|
kallsyms_addresses (oder kallsyms_offsets + kallsyms_relative_base ) | Die Adressen (oder Offsets in Bezug auf eine Basis in den letzten Kerneln) jedes Symbols als Array | 80 82 00 C0 80 82 00 C0 80 82 00 C0 0C 84 00 C0 B4 84 00 C0 5C 85 00 C0 60 85 00 C0 60 85 00 C0 ... |
kallsyms_num_syms | Die Gesamtzahl der Symbole als Ganzzahl (nützlich für die Überprüfung auf Endianges, Ausrichtung, korrekte Decodierung der Symbole Tabelle) | 54 D4 00 00 |
kallsyms_names | Das komprimierte, lang getrennte Symbol selbst nennt selbst. Jedes Byte in den komprimierten Symbol -Zeichenfolgen verweist auf einen Index im Array "kallsyms_token_index", in dem sich selbst auf den Versatz eines Zeichen- oder String -Fragments im Array "Kallsyms_Token_Table" verweist. | 09 54 64 6F 5F E1 F1 66 F5 25 05 54 F3 74 AB 74 0E 54 FF AB ... |
kallsyms_markers | Eine Nachschlagtabelle, die dazu dient, schnell den approximativen Offset eines komprimierten Symbolnamens in "kallsyms_names" zu finden: Alle 256 Symbole, ein Offset für das betroffene Symbol in "kallsyms_names" wird als lang zu dieser Tabelle hinzugefügt. | 00 00 00 00 03 0C 00 00 0C 18 00 00 1B 24 00 00 0F 31 00 00 DA 3D 00 00 CF 4A 00 00 ... |
kallsyms_seqs_of_names | Diese Nachschlagetabelle kallsyms_addresses nur in 6.2+ Kerneln vorhanden) enthält eine Array kallsyms_names Sequenz von verpackten 3-Byte | |
kallsyms_token_table | NULL-terminierte Zeichenfolgenfragmente oder Zeichen, die in Kernel-Symbolnamen enthalten sein können. Dies kann höchstens 256 String -Fragmente oder Zeichen enthalten. Indizes, die ASCII -Codepunkten entsprechen, die tatsächlich in jedem Kernelsymbol verwendet werden, entsprechen dem betroffenen ASCII -Zeichen. Andere Positionen enthalten ein statistisch ausgewähltes String -Fragment. Dieses Tool versucht, dieses Array zuerst heuristisch zu finden, um die kallsyms -Symbole -Tabelle zu finden. | 73 69 00 67 70 00 74 74 00 79 6E 00 69 6E 74 5F 00 66 72 00 ... |
kallsyms_token_index | 256 Wörter, jede Zuordnung zu den Offsets der Zeichen oder Stringfragmente, die nach ihren jeweiligen Indizes in "Kallsyms_Token_Table" bezeichnet werden. | 00 00 03 00 06 00 09 00 0C 00 11 00 14 00 1B 00 1E 00 22 00 2C 00 30 00 35 00 38 00 ... |
Diese Felder haben eine variable Ausrichtung und Feldgröße. Die Feldgrößen können auch über Architektur und Kernelversion variieren. Aus diesem Grund wurde vmlinux-to-elf in verschiedenen Fällen getestet.
OpenWRT hat seit 2013 einen Patch, der die Komprimierung über die kallsyms -Tabelle standardmäßig beseitigt (beim Erstellen kallsyms wurde vom Benutzer aktiviert). Sie tun dies, um Platz zu sparen, wenn Sie mit LZMA über den Kernel neu komprimiert werden.
Dies bedeutet, dass die Einträge kallsyms_token_table und kallsyms_token_address verschwinden, und dass die Symbolnamen stattdessen nur Text ASCII verwenden. Dieser Fall wird auch unterstützt.
In Standard -Linux 6.2 -Kerneln werden kallsyms -Arrays in der folgenden Reihenfolge codiert:
kallsyms_addresses (oder kallsyms_offsets + kallsyms_relative_base )kallsyms_num_symskallsyms_nameskallsyms_markerskallsyms_seqs_of_names (nur 6.2+)kallsyms_token_tablekallsyms_token_indexFür Linux 6.4+ -Kerne wird dieses Layout geändert in:
kallsyms_num_symskallsyms_nameskallsyms_markerskallsyms_token_tablekallsyms_token_indexkallsyms_addresses (oder kallsyms_offsets + kallsyms_relative_base )kallsyms_seqs_of_names Während diese in der folgenden Reihenfolge von vmlinux-to-elf Parsing-Algorithmus analysiert werden:
kallsyms_token_table (vorletzte Struktur)kallsyms_token_index (letzte Struktur, Vorwärtsgeschäfte)kallsyms_markers (rückwärts)kallsyms_names (wieder rückwärts)kallsyms_num_syms (wieder rückwärts)kallsyms_addresses (oder kallsyms_offsets + kallsyms_relative_base ) (wieder rückwärts) Es sollte Kernel von Version 2.6.10 (Dezember 2004) bis zum aktuellen 6.4 (ab August 2023) unterstützen. Nur Kernel, die explizit ohne CONFIG_KALLSYMS konfiguriert sind, sollten nicht unterstützt werden. Wenn diese Kernel -Konfigurationsvariable nicht auf Build eingestellt wurde, erhalten Sie: KallsymsNotFoundException: No embedded symbol table found in this kernel .
Für rohe Kerne können die folgenden Architekturen festgestellt werden (unter Verwendung von Magics aus Binwalk): MIPEL, MIPSEB, Armel, Armeb, Powerpc, SPARC, X86, X86-64, ARM64, MIPS64, Superh, Arc.
Die folgenden Kernelkompressionsformate können automatisch erkannt werden: XZ, LZMA, GZIP, BZ2, LZ4, LZO und ZSTD.
Sie können auch eine Nur-Text-Ausgabe der Symbolnamen, Adressen und Typen des Kernels durch die Verwendung des kallsyms-finder Dienstprogramms erhalten, das ebenfalls mit diesem Tool gebündelt ist. Das Format seiner Ausgabe ähnelt der Procfs -Datei /proc/kallsyms .
Einige Parameter, die vom Tool automatisch abgeleitet werden sollten (z. B. den Befehlssatz oder die Basisadresse), können im Problem überschrieben werden. Die vollständige Spezifikation der Argumente, die dies ermöglichen, wird nachstehend dargestellt:
$ vmlinux-to-elf -h
usage: vmlinux-to-elf [-h] [--e-machine DECIMAL_NUMBER] [--bit-size BIT_SIZE]
[--file-offset HEX_NUMBER] [--base-address HEX_NUMBER]
input_file output_file
Turn a raw or compressed kernel binary, or a kernel ELF without symbols, into
a fully analyzable ELF whose symbols were extracted from the kernel symbol
table
positional arguments:
input_file Path to the
vmlinux/vmlinuz/zImage/bzImage/kernel.bin/kernel.elf
file to make into an analyzable .ELF
output_file Path to the analyzable .ELF to output
optional arguments:
-h, --help show this help message and exit
--e-machine DECIMAL_NUMBER
Force overriding the output ELF "e_machine" field with
this integer value (rather than auto-detect)
--bit-size BIT_SIZE Force overriding the input kernel bit size, providing
32 or 64 bit (rather than auto-detect)
--file-offset HEX_NUMBER
Consider that the raw kernel starts at this offset of
the provided raw file or compressed stream (rather
than 0, or the beginning of the ELF sections if an ELF
header was present in the input)
--base-address HEX_NUMBER
Force overriding the output ELF base address field
with this integer value (rather than auto-detect)
$ kallsyms-finder -h
usage: kallsyms-finder [-h] [--bit-size BIT_SIZE] input_file
Find the kernel's embedded symbol table from a raw or stripped ELF kernel
file, and print these to the standard output with their addresses
positional arguments:
input_file Path to the kernel file to extract symbols from
optional arguments:
-h, --help show this help message and exit
--bit-size BIT_SIZE Force overriding the input kernel bit size, providing
32 or 64 bit (rather than auto-detect)
Zögern Sie nicht, ein Problem für einen Verbesserungsvorschlag zu eröffnen.