تسمح هذه الأداة بالحصول على ملف قابل للتحليل بالكامل من صورة kernel vmlinux/vmlinuz/bzimage/zimage (إما انقطاع ثنائي أو خام أو ملف.
لهذا ، يقوم بمسح نواةك لجدول رمز kernel (kallsyms) ، وهو جدول رمز مضغوط موجود في كل نواة تقريبًا ، معظمها دون تغيير.
نظرًا لأن جدول الرموز المعني مضغوط في الأصل ، يجب أن يستعيد الأوتار غير المرئية في الثنائي الأصلي.
ينتج ملف .elf يمكنك تحليله باستخدام 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 magic_img [حسنًا]يمكن العثور على تاريخ موجز لجدول رمز "Kallsyms" في الجزء العلوي من ملف "kallsyms_finder.py". باختصار ، تم تقديم هذا حوالي عام 2004 في kernel Linux في شكله الحالي ويستخدم لطباعة رسائل "kernel oops" ، من بين أشياء أخرى.
أنه يحتوي على tuples من "اسم الرمز" ، "عنوان الرمز" ، "نوع الرمز" (يتم تعيين أنواع الرموز مع حرف واحد بطريقة مشابهة لأداة nm ) ، هذه المعلومات معبأة بإحكام مع خوارزمية ضغط بسيطة.
يعرض المخطط أدناه كيف يتم تسلسل هذه المعلومات في kernel ، وهي إزاحة كل بنية كل منها يتم اكتشافها بواسطة 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+ kernels فقط) على تسلسل صفيف من أعداد صحيحة 3 بايت معبأة ، حيث تتطابق فهارس الصفيف مع الترتيب الأبجدي الرقمي لاسم رمز معين ، وقيم الصفيف تتطابق مع فهارس الإدخال المقابلة في kallsyms_addresses و kallsyms_names . | |
kallsyms_token_table | شظايا أو أحرف السلسلة المنتهية التي يمكن أن تكون موجودة في أسماء رمز kernel. يمكن أن يحتوي هذا على أكثر من 256 شظايا أو حرف. الفهارس المقابلة لنقاط رمز ASCII والتي يتم استخدامها فعليًا في أي رمز kernel ستتوافق مع حرف 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 ... |
هذه الحقول لها محاذاة متغيرة وحجم الحقل. قد تختلف أحجام الحقل عن الهندسة المعمارية ونسخة kernel أيضًا. لهذا السبب ، تم اختبار vmlinux-to-elf على مجموعة متنوعة من الحالات.
يحتوي OpenWrt منذ عام 2013 على رقعة تزيل الضغط على جدول kallsyms افتراضيًا (عند بناء kallsyms من قبل المستخدم). يفعلون ذلك من أجل توفير المساحة عند إعادة ضغطها فوق النواة باستخدام LZMA.
هذا يعني أن إدخالات kallsyms_token_table و kallsyms_token_address تختفي ، وأن أسماء الرموز تستخدم نصًا عاديًا بدلاً من ذلك. هذه الحالة مدعومة أيضًا.
في نواة 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+ kernels ، يتم تغيير هذا التصميم إلى:
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) ، حتى 6.4 الحالي (اعتبارًا من أغسطس 2023). لا ينبغي دعم فقط النواة التي تم تكوينها بشكل صريح دون CONFIG_KALLSYMS . إذا لم يتم تعيين متغير تكوين kernel هذا في الإنشاء ، فستحصل على: KallsymsNotFoundException: No embedded symbol table found in this kernel .
بالنسبة إلى النواة الخام ، يمكن اكتشاف البنية التالية (باستخدام السحر من Binwalk): Mipsel ، Mipseb ، Armel ، Armeb ، PowerPC ، SPARC ، X86 ، X86-64 ، ARM64 ، MIPS64 ، Superh ، Arc.
يمكن اكتشاف تنسيقات ضغط kernel التالية تلقائيًا: XZ و LZMA و GZIP و BZ2 و LZ4 و LZO و ZSTD.
يمكنك أيضًا الحصول على إخراج نص فقط من أسماء رمز Kernel وعناوين وأنواعها من خلال استخدام الأداة المساعدة 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)
لا تتردد في فتح مشكلة عن أي اقتراح بالتحسين.