
أداة لاستعادة ملف .ELF قابل للتحليل بالكامل من نواة خام، عبر استخراج جدول رموز النواة (kallsyms)
تتيح هذه الأداة الحصول على ملف .ELF قابل للتحليل الكامل من صورة نواة vmlinux/vmlinuz/bzImage/zImage (سواء كانت كتلة ثنائية خام أو ملف .ELF موجودًا مسبقًا لكنه مجرّد من الرموز)، مع استعادة رموز الدوال والمتغيرات.
للقيام بذلك، تقوم بفحص النواة بحثًا عن جدول رموز النواة (kallsyms)، وهو جدول رموز مضغوط موجود في كل نواة تقريبًا، وبشكل شبه غير معدَّل.
نظرًا لأن جدول الرموز المعنيّ مضغوط في الأصل، فإنه يستعيد سلاسل نصية غير مرئية في الملف الثنائي الأصلي.
ينتج ملف .ELF يمكنك تحليله باستخدام IDA Pro وGhidra. لذلك تُعد هذه الأداة مفيدة للهندسة العكسية للأنظمة المدمجة.
الاستخدام:
# Command line:
vmlinux-to-elf <input_kernel.bin> <output_kernel.elf>
# Command line, list symbol addresses only:
kallsyms-finder <input_kernel.bin> # If installed with uv
vmlinux-to-elf.kallsyms-finder # If installed with snap
# Command line, just decompress the kernel:
vmlinuz-decompressor <input_kernel.bin> <output_kernel.bin> # If installed with uv
vmlinux-to-elf.vmlinuz-decompressor # If installed with snap
# Graphical:
vmlinux-to-elf-gui # If installed with uv
vmlinux-to-elf.gui # If installed with snap
flatpak run re.fossplant.vmlinux-to-elf # If installed with flatpak
التثبيت:
# Install CLI+GUI with Snap (recommended on Ubuntu)
sudo snap install vmlinux-to-elf
# Install CLI+GUI with yay (recommended on Arch, Manjaro)
yay -S vmlinux-to-elf libadwaita python-gobject
# Install CLI+GUI with uv (example with Fedora)
sudo dnf install -y uv glib2-devel libadwaita-devel gtk4-devel \
gobject-introspection-devel python3-gobject-devel \
python3-devel cairo-devel @development-tools
uv tool install vmlinux-to-elf[gui]
vmlinux-to-elf-gui --install-metadata # Install .desktop file
# Install CLI with uv and GUI with Flatpak (recommended on
# distributions with libadwaita < 1.6)
sudo dnf install -y uv flatpak @development-tools
uv tool install vmlinux-to-elf
flatpak remote-add --if-not-exists flathub https://flathub.org/repo/flathub.flatpakrepo
flatpak install re.fossplant.vmlinux-to-elf
إعداد بيئة التطوير المحلية:
sudo snap install --classic astral-uv
sudo apt install git
git clone [email protected]:marin-m/vmlinux-to-elf.git
# Dependencies for the GTK-4 GUI
sudo apt install libgirepository-2.0-dev libadwaita-1-dev \
gir1.2-adw-1 gir1.2-gtk-4.0 python3-dev blueprint-compiler
cd vmlinux-to-elf
cp -a .github/hooks/* .git/hooks/
# Download Python modules and initialize virtualenv (creates ".venv",
# call "source .venv/bin/activate" to set up)
uv sync --extra gui
# Add vmlinux-to-elf to $PATH, so that the commands are callable
# system-wide (creates a symlink to the source in "~/.local/bin")
uv tool install -e .[gui]
boot.img الخاصة بأندرويد، التي تبدأ بتوقيع سحري ANDROID! أو UNCOMPRESSED_IMG [OK]يمكن العثور على نبذة تاريخية مختصرة عن جدول رموز "kallsyms" في أعلى ملف "kallsyms.py". باختصار، أُدخل هذا الجدول في نواة لينكس حوالي عام 2004 بشكله الحالي، ويُستخدم لطباعة رسائل "Kernel 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" كقيمة long إلى هذا الجدول. | 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 | أجزاء سلاسل أو أحرف تنتهي بـ Null وقد تكون موجودة في أسماء رموز النواة. يمكن أن يحتوي هذا على 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 للاختبار على مجموعة متنوعة من الحالات.