Recent posts

Cross compiling Linux ARM kernel modules

This guide will allow you to cross-compile a loadable kernel module (LKM; a.k.a. device driver) for a ARM Linux system.

1. Target system

I will use this configuration as an example, but you can apply the same method for other environments.

  • ARMv7 (32-bit)
  • ARM qemu emulating vexpress-a9 board
  • Linux is running in qemu.

2. Download linux kernel source

Download the kernel source from

You must download the exact version which is running in the qemu.

Note that source for 3.2.0 is named linux-3.2.tar.gz, not linux-3.2.0.tar.gz.

3. Download cross compiler toolchain

Linaro’s prebuilt toolchain generally works well. Download one from

Pick a version, and choose the appropriate architecture. In our case, it would be arm-linux-gnueabihf (ARM 32-bit, linux, little endian, hard float).

There are three kinds of files: gcc-linaro-, runtime-gcc-linaro-, and sysroot-eglibc-linaro-. You only need the first one. For more info, refer to this Linaro wiki page.

For instance, go to 4.9-2017.01/arm-linux-gnueabihf/ directory and download gcc-linaro-4.9.4-2017.01-x86_64_arm-linux-gnueabihf.tar.xz.

4. Take out kernel build config

We need to build the kernel first, and then build a kernel module. But to compile a kernel, we must have the exact build configuration of the currently running Linux system. Fortunately, you can get a copy from a running system. Look at these locations:

  • /proc/config.gz
  • /boot/config
  • /boot/config-*

Copy the file out of the qemu using scp or something.

5. Build the kernel

You need auto-generated files in order to build a kernel module. Otherwise you may encounter an error message like this:

/home/ubuntu/linux-3.2/include/linux/kconfig.h:4:32: fatal error: generated/autoconf.h: No such file or directory
    #include <generated/autoconf.h>

To build a kernel with given config file,

cp <CONFIG_FILE> .config
make ARCH=arm CROSS_COMPILE=<TOOLCHAIN_DIR>/bin/arm-linux-gnueabihf- oldconfig
make ARCH=arm CROSS_COMPILE=<TOOLCHAIN_DIR>/bin/arm-linux-gnueabihf-

Complete kernel build may not be necessary because what you need is generated header files.

6. Build the module

Write a Makefile as follows:

PWD := $(shell pwd)
obj-m += hello.o

        make ARCH=arm CROSS_COMPILE=$(CROSS) -C $(KERNEL) SUBDIRS=$(PWD) modules
        make -C $(KERNEL) SUBDIRS=$(PWD) clean

And create a hello world module.

// hello.c
#include <linux/module.h>
#include <linux/kernel.h>

int init_module(void) {
    printk(KERN_INFO "Hello world.\n");
    return 0;

void cleanup_module(void) {
    printk(KERN_INFO "Goodbye world.\n");

Finally run this command.

make KERNEL=<LINUX_SOURCE_DIR> CROSS=<TOOLCHAIN_DIR>/bin/arm-linux-gnueabihf-

Then you will get hello.ko compatible with the running ARM Linux.

HITCON CTF Quals 2017 - Seccomp

ELF x64 reversing challenge.

1. The main function

It is a small program. This program hides its core logic inside the seccomp syscall filter rule, and requires us to figure out the correct syscall arguments.

The filter rules stored at 0x201020 can be easily decoded using seccomp-tools. I have used bpftools for the decoding purpose, but outputs from seccomp-tools are more human-readable.

Read more

HITCON CTF Quals 2017 - Impeccable Artifact

Linux ELF pwnable challenge.

完美無瑕 ~Impeccable Artifact~
Overwhelmingly consummate protection

제목은 우리말로 “완전무결” 정도 되겠다. PIE가 걸린 x64 ELF 바이너리와 바이너리를 주었다.

1. Sandbox

프로그램이 실행되면 우선 아래와 같은 seccomp 시스템 콜 필터가 걸린다.

Read more

Building custom kernel

Use VM when you practice, just in case.

1. Download kernel

Download from
For example,

sudo apt-get install -y wget xz-utils
tar xf linux-4.9.28.tar.xz

2. Make your modification

Patch the files, add code, … etc.

3. Config

Copy current setting.

sudo cat /boot/config-`uname -r` > .config
make olddefconfig

4. Build

make -j4
make -j4 modules

5. Install

sudo make modules_install
sudo make install

Files will be written to /boot directory.

6. Reboot

Reboot the computer. If anything goes wrong, reboot again and select original kernel.

(Optional) Change default boot kernel

See here

Codegate 2017 finals - BMP

BMP is a Windows pwnable task.


1. Reversing

This program opens a BMP image and extracts LSB of each pixel. Then they are saved as another BMP image (*_out.bmp). The image can be opened by either “File > Open” menu or command line argument.

The main logic looks like this:

Read more