Turn an Android ARM64 kernel (boot.img or raw Image) into a Ghidra/IDA-ready kernel.elf with symbols by:
- extracting the embedded AArch64 ELF hidden inside many vendor kernels
- running
vmlinux-to-elfon that extracted ELF (where kallsyms is actually discoverable)
This avoids the common “0 candidates for kallsyms_token_table” trap when feeding raw Image blobs directly.
Some Android kernels ship as a raw ARM64 Image containing embedded blobs (ELF chunks, cpio initramfs, etc.).
vmlinux-to-elf can fail to detect kallsyms in the raw Image, but succeeds quickly when fed the embedded ELF64 blob.
KernelKatana automates that workflow.
python3binwalkreadelf(frombinutils)file,dd
Optional (only if you want boot.img auto-unpack):
magiskboot
sudo apt update
sudo apt install -y binwalk binutils fileClone it somewhere:
git clone https://github.com/marin-m/vmlinux-to-elf.gitBy default KernelKatana looks for ./vmlinux-to-elf.
Or set:
export VMLINUX_TO_ELF_DIR=/path/to/vmlinux-to-elfchmod +x kernelkatana.sh
./kernelkatana.sh -i boot.img -o kernel.elfIf your input is already a raw kernel Image:
./kernelkatana.sh -i Image -o kernel.elfWSL speed mode (recommended when your files are under /mnt/c or /mnt/e):
./kernelkatana.sh -i /mnt/e/.../Image -o kernel.elf --prefer-homeKeep intermediate files for debugging:
./kernelkatana.sh -i boot.img -o kernel.elf --keepkernel.elf— load this in Ghidra/IDA, architecture AArch64.- If symbols look shifted, verify
_stext/_textaddresses match expected kernel base (oftenffffffc008...on Android).
If you do:
... | headPython may print BrokenPipeError because head closes the pipe early.
Redirect to a file instead:
... > kallsyms.txt