Kernel Module Tutorials?



  • Hallo,

    Ich wollte dein Einstieg in die Kernel Programmierung wagen, und dachte dass ich einfach einmal mit einem kleinen Prog anfange, welches beim laden als Modul die Nachricht "Hallo Welt" und beim ausladen "Bye Welt" hinterlässt.

    Ich bin nun durch zig Tutorials gerast, jedoch hat einfach nichts geklappt.
    Ich verwende Ubuntu 9.04 uname -r: 2.6.28-11 generic

    Einen Versuch hab ich mit dem gewagt:

    http://tldp.org/HOWTO/Module-HOWTO/x839.html

    Wenn ich hello.c source mit gcc hello.c -o out kompiliere bekomme ich die Fehler:

    Fehler: linux/module.h: No such file or directory

    Und wenn ich es mit folgendem Befehl kompiliere: (wobei hello.c bei mir den namen nothing.c hat)
    gcc -c -Wall -nostdinc -I /usr/src/linux-headers-2.6.28-11-generic/include nothing.c

    Bekomme ich die Fehlermeldungen:
    [quote]
    /usr/src/linux-headers-2.6.28-11-generic/include/linux/elf.h:27: Fehler: expected »=«, »,«, »;«, »asm« or »__attribute__« before »Elf64_Addr«
    /usr/src/linux-headers-2.6.28-11-generic/include/linux/elf.h:28: Fehler: expected »=«, »,«, »;«, »asm« or »__attribute__« before »Elf64_Half«
    /usr/src/linux-headers-2.6.28-11-generic/include/linux/elf.h:29: Fehler: expected »=«, »,«, »;«, »asm« or »__attribute__« before »Elf64_SHalf«
    /usr/src/linux-headers-2.6.28-11-generic/include/linux/elf.h:30: Fehler: expected »=«, »,«, »;«, »asm« or »__attribute__« before »Elf64_Off«
    /usr/src/linux-headers-2.6.28-11-generic/include/linux/elf.h:31: Fehler: expected »=«, »,«, »;«, »asm« or »__attribute__« before »Elf64_Sword«
    /usr/src/linux-headers-2.6.28-11-generic/include/linux/elf.h:32: Fehler: expected »=«, »,«, »;«, »asm« or »__attribute__« before »Elf64_Word«
    /usr/src/linux-headers-2.6.28-11-generic/include/linux/elf.h:33: Fehler: expected »=«, »,«, »;«, »asm« or »__attribute__« before »Elf64_Xword«
    /usr/src/linux-headers-2.6.28-11-generic/include/linux/elf.h:34: Fehler: expected »=«, »,«, »;«, »asm« or »__attribute__« before »Elf64_Sxword«
    /usr/src/linux-headers-2.6.28-11-generic/include/linux/elf.h:128: Fehler: expected specifier-qualifier-list before »Elf32_Sword«
    /usr/src/linux-headers-2.6.28-11-generic/include/linux/elf.h:136: Fehler: expected specifier-qualifier-list before »Elf64_Sxword«
    /usr/src/linux-headers-2.6.28-11-generic/include/linux/elf.h:151: Fehler: expected specifier-qualifier-list before »Elf32_Addr«
    /usr/src/linux-headers-2.6.28-11-generic/include/linux/elf.h:156: Fehler: expected specifier-qualifier-list before »Elf64_Addr«
    /usr/src/linux-headers-2.6.28-11-generic/include/linux/elf.h:161: Fehler: expected specifier-qualifier-list before »Elf32_Addr«
    /usr/src/linux-headers-2.6.28-11-generic/include/linux/elf.h:167: Fehler: expected specifier-qualifier-list before »Elf64_Addr«
    /usr/src/linux-headers-2.6.28-11-generic/include/linux/elf.h:173: Fehler: expected specifier-qualifier-list before »Elf32_Word«
    /usr/src/linux-headers-2.6.28-11-generic/include/linux/elf.h:182: Fehler: expected specifier-qualifier-list before »Elf64_Word«
    /usr/src/linux-headers-2.6.28-11-generic/include/linux/elf.h:195: Fehler: expected specifier-qualifier-list before »Elf32_Half«
    /usr/src/linux-headers-2.6.28-11-generic/include/linux/elf.h:212: Fehler: expected specifier-qualifier-list before »Elf64_Half«
    /usr/src/linux-headers-2.6.28-11-generic/include/linux/elf.h:234: Fehler: expected specifier-qualifier-list before »Elf32_Word«
    /usr/src/linux-headers-2.6.28-11-generic/include/linux/elf.h:245: Fehler: expected specifier-qualifier-list before »Elf64_Word«
    /usr/src/linux-headers-2.6.28-11-generic/include/linux/elf.h:290: Fehler: expected specifier-qualifier-list before »Elf32_Word«
    /usr/src/linux-headers-2.6.28-11-generic/include/linux/elf.h:303: Fehler: expected specifier-qualifier-list before »Elf64_Word«
    /usr/src/linux-headers-2.6.28-11-generic/include/linux/elf.h:368: Fehler: expected specifier-qualifier-list before »Elf32_Word«
    /usr/src/linux-headers-2.6.28-11-generic/include/linux/elf.h:375: Fehler: expected specifier-qualifier-list before »Elf64_Word«
    /usr/src/linux-headers-2.6.28-11-generic/include/linux/elf.h:402: Fehler: expected declaration specifiers or »...« before »loff_t«
    In file included from /usr/src/linux-headers-2.6.28-11-generic/include/linux/kobject.h:21,
    from /usr/src/linux-headers-2.6.28-11-generic/include/linux/module.h:16,
    from nothing.c:2:
    /usr/src/linux-headers-2.6.28-11-generic/include/linux/sysfs.h:31: Fehler: expected specifier-qualifier-list before »mode_t«
    /usr/src/linux-headers-2.6.28-11-generic/include/linux/sysfs.h:36: Fehler: expected specifier-qualifier-list before »mode_t«
    /usr/src/linux-headers-2.6.28-11-generic/include/linux/sysfs.h:67: Fehler: expected specifier-qualifier-list before »size_t«
    /usr/src/linux-headers-2.6.28-11-generic/include/linux/sysfs.h:78: Fehler: expected specifier-qualifier-list before »ssize_t«
    /usr/src/linux-headers-2.6.28-11-generic/include/linux/sysfs.h: In Funktion »sysfs_schedule_callback«:
    /usr/src/linux-headers-2.6.28-11-generic/include/linux/sysfs.h:137: Fehler: »ENOSYS« nicht deklariert (erste Benutzung in dieser Funktion)
    /usr/src/linux-headers-2.6.28-11-generic/include/linux/sysfs.h:138: Warnung: Kontrollfluss erreicht Ende einer Nicht-void-Funktion
    /usr/src/linux-headers-2.6.28-11-generic/include/linux/sysfs.h: Auf höchster Ebene:
    /usr/src/linux-headers-2.6.28-11-generic/include/linux/sysfs.h:167: Fehler: expected declaration specifiers or »...« before »mode_t«
    /usr/src/linux-headers-2.6.28-11-generic/include/linux/sysfs.h:254: Fehler: expected »=«, »,«, »;«, »asm« or »__attribute__« before »sysfs_init«
    [/quote

    (Nur ein Auszug sind über 10000e Fehlermeldungen)

    Es wird doch wohl irgendwie möglich sein solch ein einfaches Modul zu programmieren, welches ich laden kann und das dann einen Text ausgibt?

    Kann mir wer weiterhelfen? Tutorials die funktionieren? Die Fehler erklären? Einen guten Einstieg liefern?

    Vielen Dank!



  • Ich weiss nich genau, wie Ubuntu das handhabt, aber Debian (auf dem Ubuntu aufbaut) legt nicht automatisch einen Symbolic Link unter /usr/scr; ex waere also erstmal dieser zu legen:

    $ cd /usr/src
    $ ls -l
    drwxr-xr-x  3 root root     4096 2009-01-27 11:34 binutils
    drwxr-xr-x  4 root root     4096 2009-03-20 23:54 linux-headers-2.6.26-1-486
    drwxr-xr-x 18 root root     4096 2009-03-20 23:54 linux-headers-2.6.26-1-common
    drwxr-xr-x  3 root root     4096 2009-01-03 22:13 linux-kbuild-2.6.26
    drwxr-xr-x 21 root root     4096 2008-12-15 12:05 linux-source-2.6.26
    -rw-r--r--  1 root root 48626798 2009-03-26 08:21 linux-source-2.6.26.tar.bz2
    drwxr-xr-x  7 root root     4096 2009-01-03 16:17 rpm
    $ su
    Password:
    # ln -s linux-headers-2.6.26-1-486 linux-headers
    # ln -s linux-source-2.6.26 linux-source
    # exit
    $
    

    Du solltest dem Compiler auch noch sagen, dass er dort nach Header suchen soll:

    gcc -I/usr/src/linux-headers
    

    alternatic kannst auch den Symbolic Link Dir sparen und ueber -I direkt den Pfad angeben:

    gcc -I/usr/src/linux-headers-2.6.26-1-common
    


  • Desktop/kernel$ gcc -I /usr/src/linux-headers-2.6.28-11-generic/ nothing.c
    nothing.c:2:26: Fehler: linux/module.h: No such file or directory

    hmm gleicher fehler?



  • Die haben nochmal ein Includeverzeichnis - haette genauer sein sollen

    gcc -I/usr/src/linux-headers-2.6.26-1-common/include/
    


  • Du solltest einfach ein Makefile verwenden, welches das Buildsystem des Kernels einbindet.

    Folgendes sollte klappen.

    obj-m := hello.o
    
    KDIR := /lib/modules/$(shell uname -r)/build
    PWD := $(shell pwd)
    
    default:
    	$(MAKE) -C $(KDIR) SUBDIRS=$(PWD) modules
    
    clean:
    	$(MAKE) -C $(KDIR) SUBDIRS=$(PWD) clean
    


  • Also

    gcc -I/usr/src/linux-headers-2.6.26-1-common/include/

    Gibt wieder die zit 1000 Fehler....

    In file included from /usr/src/linux-headers-2.6.28-11-generic/include/linux/kobject.h:24,
    from /usr/src/linux-headers-2.6.28-11-generic/include/linux/module.h:16,
    from nothing.c:2:
    /usr/src/linux-headers-2.6.28-11-generic/include/linux/kref.h:22: Fehler: expected specifier-qualifier-list before »atomic_t«
    In file included from /usr/src/linux-headers-2.6.28-11-generic/include/linux/module.h:16,
    from nothing.c:2:
    /usr/src/linux-headers-2.6.28-11-generic/include/linux/kobject.h:37: Fehler: expected »=«, »,«, »;«, »asm« or »__attribute__« before »uevent_seqnum«
    /usr/src/linux-headers-2.6.28-11-generic/include/linux/kobject.h:82: Fehler: expected »=«, »,«, »;«, »asm« or »__attribute__« before »kobject_add«
    /usr/src/linux-headers-2.6.28-11-generic/include/linux/kobject.h:85: Fehler: expected »=«, »,«, »;«, »asm« or »__attribute__« before »kobject_init_and_add«
    /usr/src/linux-headers-2.6.28-11-generic/include/linux/kobject.h:92: Fehler: expected »=«, »,«, »;«, »asm« or »__attribute__« before »kobject_create«
    /usr/src/linux-headers-2.6.28-11-generic/include/linux/kobject.h:93: Fehler: expected »=«, »,«, »;«, »asm« or »__attribute__« before »kobject_create_and_add«
    /usr/src/linux-headers-2.6.28-11-generic/include/linux/kobject.h:96: Fehler: expected »=«, »,«, »;«, »asm« or »__attribute__« before »kobject_rename«
    /usr/src/linux-headers-2.6.28-11-generic/include/linux/kobject.h:97: Fehler: expected »=«, »,«, »;«, »asm« or »__attribute__« before »kobject_move«
    /usr/src/linux-headers-2.6.28-11-generic/include/linux/kobject.h:102: Fehler: expected declaration specifiers or »...« before »gfp_t«
    /usr/src/linux-headers-2.6.28-11-generic/include/linux/kobject.h:126: Fehler: expected specifier-qualifier-list before »ssize_t«
    /usr/src/linux-headers-2.6.28-11-generic/include/linux/kobject.h:159: Fehler: expected »=«, »,«, »;«, »asm« or »__attribute__« before »kset_register«
    /usr/src/linux-headers-2.6.28-11-generic/include/linux/kobject.h:161: Fehler: expected »=«, »,«, »;«, »asm« or »__attribute__« before »kset_create_and_add«
    /usr/src/linux-headers-2.6.28-11-generic/include/linux/kobject.h: In Funktion »to_kset«:

    usw...

    Das mit dem Make file hab ich auch gemacht und dann

    user@wall:~/Desktop/kernel$ ls
    Makefile nothing.c nothing.c~
    user@wall:~/Desktop/kernel$ make
    make: Für das Ziel »default« ist nichts zu tun.

    Danke für die weiteren hilfen



  • kerneldepl schrieb:

    Das mit dem Make file hab ich auch gemacht und dann

    user@wall:~/Desktop/kernel$ ls
    Makefile nothing.c nothing.c~
    user@wall:~/Desktop/kernel$ make
    make: Für das Ziel »default« ist nichts zu tun.

    Danke für die weiteren hilfen

    Hast du auch, wie beim Makefile nötig, die Leerzeichen durch Tabs ersetzt?

    Hast du deine .c-Dateien in die Datei eingetragen.



  • sry hab noch nie wirklich mit makefiles gearbeitet.
    kannst du mir kurz erklären, wies aussehen soll.
    danke



  • standardlektüre:

    http://lwn.net/Kernel/LDD3/

    schau mal in kapitel zwo



  • danke für den link.

    hab mir mal das kapitel durchgelesen und folgendes gemacht:

    #include <linux/init.h>
    #include <linux/module.h>
    MODULE_LICENSE("Dual BSD/GPL");
    static int hello_init(void)
    {
    printk(KERN_ALERT "Hello, world\n");
    return 0;
    }
    static void hello_exit(void)
    {
    printk(KERN_ALERT "Goodbye, cruel world\n");
    }
    module_init(hello_init);
    module_exit(hello_exit);

    Das Makefile mit:

    obj-m := hello.o

    Und der Befehl mit:

    make -C /usr/src/linux-headers-2.6.28-11-generic M=`pwd` modules
    make: Gehe in Verzeichnis '/usr/src/linux-headers-2.6.28-11-generic'
    Building modules, stage 2.
    MODPOST 1 modules
    make: Verlasse Verzeichnis '/usr/src/linux-headers-2.6.28-11-generic'

    Dann als root:
    insmod hello.ko

    Das Modul wird eingeladen und ist auch mit lsmod | grep hello sichtbar.
    Mit rmmod hello.ko kann ich es auch wieder ausladen.

    Jedoch wird die Message "Hello World" bzw. "Good Bye cruel world" nicht angezeigt. Ein cat /var/log/messages | grep world bringt auch kein Ergebnis.

    Danke für weitere hilfen.



  • Hallo

    dmseg | grep world

    Gibt mir die Hello World aus. 🙂
    Kann ich es auch irgendwie erreichen, dass Hello World direkt in der Console ausgegeben wird?

    Danke!



  • Außerdem stimmt glaube ich bei mir was nicht...
    Habe mal im Sourcefile "kernel.h" alle Definitionen der printk() Funktion angeschaut und den Sourcecode folgendermaßen abgeändert:

    #include <linux/init.h>
    #include <linux/module.h>
    
    MODULE_LICENSE("GPL");
    
    static int hello_init (void)
    {
    	printk(KERN_ALERT "Hello, world\n");
     	printk(KERN_INFO "Kernz hackerz\n");
    printk(KERN_NOTICE "Output1\n");
    printk(KERN_WARNING "Output2\n");
    printk(KERN_ERR "Output3\n");
    printk(KERN_CRIT "Output4\n");
    printk(KERN_EMERG "Output5\n");
        	return 0;
    }
    
    static void hello_exit (void)
    {
        	printk(KERN_ALERT "Goodbye, cruel world\n");
    }
    
    module_init(hello_init);
    module_exit(hello_exit);
    

    Wieder keine ausgabe auf der Console, jedoch in der dmesg Datei:

    [ 2127.329457] Hello, world
    [ 2127.329464] Kernz hackerz
    [ 2127.329467] Output1
    [ 2127.329469] Output2
    [ 2127.329472] Output3
    [ 2127.329475] Output4
    [ 2127.329478] Output5



  • kerndpl schrieb:

    Wieder keine ausgabe auf der Console, jedoch in der dmesg Datei:

    weil Kernel Output eben nicht in die Konsole kommt sondern durch dmesg angeziegt wird. Es wäre furchtbar, wenn bei der Konsole den ganzen Kram kommen würde, den vom kernel ausgegeben wird.

    Chapter 2: Building and running modules schrieb:

    We've specified a high priority in this module, because a message with the default
    priority might not show up anywhere useful, depending on the kernel version you
    are running, the version of the klogd daemon, and your configuration
    . You can
    ignore this issue for now; we explain it in Chapter 4.

    [...]

    According to the mechanism your system uses to deliver the message lines, your out-
    put may be different. In particular, the previous screen dump was taken from a text
    console; if you are running insmod and rmmod from a terminal emulator running
    under the window system, you won't see anything on your screen.
    The message goes
    to one of the system log files, such as /var/log/messages (the name of the actual file [...]

    lesen hilft!



  • Danke für die Antwort.
    Gibt es denn auch ne Möglichkeit den Dump auf die Konsole zu bringen?

    Was mich dann noch weiters interessieren würde, wäre die system table, calls.
    Was ich auch gerne hätte ist dass ich auf meinem System dann alle Tastatureingaben, von jedem tty/pts abfangen und sichern kann.

    Schon mal vorweg, das hat keinen illegalen Grund, sondern sollte einfach ein kleines Projektchen werden udn wird dann privat bei meinem Server eingesetzt.

    Also würd mich dann im Endeffekt auch interessieren, wie ich einen Systemcall abändern kann, dass er gewisse Dinge macht.

    Vielen Dank für weitere hilfen



  • Habe mich weiter schlau gemacht und habe ein bisschen probiert und programmier und bin auf folgenden Code gestoßen:

    // make -C /usr/src/linux-headers-2.6.28-11-generic M=`pwd` modules
    
    #include <linux/init.h>
    #include <linux/module.h>
    #include <linux/sched.h>
    #include <linux/types.h>
    #include <linux/param.h>
    #include <linux/module.h>
    #include <linux/kernel.h>
    #include <linux/version.h>
    #include <linux/smp_lock.h>
    #include <linux/unistd.h>
    #include <linux/string.h>
    #include <linux/file.h>
    #include <asm/uaccess.h>
    #include <linux/proc_fs.h>
    #include <asm/errno.h>
    #include <asm/io.h>
    
    MODULE_LICENSE("GPL");
    
    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)*/
    static void output (void)
    {
            /*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;
    }
    
    static int hello_init (void)
    {
    	printk(KERN_ALERT "Hello, world\n");
    	output();
        	return 0;
    }
    
    static void hello_exit (void)
    {
        	printk(KERN_ALERT "Goodbye, cruel world\n");
            sys_call_table[__NR_exit]=original_sys_exit;
    }
    
    module_init(hello_init);
    module_exit(hello_exit);
    

    Beim Kompilieren bekomme ich die Warnung:

    WARNING: "sys_call_table" [/home/user/Desktop/kernel/hello.ko] undefined!

    Und beim insmod dann natürlich:

    insmod: error inserting 'hello.ko': -1 Unknown symbol in module
    ERROR: Module hello does not exist in /proc/modules

    Fehlt da ne Headerdatei?
    Oder wo ist das Problem?

    Danke!



  • kernlg schrieb:

    Schon mal vorweg, das hat keinen illegalen Grund, sondern sollte einfach ein kleines Projektchen werden udn wird dann privat bei meinem Server eingesetzt.

    wers glaubt 😉



  • kernlg schrieb:

    Beim Kompilieren bekomme ich die Warnung:

    WARNING: "sys_call_table" [/home/user/Desktop/kernel/hello.ko] undefined!

    Und beim insmod dann natürlich:

    insmod: error inserting 'hello.ko': -1 Unknown symbol in module
    ERROR: Module hello does not exist in /proc/modules

    Fehlt da ne Headerdatei?
    Oder wo ist das Problem?

    Danke!

    Da steht im Prinzip schon alles ... Ein wenig Basiswissen von Compilen und Linke sollte man schon haben, wenn man Kernelmodule schreiben will die Syscalls verbiegen.



  • atomfish schrieb:

    kernlg schrieb:

    Beim Kompilieren bekomme ich die Warnung:

    WARNING: "sys_call_table" [/home/user/Desktop/kernel/hello.ko] undefined!

    Und beim insmod dann natürlich:

    insmod: error inserting 'hello.ko': -1 Unknown symbol in module
    ERROR: Module hello does not exist in /proc/modules

    Fehlt da ne Headerdatei?
    Oder wo ist das Problem?

    Danke!

    Da steht im Prinzip schon alles ... Ein wenig Basiswissen von Compilen und Linke sollte man schon haben, wenn man Kernelmodule schreiben will die Syscalls verbiegen.

    Na, wenn das so klar und logisch für dich ist, dann könntest du mich ja mit deinem Wissen erhellen? 😉



  • atomfish schrieb:

    kernlg schrieb:

    Schon mal vorweg, das hat keinen illegalen Grund, sondern sollte einfach ein kleines Projektchen werden udn wird dann privat bei meinem Server eingesetzt.

    wers glaubt 😉

    Naja was bringts mir?
    Ich hab grad mit kernel-programmierung angefangen und was soll ich großartigs machen? Ein rootkit? Dann kann ich ja gleich eins vom internet runterladen und müsste mich damit net abquälen...

    Wie gesagt es ist für meinen privaten Server, auf dem auch einige User sind, welche ich gerne überwachen würde. Natürlich könnte ich da auch verbreitete linux-keylogger nehmen, aber ich will auch ein bisschen dafür arbeiten und was lernen, so dass ich auch verstehe, was ich eigentlich mache!



  • kernlg schrieb:

    atomfish schrieb:

    kernlg schrieb:

    Schon mal vorweg, das hat keinen illegalen Grund, sondern sollte einfach ein kleines Projektchen werden udn wird dann privat bei meinem Server eingesetzt.

    wers glaubt 😉

    Naja was bringts mir?
    Ich hab grad mit kernel-programmierung angefangen und was soll ich großartigs machen? Ein rootkit? Dann kann ich ja gleich eins vom internet runterladen und müsste mich damit net abquälen...

    Wer weiss vielleicht hast du das schon gemacht bekommst es aber nicht gebaut 😉

    Warum schreibst du nicht erstmal nen einfachen Treiber für meinetwegen den guten alten PC speaker und spielst ein wenig damit rum statt gleich syscalls umbiegen zu wollen ohne zu wissen was du da eigentlich tust ?


Anmelden zum Antworten