Noyau Linux: Système d'appel d'accrochage exemple
Je suis en train d'écrire un simple code de test comme une démonstration de l'accrochage de la table des appels systèmes.
"sys_call_table" n'est plus exporté dans le noyau 2.6, je suis juste en saisissant l'adresse du Système.fichier de la carte, et je peux voir qu'il est correct (à la Recherche par le biais de la mémoire à l'adresse que j'ai trouvé, je peux voir les pointeurs pour les appels système).
Cependant, lorsque j'essaie de modifier ce tableau, le noyau donne un "Oups" avec "incapables de gérer le noyau de pagination demande à l'adresse virtuelle c061e4f4" et la machine redémarre.
C'est CentOS 5.4 exécution de la version 2.6.18-164.10.1.el5. Est-il une sorte de protection ou dois-je juste avoir un bug? Je sais qu'il vient avec SELinux, et j'ai essayé de le mettre en mode permissif, mais il ne fait pas une différence
Voici mon code:
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/moduleparam.h>
#include <linux/unistd.h>
void **sys_call_table;
asmlinkage int (*original_call) (const char*, int, int);
asmlinkage int our_sys_open(const char* file, int flags, int mode)
{
printk("A file was opened\n");
return original_call(file, flags, mode);
}
int init_module()
{
//sys_call_table address in System.map
sys_call_table = (void*)0xc061e4e0;
original_call = sys_call_table[__NR_open];
//Hook: Crashes here
sys_call_table[__NR_open] = our_sys_open;
}
void cleanup_module()
{
//Restore the original call
sys_call_table[__NR_open] = original_call;
}
LD_PRELOAD
ou ptrace
? Ne sont-ils pas répondre à ce que vous essayez de faire?Pas vraiment, le but de l'exercice est de charger un module noyau qui va accrocher un système d'appel pour l'ensemble du système. Il n'importe pas vraiment ce qu'il fait à ce point.
Veuillez noter que, pour les fins de l'enseignement, il pourrait être OK pour examiner cette question, mais il a, à la fois techniques et des problèmes de licences. Ne pas l'utiliser dans le monde réel!
ce pourrait être le cas d'utilisation de ce code? Puis-je brancher tout appel système linux de cette façon?
quoi? Soins pour étoffer un peu?
OriginalL'auteur Stephen | 2010-01-20
Vous devez vous connecter pour publier un commentaire.
J'ai enfin trouvé la réponse moi-même.
http://www.linuxforums.org/forum/linux-kernel/133982-cannot-modify-sys_call_table.html
Le noyau a été changé à un certain point, de sorte que le système d'appel de table est en lecture seule.
cypherpunk:
Le lien a aussi un exemple de modification de la mémoire à l'écriture.
nasekomoe:
Voici une version modifiée de l'original du code qui fonctionne pour moi.
+1 pour la documentation de la solution que vous étiez venu pour les autres à voir.
Notez que lorsque vous appelez set_memory_rw() et l'adresse n'est pas alignée sur, vous obtiendrez ce: AVERTISSEMENT: lors de arch/x86/mm/pageattr.c:877 change_page_attr_set_clr+0x343/0x530() (Non contaminé). Je suis en utilisant 2.6.32, toujours une solution (comme la mémoire semble être en lecture seule après que je l'appelle).
Génial réponse à votre propre question. Très détaillé. +1 fer sûr. L'homme acclamations.
Merci pour cette. J'ai appris quelque chose de nouveau 🙂
OriginalL'auteur Stephen
Merci Stephen, votre recherche ici a été utile pour moi. J'ai eu quelques problèmes, mais, comme je l'ai été d'essayer ce sur un noyau 2.6.32, et d'obtenir
WARNING: at arch/x86/mm/pageattr.c:877 change_page_attr_set_clr+0x343/0x530() (Not tainted)
suivie par un kernel OOPS de ne pas être capable d'écrire à l'adresse de la mémoire.Le commentaire ci-dessus mentionnés en ligne membres:
La suite modifié le code fonctionne:
Noter que ce n'est toujours pas la page en lecture/écriture dans certaines situations. Le
static_protections()
fonction, qui est appelé à l'intérieur deset_memory_rw()
, supprime le_PAGE_RW
drapeau si:Je ne la trouve après le débogage pourquoi j'ai toujours "incapables de gérer le noyau de la pagination à la demande" lorsque vous tentez de modifier l'adresse des fonctions du noyau. J'étais finalement capable de résoudre ce problème en trouvant la page d'entrée de la table pour l'adresse moi-même et de régler manuellement à l'écriture. Heureusement, la
lookup_address()
fonction est exportée dans la version 2.6.26+. Voici le code que j'ai écrit pour le faire:Enfin, bien que la Marque de la réponse est techniquement correct, il va de cas de problème lors de l'couru à l'intérieur de Xen. Si vous souhaitez désactiver la protection en écriture, usage de la lecture/écriture cr0 fonctions. J'macro comme ceci:
Espère que cela aide quelqu'un d'autre qui bute sur cette question.
Sur les noyaux xen, j'ai essayé, il provoque une "erreur de protection générale". Si vous remarquerez, xen définit ses propres xen_write_cr0() fonction qui n'a pas désactiver la protection en écriture, l'hyperviseur de poignées, et l'OS invité n'a pas ce genre de accès aux les registres du CPU.
Sweet! Super infos! Merci!
Corey, je vous remercie beaucoup pour le partage de vos résultats...souhaite que je pourrais upvote 100 fois plus!
pouvez-vous poster le code complet pour la référence
OriginalL'auteur Corey Henderson
Remarque que le suivant va également travailler au lieu d'utiliser change_page_attr et ne peuvent être amorties:
est un registre de contrôle. Les 16 bits page de contrôle d'application de la protection - bascule et soudainement pages "lecture seule" n'a plus d'importance. Vous pouvez le faire dans l'espace du noyau, car le code est marqué au niveau de privilège (anneau) 0. Les programmes normaux ne peuvent pas le faire eux-mêmes. Donc, fondamentalement, désactiver la protection en écriture, piétiner sur "lecture seule" de la mémoire, de la retourner sur le dos encore une fois, le tour est joué. Vous ne pouvez pas déprécier ce parce que c'est une partie de la conception de noyau, d'être monolithique, que tous les modules exécuter en ring 0.
Si vous allez faire cela, vous devez désactiver les interruptions,
cli
, avant de modifiercr0
et réactiver les interruptions,sti
, une fois que vous avez terminé. Voir vulnfactory.org/blog/2011/08/12/wp-safe-or-not pour plus de détails.La modification du
cr0
de cette façon implique agissant sur la page en cours?si vous modifiez cr0 il compte pour le cpu, donc tous les instrucitons sur le cpu lors de sa handicapés ont l'un de ces protections désactivées indépendamment de l'adresse. (en.wikipedia.org/wiki/Control_register)
OriginalL'auteur mark
Si vous faites affaire avec un noyau 3.4 et plus tard (il peut aussi travailler avec les noyaux précédents, je n'ai pas tester), je recommanderais une façon plus intelligente d'acquérir le système callы l'emplacement de la table.
Par exemple
Que c'est. Pas d'adresses, il fonctionne très bien avec chaque noyau, je l'ai testé.
De la même manière vous pouvez utiliser un pas exporté du Noyau de la fonction de votre module:
Profitez-en!
Hum, je pensais que c'était seulement possible si vous avez
KALLSYMS_ALL=yes
dans votre.config
lors de la compilation du noyau. Je ne sais pas si cela fonctionne si vous n'avez pas le symbole présent dans/proc/kallsyms
.De toutes les réponses sur Internet, seulement cela a fonctionné pour moi! La copie de l'adresse de sys_call_table à partir du Système.la carte génère une erreur de page oups dans le Noyau.
bonne réponse pour les modernes versions de noyau!
OriginalL'auteur Sebastian Mountaniol