Programmation de module kernel chargeable et interception d’appels système

Supposons que nous voulions intercepter l’appel système de sortie et imprimer un message sur la console lorsqu’un processus l’invoque. Pour ce faire, nous devons écrire notre propre appel système de sortie factice, puis faire en sorte que le kernel appelle notre fonction de sortie factice au lieu de l’appel de sortie d’origine. À la fin de notre faux appel de sortie, nous pouvons appeler l’appel de sortie d’origine. Pour ce faire, nous devons manipuler le tableau de table d’appels système (sys_call_table). Armés du tableau sys_call_table, nous pouvons le manipuler pour que le point d’entrée sys_exit soit pointé vers notre nouvel appel de sortie factice. Nous devons stocker un pointeur sur l’appel sys_exit d’origine et l’appeler lorsque nous aurons fini d’imprimer notre message sur la console. Code source :

#include  #include  #include  extern void *sys_call_table[]; asmlinkage int (*original_sys_exit)(int); asmlinkage int our_fake_exit_function(int error_code) { /*print message on console every time we *are called*/ printk("HEY! sys_exit called with error_code=%d\n",error_code); /*call the original sys_exit*/ return original_sys_exit(error_code); } /*this function is called when the module is *loaded (initialization)*/ int init_module() { /*store reference to the original sys_exit*/ original_sys_exit=sys_call_table[__NR_exit]; /*manipulate sys_call_table to call our *fake exit function instead *of sys_exit*/ sys_call_table[__NR_exit]=our_fake_exit_function; } /*this function is called when the module is *unloaded*/ void cleanup_module() { /*make __NR_exit point to the original *sys_exit when our module *is unloaded*/ sys_call_table[__NR_exit]=original_sys_exit; } 

Lorsque je comstack ce programme, je reçois un avertissement:

AVERTISSEMENT: “sys_call_table” [/home/roiht/driver/one.ko] undefined!

En effectuant une recherche, j’ai constaté que la version du kernel après la version 2.5 avait modifié le concept de la table sys_call. Ma question est donc quelle est la méthode alternative pour le faire dans la nouvelle version du kernel?

Toute variable de kernel peut être utilisée dans un module si elle a été explicitement exscope dans le kernel à l’aide de EXPORT_SYMBOL (). Depuis la version 2.6 du kernel, l’exportation de sys_call_table a été supprimée. Donc, si vous souhaitez utiliser cette approche, exportez explicitement la variable. Comme convention, l’exportation est faite juste après la déclaration de la variable, mais j’imagine que l’exportation depuis n’importe quel fichier où cette variable est définie fera également l’affaire. Pour vérifier si l’approche a fonctionné, il suffit de regarder dans le résultat de “cat / proc / kallsyms”.

Une autre approche pour capturer l’appel de sortie consistera à mettre un point d’ancrage dans la partie sysenter de l’exécution de l’appel système. Regardez ici pour plus de détails: http://articles.manugarg.com/systemcallinlinux2_6.html

Vous pouvez lire l’adresse de sys_call_table partir du System.map-xxx sys_call_table System.map-xxx correspondant à votre kernel. Le fichier se trouve généralement dans le répertoire / boot et porte le nom System.map- , où kernel-version est le résultat de la commande uname -r Vous pouvez utiliser le paramètre module pour transmettre l’adresse à votre module.