Enable CR0 write in Linux kernel 5+

If you ever want to disable the WriteProtect (WP) bit you’ll need to read/write access to the CR0 register. The problem is that the write_cr0 function provided by the linux kernel has been tweaked to prevent this exact thing.

Here are the steps you need to follow to compile a new kernel and have the changed removed:

  • Go to https://www.kernel.org/ and download the latest stable version.
  • $ unxz -v linux-<version>.tar.xz
  • $ tar xvf linux-<version>.tar
  • $ cd linux-<version>
  • $ cp -v /boot/config-$(uname -r) .config
  • Ubuntu: $ sudo apt-get build-dep linux linux-image-$(uname -r) && apt-get install build-essential libncurses-dev flex bison openssl libssl-dev dkms libelf-dev libudev-dev libpci-dev libiberty-dev autoconf
  • CentOS: $ sudo yum groupinstall “Development Tools” && yum install ncurses-devel openssl-devel hmaccalc zlib-devel binutils-devel elfutils-libelf-devel
  • Patch the native_write_cr0 function (in arch/x86/kernel/cpu/common.c). Basically, remove everything related to cr_pinning, X86_CR0_WP, and leave only the asm volatile(“mov %0, %%cr0”: “+r” (val), “+m” (__force_order)) line.
  • $ make menuconfig
  • $ make -j$(nproc)
  • $ make modules
  • $ sudo make modules_install
  • $ sudo make install

Happy hooking syscalls 🙂

Hint: cat /proc/kallsyms | grep sys_call_table has the address you’re looking for.