Dies ist nicht möglich, da die Systemaufruftabelle (aufgerufen sys_call_table
) ein Array mit statischer Größe ist. Die Größe wird beim Kompilieren durch die Anzahl der registrierten Systemaufrufe bestimmt. Dies bedeutet, dass kein Platz für einen anderen vorhanden ist.
Sie können die Implementierung beispielsweise für die x86-Architektur in der arch/x86/kernel/syscall_64.c
Datei überprüfen , in der sie sys_call_table
definiert ist. Seine Größe ist genau __NR_syscall_max+1
. __NR_syscall_max
ist definiert arch/x86/kernel/asm-offsets_64.c
als sizeof(syscalls) - 1
(es ist die Anzahl der letzten Systemaufrufe), wobei syscall
eine Tabelle mit allen Systemaufrufen ist.
Eine mögliche Lösung besteht darin, eine vorhandene (oder veraltete, wenn Ihre Architektur eine hat, siehe sys_setaltroot
zum Beispiel) Syscall-Nummer mit Ihrer wiederzuverwenden, da dies nicht mehr Speicherplatz erfordert. Einige Architekturen haben möglicherweise auch Lücken in der Syscall-Tabelle (wie die 64-Bit-Version von x86), sodass Sie diese auch verwenden können.
Sie können diese Technik verwenden, wenn Sie einen neuen Systemaufruf entwickeln und nur einen Neustart während des Experimentierens vermeiden möchten. Sie müssen Ihren neuen Systemaufruf definieren, den vorhandenen Eintrag in der Syscall-Tabelle suchen und ihn dann von Ihrem Modul ersetzen.
Dies vom Kernelmodul aus zu tun ist nicht trivial, da der Kernel ab sys_call_table
Version 2.6 nicht in Module exportiert wird (die letzte Kernelversion, in die dieses Symbol exportiert wurde, war 2.5.41
).
Eine Möglichkeit, dies zu umgehen, besteht darin, den Kernel so zu ändern, dass das sys_call_table
Symbol in Module exportiert wird . Dazu müssen Sie die folgenden zwei Zeilen hinzufügen kernel/kallsyms.c
( tun Sie dies nicht auf Produktionsmaschinen ):
extern void *sys_call_table;
EXPORT_SYMBOL(sys_call_table);
Eine andere Technik besteht darin, die Syscall-Tabelle dynamisch zu finden. Sie iterieren über den Kernelspeicher und vergleichen jedes Wort mit einem Zeiger auf eine bekannte Systemaufruffunktion. Da Sie den Offset dieses bekannten Systemaufrufs in der Tabelle kennen, können Sie die Anfangsadresse der Tabelle berechnen.