2024-04-17 12:10:24 +02:00
|
|
|
/************************/
|
|
|
|
/** **/
|
|
|
|
/** PLT section **/
|
|
|
|
/** **/
|
|
|
|
/************************/
|
|
|
|
// insmod error: module PLT section(s) missing
|
|
|
|
__attribute__((section(".plt")))
|
|
|
|
char plt = 0;
|
|
|
|
|
|
|
|
__attribute__((section(".init.plt")))
|
|
|
|
char initplt = 0;
|
|
|
|
|
|
|
|
__attribute__((section(".text.ftrace_trampoline")))
|
2024-04-17 12:34:47 +02:00
|
|
|
char textftrace_trampoline = 0; // TODO: probably an overkill
|
2024-04-17 12:10:24 +02:00
|
|
|
|
|
|
|
|
|
|
|
/************************/
|
|
|
|
/** **/
|
|
|
|
/** .modinfo **/
|
|
|
|
/** **/
|
|
|
|
/************************/
|
|
|
|
// objdump -s -j .modinfo $KMODULE
|
|
|
|
#define AUTHOR "someone"
|
|
|
|
#define DESCRIPTION "Simple =^.^= kernel module"
|
|
|
|
#define NAME "bmod"
|
|
|
|
#define LICENSE "GPL"
|
|
|
|
#define VERMAGIC "4.14.186-perf-00288-g7df34d2ae6db SMP preempt mod_unload modversions aarch64"
|
|
|
|
|
|
|
|
__attribute__((section(".modinfo")))
|
|
|
|
char modinfo_strings[] =
|
|
|
|
"author=" AUTHOR "\0"
|
|
|
|
"description=" DESCRIPTION "\0"
|
|
|
|
"license=" LICENSE "\0"
|
|
|
|
"vermagic=" VERMAGIC "\0"
|
|
|
|
"name=" NAME "\0"
|
|
|
|
;
|
|
|
|
|
|
|
|
|
|
|
|
/*******************************/
|
|
|
|
/** **/
|
|
|
|
/** .gnu.linkonce.this_module **/
|
|
|
|
/** **/
|
|
|
|
/*******************************/
|
|
|
|
// 1 - section size
|
|
|
|
// objdump -h $KMODULE | grep .gnu.linkonce.this_module
|
|
|
|
// .gnu.linkonce.this_module 00000340 0000000000000000 0000000000000000 00109800 2**6
|
|
|
|
// ^^^^^^^^ section size
|
|
|
|
|
|
|
|
// 2 - section content
|
|
|
|
// objdump -s $KMODULE -j .gnu.linkonce.this_module
|
|
|
|
// Contents of section .gnu.linkonce.this_module:
|
|
|
|
// 0000 00000000 00000000 00000000 00000000 ................
|
|
|
|
// 0010 00000000 00000000 6d657400 00000000 ........met..... // <<-- NAME offset 0x18
|
|
|
|
// 0020 00000000 00000000 00000000 00000000 ................
|
|
|
|
|
|
|
|
// 3 - entry points offsets
|
|
|
|
// readelf -a $KMODULE -W
|
|
|
|
// Relocation section '.rela.gnu.linkonce.this_module' at offset 0x109b40 contains 2 entries:
|
|
|
|
// <--- Offset ---> Info Type Symbol's Value Symbol's Name + Addend
|
|
|
|
// 0000000000000150 000006c500000101 R_AARCH64_ABS64 0000000000000000 init_module + 0
|
|
|
|
// 0000000000000310 000006ee00000101 R_AARCH64_ABS64 0000000000000000 cleanup_module + 0
|
|
|
|
|
|
|
|
#define L_ONCE_SIZE 0x340
|
|
|
|
#define L_ONCE_OFFSET_NAME 0x18
|
|
|
|
#define L_ONCE_OFFSET_INIT 0x150
|
|
|
|
#define L_ONCE_OFFSET_CLEANUP 0x310
|
|
|
|
|
|
|
|
int init_module(void);
|
|
|
|
void cleanup_module(void);
|
|
|
|
|
|
|
|
__attribute__((section(".gnu.linkonce.this_module"), aligned(8)))
|
|
|
|
struct module {
|
|
|
|
char __pad0[L_ONCE_OFFSET_NAME];
|
|
|
|
char name[sizeof(NAME)];
|
|
|
|
|
|
|
|
char __pad1[L_ONCE_OFFSET_INIT - L_ONCE_OFFSET_NAME - sizeof(NAME)];
|
|
|
|
int (*init_module)(void);
|
|
|
|
|
|
|
|
char __pad2[L_ONCE_OFFSET_CLEANUP - L_ONCE_OFFSET_INIT - sizeof(void*)];
|
|
|
|
void (*cleanup_module)(void);
|
|
|
|
|
|
|
|
char __pad3[L_ONCE_SIZE - L_ONCE_OFFSET_CLEANUP - sizeof(void*)];
|
|
|
|
} __attribute__((packed))
|
|
|
|
__this_module = {
|
|
|
|
.name = NAME,
|
|
|
|
.init_module = &init_module,
|
|
|
|
.cleanup_module = &cleanup_module,
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
/*******************************/
|
|
|
|
/** **/
|
|
|
|
/** __versions **/
|
|
|
|
/** **/
|
|
|
|
/*******************************/
|
|
|
|
// objdump -s $KMODULE -j '__versions' #dump binary
|
|
|
|
// modprobe --dump-modversions $KMODULE #dump readable
|
|
|
|
|
|
|
|
char __attribute__((section("__versions"))) ____versions[] = {
|
|
|
|
/* module_layout */ // <<-- MUST BE PROVIDED
|
|
|
|
0xe8, 0xd6, 0xfc, 0x68, 0x00, 0x00, 0x00, 0x00, 0x6d, 0x6f, 0x64, 0x75, 0x6c, 0x65, 0x5f, 0x6c,
|
|
|
|
0x61, 0x79, 0x6f, 0x75, 0x74, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
|
|
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
|
|
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
|
|
|
|
|
|
|
/* printk */
|
|
|
|
0xa1, 0x58, 0x55, 0x98, 0x00, 0x00, 0x00, 0x00, 0x70, 0x72, 0x69, 0x6e, 0x74, 0x6b, 0x00, 0x00,
|
|
|
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
|
|
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
|
|
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
* The Module
|
|
|
|
*/
|
|
|
|
// load: insmod module_name.ko
|
|
|
|
// logs: dmesg | grep insmod
|
|
|
|
// unload: rmmod MODULE_NAME # from .gnu.linkonce.this_module section
|
|
|
|
|
|
|
|
int printk(const char *fmt, ...);
|
|
|
|
#define MTAG "["NAME"] "
|
|
|
|
|
|
|
|
int init_module(void) {
|
|
|
|
printk( MTAG"Hello, world!\n");
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
void cleanup_module(void) {
|
|
|
|
printk( MTAG"Goodbye, world!\n");
|
|
|
|
}
|