Esta pagina se ve mejor con JavaScript habilitado

Programación de módulos para el kernel de Linux

 ·  🎃 kr0m

Como ya se indicó en un artículo anterior donde compilábamos nuestro kernel, los diferentes parámetros del kernel se pueden compilar dentro del propio kernel o como módulo, el hacerlo como módulo nos dará una mayor flexibilidad ya que se puede cargar el módulo con diferentes parámetros pero por otro lado nos expone a los temidos rootkits.

En esta ocasión aprenderemos a compilar un módulo de lo mas sencillo cuya única misión es imprimir un mensaje en los logs del sistema, lo se no es gran cosa pero bastará como iniciación a la programación de módulos.

Los módulos se encuentran en un directorio determinado, /lib/modules/version/ los principales comandos utilizados para su gestión son los siguientes:

  • depmod -a: Genera el fichero /lib/modules/version/modules.dep donde se indican las dependencias de los módulos.
  • insmod: Carga un módulo sin comprobar dependencias, si existen dependencias hay que cargarlas en el orden correcto manualmente y es necesario indicarle la localización exacta del módulo
  • modprobe: Carga el módulo teniendo en cuenta las dependencias, busca en el directorio por defecto para cargar los módulos
  • rmmod: Descarga el módulo

Todo módulo consta como mínimo de dos partes:

  • init_module –> main() Se ejecuta en la carga del módulo: insmod, modprobe
  • cleanup_module –> Se ejecuta en la descarga del módulo: rmmod

En nuestro ejemplo simplemente imprimiremos mediante syslog un mensaje en la carga de módulo y otro en la descarga:

vi my_module.c

#include <linux/module.h> /* Needed by all modules */
#include <linux/kernel.h> /* Needed for KERN_INFO */

int init_module(void)
{
     printk(KERN_INFO "Hello world 1.
");
     return 0;
}

void cleanup_module(void)
{
     printk(KERN_INFO "Goodbye world 1.
");
}

Creamos un makefile para poder compilarlo:

vi Makefile

obj-m += my_module.o
all:
    make -C /lib/modules/$(shell uname -r)/build M=$(PWD) modules

clean:
    make -C /lib/modules/$(shell uname -r)/build M=$(PWD) clean

NOTA: Las tabulaciones del make son muy importantes, si se edita con Vi se puede apreciar como cambia de color al tabular

Compilamos:

make all
make -C /lib/modules/3.16.5-gentoo-Kr0m-ceph-xfs-xen/build M=/home/XXXX modules

make[1]: Entering directory '/usr/src/linux-3.16.5-gentoo'
  CC [M]  /home/XXXX/my_module.o
  Building modules, stage 2.
  MODPOST 1 modules
  CC      /home/XXXX/my_module.mod.o
  LD [M]  /home/XXXX/my_module.ko
make[1]: Leaving directory '/usr/src/linux-3.16.5-gentoo'

Ya podemos cargar el módulo pero antes dejaremos un tail en los logs del sistema para comprobar que se ha cargado con éxito:

tail -f /var/log/messages

En otro terminal cargamos el módulo:

insmod my_module.ko

lsmod|grep my_module

my_module 812 0

En la consola con el tail veremos:

Nov 18 21:46:30 localhost kernel: [981248.867904] Hello world 1.

Si lo descargamos:

rmmod my_module

En la consola con el tail veremos:

Nov 18 21:49:08 localhost kernel: [981407.803926] Goodbye world 1.

Esto puede ser un primer paso hacia la programación de nuestro propio rootkit ;)

Si te ha gustado el artículo puedes invitarme a un RedBull aquí