Post

Extracting Kernel Symbols from Android Boot Image

Extracting Kernel Symbols from Android Boot Image

/proc Filesystem

The /proc filesystem (also known as procfs) is a virtual filesystem in Linux. It does not contain real files on disk. Instead, it provides runtime system information about the kernel, processes, and hardware.

This filesystem is widely used for:

  • Debugging
  • System monitoring
  • Performance tuning

/proc/kallsyms

/proc/kallsyms provides the symbol table of the Linux kernel. It lists kernel symbols such as functions, variables, and other internal identifiers along with their memory addresses.

It is mainly used for:

  • Debugging
  • Kernel module development

Relevant Kernel Configuration Options:

  • CONFIG_KALLSYMS — Enables the symbol table.
  • CONFIG_KALLSYMS_ALL — Includes all symbols, even unexported ones.
  • /proc/sys/kernel/kptr_restrict — Controls the visibility of kernel addresses in /proc/kallsyms (for security/hardening).

Usage in Android Kernel Exploitation

When performing Android kernel exploitation or porting an exploit to run on another device, it is often necessary to obtain the addresses of kernel functions specific to that device. In such cases, /proc/kallsyms becomes an invaluable resource, as it provides a list of kernel symbols along with their memory addresses. This allows exploit developers to easily locate the required functions and adapt their exploits accordingly.

When working with the Android kernel, you typically start by extracting the boot image (boot.img).

Boot Image (boot.img): This is the boot partition of an Android device. It contains the kernel and the ramdisk, which are essential for booting the system. You can obtain boot.img either by extracting it from the official firmware package (factory images, OTA updates, etc.) or by dumping it directly from the device’s storage.

abootimg

It allows you to extract, modify, and repack the boot image, making it an essential tool for rooting, custom ROM development, or kernel modification.

1
sudo apt install abootimg

To extract the contents of a boot.img file, use the following command:

1
abootimg -x boot.img

This will extract the following files:

  • bootimg.cfg: Configuration file containing boot header information.
  • zImage (or Image.gz): The kernel binary.
  • initrd.img: The ramdisk (compressed filesystem).
  • second.img (if present): The second stage bootloader.

To view the header information of a boot.img file, use:

1
abootimg -i boot.img

This will display details such as:

  • Kernel size and load address.
  • Ramdisk size and load address.
  • Page size.
  • Command line parameters.

After making changes to the kernel, ramdisk, or configuration, you can repack the boot.img using:

1
abootimg --create newboot.img -f bootimg.cfg -k zImage -r initrd.img -s second.img

The ramdisk (initrd.img) is typically a compressed CPIO archive. To extract its contents:

1
mv initrd.img initrd.cpio.gz

Extract the ramdisk:

1
2
3
mkdir ramdisk
cd ramdisk
gunzip -c ../initrd.cpio.gz | cpio -i

Make changes to the ramdisk (e.g., add root scripts). Repack the ramdisk:

1
2
find . | cpio -o -H newc | gzip > ../initrd.cpio.gz
mv ../initrd.cpio.gz ../initrd.img

If you want to replace the kernel (zImage or Image.gz), simply place the new kernel binary in the same directory and repack the boot.img:

1
abootimg --create newboot.img -f bootimg.cfg -k new_kernel -r initrd.img

For newer devices that use a Device Tree Blob (DTB), you can include it when repacking the boot.img:

1
abootimg --create newboot.img -f bootimg.cfg -k zImage -r initrd.img -d dtb

bzImage is a compressed kernel image used in x86 and x86_64 architectures. It contains the kernel code, compressed using algorithms like gzip, LZMA, or others.

For Linux: extract-vmlinux Script: This script extracts the uncompressed vmlinux from bzImage.

1
2
wget https://raw.githubusercontent.com/torvalds/linux/master/scripts/extract-vmlinux
chmod +x extract-vmlinux

For Android: vmlinux-to-elf: This tool allows to obtain a fully analyzable ELF file from a vmlinux/vmlinuz/bzImage/zImage kernel image (either a raw binary blob or a preexisting but stripped ELF file), with recovered function and variable symbols.

1
2
3
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-elf

It produces an ELF file that you can analyze using IDA Pro and Ghidra. This tool is hence useful for embedded systems reverse engineering.

1
vmlinux-to-elf bzImage vmlinux

Once vmlinux is generated now you can extract kallsyms.

1
kallsyms-finder vmlinux > kallsyms
This post is licensed under CC BY 4.0 by the author.