เครื่องมือนี้ช่วยให้ได้รับไฟล์. ตัวเองที่สามารถวิเคราะห์ได้อย่างเต็มที่จากภาพเคอร์เนล VMLINUX/VMLINUZ/BZIMAGE/ZIMAGE (ทั้ง binary binary ดิบหรือไฟล์ preexisting แต่ถูกถอดไฟล์.
สำหรับสิ่งนี้มันจะสแกนเคอร์เนลของคุณสำหรับตารางสัญลักษณ์เคอร์เนล (Kallsyms) ตารางสัญลักษณ์บีบอัดที่มีอยู่ในเกือบทุกเคอร์เนลซึ่งส่วนใหญ่ไม่เปลี่ยนแปลง
เนื่องจากตารางสัญลักษณ์ที่เกี่ยวข้องถูกบีบอัด แต่เดิมควรกู้คืนสตริงที่ไม่สามารถมองเห็นได้ในไบนารีดั้งเดิม
มันสร้างไฟล์. ตัวเองที่คุณสามารถวิเคราะห์ได้โดยใช้ 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 [ตกลง]ประวัติย่อของตารางสัญลักษณ์ "Kallsyms" สามารถพบได้ที่ด้านบนของไฟล์ "kallsyms_finder.py" โดยสังเขปสิ่งนี้ได้รับการแนะนำ Circa 2004 ในเคอร์เนล Linux ในรูปแบบปัจจุบันและใช้ในการพิมพ์ข้อความ "เคอร์เนลโอ๊ะโอ" ท่ามกลางสิ่งอื่น ๆ
มันมี tuples ของ "ชื่อสัญลักษณ์", "ที่อยู่สัญลักษณ์", "ประเภทสัญลักษณ์" (ประเภทสัญลักษณ์ที่ถูกกำหนดด้วยตัวอักษรเดียวในรูปแบบที่คล้ายกับยูทิลิตี้ 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 | จำนวนสัญลักษณ์ทั้งหมดเป็นจำนวนเต็ม (มีประโยชน์สำหรับการตรวจสอบ endianness, การจัดตำแหน่ง, การถอดรหัสที่ถูกต้องของตารางสัญลักษณ์) | 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 | ชิ้นส่วนหรืออักขระสตริงที่สิ้นสุดแบบไม่มีค่าที่อาจมีอยู่ในชื่อสัญลักษณ์เคอร์เนล สิ่งนี้สามารถมีชิ้นส่วนหรืออักขระสตริงได้มากที่สุด ดัชนีที่สอดคล้องกับจุดรหัส 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 จึงได้รับการทดสอบในหลายกรณี
OpenWRT ตั้งแต่ปี 2013 มีแพตช์ที่ลบการบีบอัดเหนือตาราง kallsyms โดยค่าเริ่มต้น (เมื่อผู้ใช้สร้าง kallsyms ) พวกเขาทำสิ่งนี้เพื่อประหยัดพื้นที่เมื่อบีบอัดเคอร์เนลอีกครั้งโดยใช้ LZMA
ซึ่งหมายความว่ารายการ kallsyms_token_table และ kallsyms_token_address หายไปและชื่อสัญลักษณ์ใช้ข้อความธรรมดา ASCII แทน กรณีนี้รองรับเช่นกัน
ใน kernels มาตรฐาน 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 (ธันวาคม 2547) จนถึงปัจจุบัน 6.4 (ณ เดือนสิงหาคม 2566) ไม่ควรรองรับเคอร์เนลอย่างชัดเจนหากไม่มี CONFIG_KALLSYMS หากตัวแปรการกำหนดค่าเคอร์เนลนี้ไม่ได้ถูกตั้งค่าไว้ที่ Build คุณจะได้รับ: KallsymsNotFoundException: No embedded symbol table found in this kernel
สำหรับเมล็ดดิบสามารถตรวจพบสถาปัตยกรรมต่อไปนี้ได้ (โดยใช้เวทมนตร์จาก Binwalk): Mipsel, Mipseb, Armel, Armeb, PowerPC, Sparc, X86, X86-64, ARM64, 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)
อย่าลังเลที่จะเปิดปัญหาสำหรับข้อเสนอแนะการปรับปรุงใด ๆ