Creating android kernel module in emulator is really painful. So here I want to show you how to create a loadable module.

My environment:
Ubuntu 18.04
Android 4.4.2
Goldfish 3.4

Most the configuration is the same with my previous post here:
http://xdshao.com/2018/04/10/Android-exploitation-Kernel-stack-buffer-overflow/
And if you read this post before you read mine, it will be a really big help.
https://abdullahyousafzaii.wordpress.com/2015/08/02/how-to-write-a-kernel-module-for-android/
But if you only follow his paper, you will fail with my environment.

I also created a video here. If you prefer to watch videos, it will be a good choice.

So before we start, there are several things we need to do.

First, go to the goldfish/arch/arm/configs/goldfish_armv7_defconfig file and add these lines at the end.

1
2
3
4
CONFIG_MODULES=y
CONFIG_MODULE_FORCE_LOAD=y
CONFIG_MODULE_UNLOAD=y
CONFIG_MODULE_FORCE_UNLOAD=y

Also, if you just add these lines and start compile the kernel, you will get a lot of errors. So you will want to delete these configurations. Simply add “#” before the line.

1
2
3
4
5
6
7
8
#CONFIG_NF_CONNTRACK_IPV6=y
#CONFIG_IP6_NF_IPTABLES=y
#CONFIG_IP6_NF_FILTER=y
#CONFIG_IP6_NF_TARGET_REJECT=y
#CONFIG_IP6_NF_TARGET_REJECT_SKERR=y
#CONFIG_IP6_NF_MANGLE=y
#CONFIG_IP6_NF_RAW=y
#CONFIG_NETFILTER_XT_MATCH_QTAGUID=y

To make it better, add this at the beginning.

1
# CONFIG_IPV6 is not set

When you finish these things, you are done with the environment. Go to the goldfish/drivers and create a directory. Let’s make it “helloworld”. To make it clear, you can create this directory anywhere you want. But here we make it in the drivers directory.
Under the “helloworld”, you need to create several files.
The first one is hello.c.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
#include <linux/init.h>
#include <linux/module.h>
MODULE_LICENSE("GPL");
MODULE_AUTHOR("Xudong Shao 2018");
MODULE_DESCRIPTION("Hello World Kernel Module for Android");

static int hello_init(void)
{
printk("Hello Kernel World....\n");
return 0;
}
static void hello_exit(void)
{
printk("Goodbye Kernel World\n");
}
module_init(hello_init);
module_exit(hello_exit);

The second one is Makefile.

1
2
3
4
5
6
obj-m   := hello.o

KERNEL_DIR = ~/Documents/kernel/goldfish

all:
make -C $(KERNEL_DIR) M=$(PWD)/ ARCH=arm CROSS_COMPILE=$(CROSS_COMPILE) modules

Then all you need to do is type “make” in the terminal in this directory. And you will get several files here. What you need is the “hello.ko”. Start the emulator now.

1
emulator -show-kernel -kernel arch/arm/boot/zImage -avd kernelEXP -no-boot-anim -no-skin -no-audio -no-window -qemu -monitor unix:/tmp/qemuSocket,server,nowait -s

Push the “hello.ko” to the /data/local/tmp. Then insert the module and remove it. You will see this.

Let’s take a look at the second one. This kind of kernel module is built into the kernel so it will get loaded when you start the kernel and no need to load it manually.

Same here. Go to the goldfish/drivers directory and create the “helloword” directory. In this case, you have to make it here because we need to change the “Kconfig” and “Makefile” under the “drivers” directory.

First, in this “helloworld” directory, create “hello.c”.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
#include <linux/init.h>
#include <linux/module.h>
MODULE_LICENSE("GPL");
MODULE_AUTHOR("Xudong Shao 2018");
MODULE_DESCRIPTION("Hello World Kernel Module for Android");

static int hello_init(void)
{
printk("Hello Kernel World....\n");
return 0;
}
static void hello_exit(void)
{
printk("Goodbye Kernel World\n");
}
module_init(hello_init);
module_exit(hello_exit);

The second one is Kconfig.

1
2
3
4
5
6
config HELLO_MOD
tristate "Hello World Module"
default y
depends on MODULES
help
This module will write Hello Kernel World to the Kernel Message Buffer

The third one is “Makefile”.

1
2
3
4
5
6
obj-y   := hello.o

KERNEL_DIR = ~/Documents/kernel/goldfish

all:
make -C $(KERNEL_DIR) M=$(PWD)/ ARCH=arm CROSS_COMPILE=$(CROSS_COMPILE) modules

Then go to the “Kconfig” under the “drivers” directory and add this:

1
source drivers/helloworld/Kconfig”

Go to the “Makefile” under the “drivers” directory and add this:

1
“obj-y    += helloworld/”

After you finish all these things, go to the goldfish directory and do this to compile the whole kernel.

1
make goldfish_armv7_defconfig && make -j8

Now you get the new kernel, start it. Check this:

The module is loaded automatically!

Finally, we make it here! To be honest, in order to figure out how to set those configuration files, it took me several days. I asked many people and it just didn’t work on my machine. So be patient and move on.