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:
- Internal kennel function (see kernel parameter func)
- The local function of a process and it set using ioctl system call.
Build the module
git clone https://github.com/yairgd/disa.git cd disa make
Testing the module
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
Testing of disassembly of userspace function
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
Testing of disasbly internal kernel function
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'
Supervisor Mode Access Prevention
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