該工具允許從vmlinux/vmlinuz/bzimage/zimage內核圖像獲得完全可分析的.eff文件(恢復功能和可變符號,都可以使用原始的二進制斑點或已刪除的drake trepeefef。
為此,它會掃描您的內核中的內核符號表(kallsyms),這是一個壓縮符號表,幾乎每個內核都存在,大部分都沒有改變。
由於相關符號表最初是壓縮的,因此應恢復原始二進制中不可見的字符串。
它會生成一個.fly文件,您可以使用IDA Pro和Ghidra進行分析。因此,該工具對於嵌入式系統逆向工程很有用。
用法:
./vmlinux-to-elf < input_kernel.bin > < output_kernel.elf >整個系統安裝(可能不需要第二個命令,因為PIP應該在setup.py中找到依賴項):
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 ANDROID!或未UNCOMPRESSED_IMG魔術[OK]可以在“ kallsyms_finder.py”文件的頂部找到“ kallsyms”符號表的簡短歷史記錄。簡而言之,這是在2004年的Linux內核中以其當前形式引入的,用於打印“內核OOPS”消息等。
它包含“符號名稱”,“符號地址”,“符號類型”的元素(符號類型(用類似於nm實用程序的單個字母)指定的符號類型),此信息與簡單的壓縮算法緊密包裝。
下面的模式顯示瞭如何將此信息序列化到內核中,這是通過啟發式方法檢測到的vmlinux-to-elf所檢測到的每個相應結構的偏移:
| 數組名稱 | 描述 | 樣本內容 |
|---|---|---|
kallsyms_addresses (或kallsyms_offsets + kallsyms_relative_base ) | 每個符號作為數組 | 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 | 符號的總數,作為整數(用於檢查底色,對齊,正確解碼符號表) | 54 D4 00 00 |
kallsyms_names | 壓縮,長度分離的符號本身。壓縮符號字符串中的每個字節引用了“ kallsyms_token_index”數組中的索引,該數個數組本身引用了“ kallsyms_token_table”陣列中字符或字符串片段的偏移。 | 09 54 64 6F 5F E1 F1 66 F5 25 05 54 F3 74 AB 74 0E 54 FF AB ... |
kallsyms_markers | 查找表可快速找到“ kallsyms_names”中的壓縮符號名稱的近似偏移:每256個符號,“ kallsyms_names”中相關符號的偏移是在此表中添加的。 | 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 | 此查找表(僅在6.2+內存中)包含一個包裝的3字節整數的數組序列,其中陣列索引符合給定符號名稱的字母數字順序,並且陣列值與kallsyms_addresses和kallsyms_names中的相應輸入索引匹配 | |
kallsyms_token_table | 可包含內核符號名稱中的零終止的字符串片段或字符。這最多可以包含256個字符串片段或字符。與ASCII代碼點相對應的索引,實際上在任何內核符號中使用的索引將與相關的ASCII字符相對應,其他位置將包含統計選擇的字符串片段。該工具試圖首先在傳遞的文件上啟發上找到此數組,以找到kallsyms符號表。 | 73 69 00 67 70 00 74 74 00 79 6E 00 69 6E 74 5F 00 66 72 00 ... |
kallsyms_token_index | 256個單詞,每個映射到“ kallsyms_token_table”中各自索引指定的字符或字符串片段的偏移。 | 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 ... |
這些字段具有可變的對齊和字段大小。場地的大小可能會因體系結構和內核版本而異。因此, vmlinux-to-elf已在多種情況下進行了測試。
自2013年以來,OpenWrt的補丁程序默認情況下可以在kallsyms表上刪除壓縮(用戶啟用了kallsyms時)。他們這樣做是為了在使用LZMA重新壓縮內核時節省空間。
這意味著kallsyms_token_table和kallsyms_token_address條目消失了,並且符號名稱使用純文本ascii。此案也得到了支持。
在標準Linux 6.2內核中, kallsyms數組按以下順序進行編碼:
kallsyms_addresses (或kallsyms_offsets + kallsyms_relative_base )kallsyms_num_symskallsyms_nameskallsyms_markerskallsyms_seqs_of_names (僅6.2+)kallsyms_token_tablekallsyms_token_index對於Linux 6.4+內核,此佈局更改為:
kallsyms_num_symskallsyms_nameskallsyms_markerskallsyms_token_tablekallsyms_token_indexkallsyms_addresses (或kallsyms_offsets + kallsyms_relative_base )kallsyms_seqs_of_names雖然它們按以下順序解析了vmlinux-to-elf的解析算法:
kallsyms_token_table (持久結構)kallsyms_token_index (最後一個結構,向前)kallsyms_markers (向後)kallsyms_names (再次向後)kallsyms_num_syms (再次向後)kallsyms_addresses (或kallsyms_offsets + kallsyms_relative_base )(再次向後) 它應支持2.6.10版(2004年12月)的內核,直到當前6.4(截至2023年8月)。不得支持沒有CONFIG_KALLSYMS的明確配置的內核。如果在構建中未設置此內核配置變量,則您將獲得: KallsymsNotFoundException: No embedded symbol table found in this kernel 。
對於RAW內核,可以檢測到以下架構(使用BinWalk的MAGIC):MIPSEL,MIPSEB,ARMEL,ARMEB,ARMEB,POWERPC,SPARC,SPARC,X86,X86-64,ARM64,MIPS64,MIPS64,SUPERH,ARC。
可以自動檢測到以下內核壓縮格式:XZ,LZMA,GZIP,BZ2,LZ4,LZO和ZSTD。
您還可以通過使用kallsyms-finder實用程序獲得內核符號名稱,地址和類型的僅文本輸出,並與此工具捆綁在一起。其輸出格式將類似於/proc/kallsyms procfs文件。
如果在發行問題的情況下,該工具應自動推斷的某些參數(例如指令集或基本地址)可能會被覆蓋。允許這樣做的參數的完整規範如下:
$ 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)
不要猶豫,為任何改進的建議打開一個問題。