Open In App

How to extract and disassemble a Linux kernel

Last Updated : 15 Jun, 2021
Improve
Improve
Like Article
Like
Save
Share
Report

Extracting and examining the disassembled assembly code for your Linux kernel can be really helpful if you want to look for some malfunctioning piece of code or want to examine entry points for various functions. The process is fairly intuitive once you know the necessary tools that are required.

The process below is described for Ubuntu 20.04 but should work for other GNU/Linux based operating systems as well. We will be using the objdump command-line utility that comes pre-installed with all Ubuntu distributions. To check if it is installed and working, type the following on your terminal and you should see the version and license information about the program.

objdump --version

The Linux kernel executable is called vmlinuz . This is the executable file that is first loaded into the memory when we boot up our computer and this is what we will be disassembling. The file is located under /boot/ directory. It is, however, compressed. We will have to first extract it before disassembly using the extract-vmlinux script that comes with the Linux-headers.

STEP 1: Copying the compressed kernel executable to a different location :
First, we will create a copy of our kernel to a location of our choice and cd into that directory. Superuser privileges are necessary for this step.

mkdir ~/kernel-tmp
sudo cp /boot/vmlinuz-$(uname -r) ~/kernel-tmp
cd kernel-tmp

STEP 2: Extracting the kernel :
Now we will extract the compressed kernel that we have copied into our directory. we will use the extract-vmlinux script that comes with our Linux-headers.

sudo /usr/src/linux-headers-$(uname -r)/scripts/extract-vmlinux vmlinuz-$(uname -r) > decomp-vmlinuz

The above command will run the extract-vmlinux script for our copy of the kernel and output it into a file with the name decomp-vmlinuz that will be located under our current working directory.

STEP 3: Disassembly :
We are now ready to disassemble our decompressed executable. Simply run the following command

objdump -D decomp-vmlinuz > disassembled-vmlinuz.asm

The disassembled kernel code can now be found in dissassembled-vmlinuz.asm file. 

STEP 4: Finding symbols :
The disassembled kernel file has no symbols, hence we cannot find the starting point of functions very easily. Linux stores all symbol names and their starting address in a  separate file. We will copy that file as well for our ease of access.

sudo cp /boot/System.map-$(uname -r) ./

Now, we can easily grep for our symbol name in the System.map-x.x.x-xx-generic  file to get the starting address, then we can look for that address in the dissassembled-vmlinuz.asm file.
For e.g. we could grep for register_keyboard_notifier

sudo cat System.map-$(uname -r) | grep register_keyboard_notifier

which will give an output somewhat like:

ffffffff816ec720 T register_keyboard_notifier

We can copy the starting address and search for it in the disassembled kernel code to find something like this :

ffffffff816ec720:    e8 4b 13 98 ff           callq  0xffffffff8106da70
ffffffff816ec725:    55                       push   %rbp
ffffffff816ec726:    48 89 fe                 mov    %rdi,%rsi
ffffffff816ec729:    48 c7 c7 a0 f7 d8 82     mov    $0xffffffff82d8f7a0,%rdi
ffffffff816ec730:    48 89 e5                 mov    %rsp,%rbp
ffffffff816ec733:    e8 18 bb 9d ff           callq  0xffffffff810c8250
...

Like Article
Suggest improvement
Previous
Next
Share your thoughts in the comments

Similar Reads