Linux module to disassemble code in the Linux kernel.
Published at February 18, 2020 · Last Modified at May 7, 2022 · 4 min read · Tags: linux kernel
Linux module to disassemble code in the Linux kernel.
Published at February 18, 2020 · Last Modified at May 7, 2022 · 4 min read · Tags: linux kernel
Here is a simple module to disassemble memory using a Linux kernel module. This module is integrated into this module based on Zydis. Also, there is a userspace application to demonstrate the Zydis library on a test function in user space and disassembly of the same c function at the kernel space. Also can dissemble internal c functions of the kernel like printk, kmalloc, etc.' It could download the project from here.
The module allows two interfaces from userspace:
Using kernel parameters API: This part of the module demonstrates the use of module parameters API to control the module. There is one parameter named func and it uses to select from userspace the internal function to disassemble.
Using kernel char device API (using a misc device): The purpose of this interface is to make a file behavior for the disa module using /dev/disa using file system calls open, read,ioctl, and its content is the disassembly text code of a selected function. The selected function can be one of two:
git clone https://github.com/yairgd/disa.git
cd disa
make
Run test1,test2.py are unit tests for this module and to load into the kernel use this command:
sudo insmod module/disa.ko
sudo ./test1
sudo ./test2.py
Compare between the output of test1 function that disassembles func1 (see test1.c) on userspace and in the kernel space using disa module. Here is the output of test1 in userspace:
this function named "func1" with param 123
push rbp
mov rbp, rsp
sub rsp, 0x10
mov [rbp-0x04], edi
mov eax, [rbp-0x04]
mov edx, eax
lea rsi, [0x000055EE2B1475D5]
and the same disasebly in kernel space:
push rbp
mov rbp, rsp
sub rsp, 0x10
mov [rbp-0x04], edi
mov eax, [rbp-0x04]
mov edx, eax
lea rsi, [0x000055F50A1455D5]
Both results are identical with gdb:
(gdb) x/10i func1
0x555555563aba <func1>: push %rbp
0x555555563abb <func1+1>: mov %rsp,%rbp
0x555555563abe <func1+4>: sub $0x10,%rsp
0x555555563ac2 <func1+8>: mov %edi,-0x4(%rbp)
0x555555563ac5 <func1+11>: mov -0x4(%rbp),%eax
0x555555563ac8 <func1+14>: mov %eax,%edx
0x555555563aca <func1+16>: lea 0x17b04(%rip),%rsi # 0x55555557b5d5 <__FUNCTION__.3489>
and func1 eauls to :
p/u (void*)func1
$14 = 93824992295610
and the addr parameter also equals to it:
cat /sys/module/disasm/parameters/addr
93824992295610
Use this command to get list of inernal functions that module is able to disasebmly.
sudo su -c '/sys/module/disasm/parameters/func'
Here is a pyhton code to use when its required to disasmble the code of kfree:
# select intenal function to disasembly
f = open("/sys/module/disasm/parameters/func","w");
f.write("kfree");
f.close();
# read the disasmbly data as file
f=open("/dev/disa","r");
a = f.read(256);
a = a.replace(';','\n');
print ( a);
f.close();
And the result is:
push rbp
mov rbp, rsp
push r13
push r12
mov r13, [rbp+0x08]
push rbx
mov rbx, rdi
nop
cmp rbx, 0x10
jbe 0xFFFFFFFF8117C71D
mov r10d, 0x80000000
mov rax, 0x77FF80000000
mov rdi, 0xFFFFEA0000000000
add r10, rbx
cmovb rax, [0xFFFFFFFF81E0D010]
add r10, rax
To use the module in bash command line type:
sudo cat /dev/disa | sed -e $'s/;/\\\n/g'
When the module has to disassemble the function from userspace, it has to copy the function data from the userspace to kernel space to handle the parsing of memory in the kernel space. In the previous driver versions, the kernel had direct access to userspace. However, it ran on an earlier kernel version, and it had worked. In the new versions of the kernel, it must use copy_from_user. Refer here for more info:
Intel’s new “Supervisor Mode Access Prevention” (SMAP) feature changes that situation; those wanting the details can find them starting on page 408 of >this reference manual [PDF]. This extension defines a new SMAP bit in the CR4 control register; when that bit is set, any attempt to access user-space >memory while running in a privileged mode will lead to a page fault. Linux support for this feature has been posted by H. Peter Anvin to generally >positive reviews; it could show up in the mainline as early as 3.7.
Here are some reference sources that used to create this module
[1] misc device
[2] char device
[3] example of char device
[4] misc vs char device
[5] fix camke pthread problem
[6] misc device
[7] questions about it Supervisor mode access prevention