• Willkommen im Linux Club - dem deutschsprachigen Supportforum für GNU/Linux. Registriere dich kostenlos, um alle Inhalte zu sehen und Fragen zu stellen.

Kernelmodul, Systemcall aus dem Kernelspace

sim186

Newbie
hallo liebes Forum,

ich hoffe Ihr könnt mir helfen.

und zwar "biege" ich einen Systemcall um (Execve). Ich möchte, dass meine eigene execve Systemcall (es passiert nichts) und der originalle execve abwechselnd aufgerufen werden.

Klingt erstmal kompliziert, die Grundidee die da hinter steckt ist folgende. Wenn ein Prozess gestartet wird (durch execve), soll das durch mein Kernelmodul verhindert werden. Beim zweiten Aufruf soll es aber wieder klappen.

So, an sich klappt das umbiegen. D.h. also dass wenn Prozess gestartet werden soll, dann wird das verhindert (mein execve wird aufgerufen. Beim zweiten mal wird dann wieder origninal execve aufgerufen. Das klappt! Nur nach dem originallen Aufruf, kommt man nicht zurück in das Modul. Ab da an, läuft execve wieder "normal".

Hier erstmal der Code (teil):
Code:
asmlinkage int our_sys_execve(const char *ufilename,
 		              const char *const *uargv,
                              const char *const *uenvp,
                              struct pt_regs *regs)
{
   printk("A file was executed %s, count=%d\n", ufilename,count);
   count++;
   if (count%2==0){
        printk("Original execve, count = %d fn=%s\n",count,ufilename);
        disable_page_protection();
        sys_call_table[__NR_execve] = original_call_execve;
        enable_page_protection();
        original_call_execve(ufilename, uargv, uenvp, regs);
        printk("Hier kommen wir leider nicht hin :-(\n");
   }
    disable_page_protection();
    sys_call_table[__NR_execve] = our_sys_execve;
    enable_page_protection();
    return original_call_execve(ufilename, uargv, uenvp, regs);
}


int init_module()
{
    // sys_call_table address in System.map
    sys_call_table = (void*)0xffffffff8154e380;
    //original_call = sys_call_table[__NR_open];  __NR_execve
    original_call_execve = sys_call_table[__NR_execve];
    printk("Orginal table %p\n", sys_call_table[__NR_execve]);
    //set_page_rw(sys_call_table);
    disable_page_protection();
    //sys_call_table[__NR_open] = our_sys_open;
    sys_call_table[__NR_execve] = our_sys_execve;
    //set_page_ro(sys_call_table);
    enable_page_protection();
    printk("Function pointer:  %p\n", our_sys_execve);
    printk("Changed: table %p\n", sys_call_table[__NR_execve]);
    printk("System initalized!\n");
    return 0;
}

Im init_module() wird also die Adresse der originalen execve gesichter und dann der Syscalltable die unserer Funktion zugeordnet. In unserer Funktion our_sys_execve() wird dann beim zweiten mal der originale execve wieder aufgerunfe. DAnn ist aber Schluss :(

Ich hoffe jemand hier zu finden, der mir einen guten Tipp geben könnte.

Vielen, vielen Dank schonmal im Voraus :))
 

spoensche

Moderator
Teammitglied
sim186 schrieb:
Klingt erstmal kompliziert, die Grundidee die da hinter steckt ist folgende. Wenn ein Prozess gestartet wird (durch execve), soll das durch mein Kernelmodul verhindert werden. Beim zweiten Aufruf soll es aber wieder klappen.

Was soll das den für einen Sinn haben?? Dir ist klar, dass execve die Stackpotection schwächen kann?

sim186 schrieb:
So, an sich klappt das umbiegen. D.h. also dass wenn Prozess gestartet werden soll, dann wird das verhindert (mein execve wird aufgerufen. Beim zweiten mal wird dann wieder origninal execve aufgerufen. Das klappt! Nur nach dem originallen Aufruf, kommt man nicht zurück in das Modul. Ab da an, läuft execve wieder "normal".

Warum kommt man wohl nicht zurück ins Modul, wenn der Prozess läuft? Weil es ein Subprocess ist, der entweder vom Elternprozess beendet oder abnormal per SIGKILL abgeschossen wird.
 
OP
S

sim186

Newbie
was nicht gleich ist mit Deinem Wert (ich hoffe ich mache mich nicht lächerlich :D )

ja, weil sie abhängig ist vom System. Ich habe 64 bit, daher ist sie auch lägner ;)



Was soll das den für einen Sinn haben?? Dir ist klar, dass execve die Stackpotection schwächen kann?

Ein Prozess soll nur mit einer gewissen Wahrscheinlichkeit bzw. jeder zweiter Prozess soll nur gestartet werden. Mit der stackprotection kann vernachlässigt werden bzw. sagt mir das jetzt auch nicht wirklich was.


Warum kommt man wohl nicht zurück ins Modul, wenn der Prozess läuft? Weil es ein Subprocess ist, der entweder vom Elternprozess beendet oder abnormal per SIGKILL abgeschossen wird.

Das ergibt Sinn!! Allerdings, wenn man den Prozess beendet, kommen wir auch nicht wieder zurück.


Anderer Ansatz. Den Prozess killen. Aber da muss ich irgendwie indentifizieren, ob ein Prozess gestartet wurde, sprich dass execve aufgerufen wurde.
 

RME

Advanced Hacker
sim186 schrieb:
ja, weil sie abhängig ist vom System. Ich habe 64 bit, daher ist sie auch lägner
Dein Wert:
Code:
0xffffffff8154e380;
Der von mir gepostete Wert:
Code:
0xffffffff818571a0;
Sehen gleich lang aus :???:
 
OP
S

sim186

Newbie
ich dachte das wäre die Dokumenation, die ich genutzt habe. Dann ist sie auch von anderen Einflüssen abhängig. Also die Adresse ist schon richtg ;)

Gruß
 

spoensche

Moderator
Teammitglied
sim186 schrieb:
Ein Prozess soll nur mit einer gewissen Wahrscheinlichkeit bzw. jeder zweiter Prozess soll nur gestartet werden. Mit der stackprotection kann vernachlässigt werden bzw. sagt mir das jetzt auch nicht wirklich was.

Wieso soll nur jeder zweite Prozess gestartet werden? Ein Prozess wird nicht ohne Grund gestartet.

Nur weil dir Stackprotection nichts sagt kann sie noch lange nicht vernachlässigt werden. Stackprotection ist ein Schutz vor Bufferoverflows mit der damit verbunden Codeinjection.

sim186 schrieb:
Allerdings, wenn man den Prozess beendet, kommen wir auch nicht wieder zurück. Den Prozess killen. Aber da muss ich irgendwie indentifizieren, ob ein Prozess gestartet wurde, sprich dass execve aufgerufen wurde.

Prozesse können nicht nur durch execve gestartet werden. Die laufenden Prozesse kannst du dir mit
Code:
ps
ansehen.
 
OP
S

sim186

Newbie
Wieso soll nur jeder zweite Prozess gestartet werden? Ein Prozess wird nicht ohne Grund gestartet.

Das ist ja auch gar nicht die Frage. Ich habe auch meinen Grund ein solches Kernelmodul implementieren zu wollen.

Danke, wie ich mir laufende Prozesse aus dem Userspace ansehen kann, ist mir schon seit längerem klar.

Also ich habe das Problem gelöst. Und zwar ist es ja gar nicht notwendig den Call zurückzubiegen. Daher biege ich execve auf das Modul um, rufe die originale aus (wenn Prozess gestartet werden soll), unabhängig von der Sys_Call_table und gebe einfach 0 zurück, wenn kein Prozess zu stande kommen soll.
 

spoensche

Moderator
Teammitglied
Wenn das Thema für dich gelöst ist, dann setze den Thread bitte noch auf gelöst. Dazu den ersten Beitrag editieren und ein [gelöst] im Titel einfügen.
 
Oben