Writing a (Super Simple) Linux Module

Okay, so Today I’ll need the CR3 value given a PID. The Linux kernel does not give this information out to the userspace, so I’ll be building my own module to take care of this. The code is available on my Gitlab.

Two awesome references I’ll be using for this task:

Making the basic module

We need to the actual module that is loadable into the kernel. This can be done by using the tutorial from the first reference. The main module source code needs to have the proper headers (to call proper module MACROs), the proper calls to the macros (description, author, license), and finally actually define which functions of the module are the entry and exit points.


#include 	
#include 	
#include 	

MODULE_DESCRIPTION("Kernel module to translate given PID to CR3 physical address");
MODULE_AUTHOR("Chang Hyun Park");
MODULE_LICENSE("GPL");

static int pid2cr3_init(void)
{
  printk("%s\n", __func__);
  return 0;
}

static void pid2cr3_exit(void)
{
  printk("%s\n", __func__);
}

module_init(pid2cr3_init);
module_exit(pid2cr3_exit);

The Makefile and the Kbuild files are identical to the first reference, except the filename of the code above (pid2cr3.c, add the object as pid2cr3.o​).

The full code can be found at Gitlab here

Actually doing the intended work

Now, given a PID we want to retrieve the CR3 Value! There are a few ways to pass on the PID value to the module.

  1. Register the module to listen on a system call [here]
  2. Pass on parameters when loading the module (and dynamically change the parameter at runtime) [here]
  3. Open a pseudo-file to communicate with the module (sysfs, procfs).

We take the final approach, where we create a new sysfs directory and file which we program to act differently for reads and writes.

For a write to the file, we receive the PID from the userspace, and for the write, we return the CR3 for the priorly received PID.

The code is available here.

That’s it!

Leave a comment