Differences

This shows you the differences between two versions of the page.

Link to this comparison view

so2:laboratoare:lab02:exercitii [2018/02/28 09:13]
ionel.ghita [0. [0.5p] Intro]
so2:laboratoare:lab02:exercitii [2019/02/25 15:18] (current)
ionel.ghita [Extra]
Line 154: Line 154:
 Urmați pașii de mai sus pentru a compila și copia modulele pe mașina virtuală, apoi testați modulul ''​hello_mod.ko''​ din directorul ''/​home/​root/​skels/​kernel_modules/​1-2-test-mod''​. Urmați pașii de mai sus pentru a compila și copia modulele pe mașina virtuală, apoi testați modulul ''​hello_mod.ko''​ din directorul ''/​home/​root/​skels/​kernel_modules/​1-2-test-mod''​.
  
-Apoi urmați pașii uzuali în foosirea ​unui modul de kernel:+Apoi urmați ​**pașii uzuali** în folosirea ​unui modul de kernel:
   - Încărcați modulul în kernel.   - Încărcați modulul în kernel.
   - Listați modulele din kernel și verificați existența modulului curent.   - Listați modulele din kernel și verificați existența modulului curent.
Line 253: Line 253:
  
 Repetați apoi operația de încărcare/​descărcare. Observați că diferă PID-urile proceselor afișate. Acest lucru se întâmplă pentru că la încărcarea modulului se creează un proces pornind de la executabilul ''/​sbin/​insmod''​ iar la descărcarea modulului se creează un proces pornind de la executabilul ''/​sbin/​rmmod''​. Procesele vor fi diferite. Repetați apoi operația de încărcare/​descărcare. Observați că diferă PID-urile proceselor afișate. Acest lucru se întâmplă pentru că la încărcarea modulului se creează un proces pornind de la executabilul ''/​sbin/​insmod''​ iar la descărcarea modulului se creează un proces pornind de la executabilul ''/​sbin/​rmmod''​. Procesele vor fi diferite.
-==== 8. [2.5p] Kprobes ==== 
  
-**[0.5p]** Intrați în directorul ''​8-kprobes/''​ din arhiva de resurse a laboratorului. Urmăriți fișierul sursă ''​kprobes.c''​. Modulul folosește ''​jprobes''​ pentru a urmări apelul ''​do_execve_common'',​ aferent apelului de sistem [[http://​man7.org/​linux/​man-pages/​man3/​exec.3.html|exec]]. +==== Extra ====
- +
-Compilați și încărcați în mașina virtuală modulul de kernel rezultat (''​kprobes.c''​). Urmăriți mesajele de debug și comparați cu procesele existente în sistem. +
- +
-<​note>​ +
-Este chiar exmplul din laborator din secțiunea [[:​so2:​laboratoare:​lab02#​Kprobes|Kprobes]]. +
-</​note>​ +
- +
-**[2p]** Creați un modul care analizează valoarea de retur a funcției [[http://​lxr.free-electrons.com/​source/​kernel/​fork.c?​v=4.9#​L1904|_do_fork]]. La întoarcerea din funcție, afișați valoarea de retur, numele și pid-ul procesului părinte și pid-ul procesului curent. +
- +
-<note tip> +
-Revedeți secțiunea [[:​so2:​laboratoare:​lab02#​Kprobes|Kretprobes]]. +
- +
-Puteți urmări și exemplul de cod din sursele nucleului din [[https://​git.kernel.org/​cgit/​linux/​kernel/​git/​torvalds/​linux.git/​tree/​samples/​kprobes/​kretprobe_example.c?​h=v3.13|samples/​kprobes/​kretprobe_example.c]]. +
-</​note>​ +
- +
-<note tip> +
-Urmăriți comentariile marcate cu ''​TODO''​ din cadrul fișierului cod sursă ''​kprobes.c''​. +
-</​note>​ +
- +
-<note tip> +
-Pentru a afișa adresa de retur în handler-ul de ''​kretprobe''​ (adică în funcțion ''​my_ret_handler''​) folosiți funcția [[http://​lxr.free-electrons.com/​source/​arch/​x86/​include/​asm/​ptrace.h?​v=3.13#​L82|regs_return_value]]. +
-</​note>​ +
- +
-<note tip> +
-Pentru a obține structura de tip ''​struct task_struct *''​ aferentă procesului părinte al procesului curent folosiți construcția ''​%%current->​parent%%''​. +
-</​note>​ +
- +
-<​note>​ +
-Procesul interceptat de ''​kretprobe''​ este shell-ul. În mașina virtuală procesul său părinte este procesul ''​init''/''​busybox''​ (cu PID-ul ''​1''​). Valoarea întoarsă de apelul [[http://​lxr.free-electrons.com/​source/​kernel/​fork.c?​v=4.9#​L1904|_do_fork]] afișată în cadrul handler-ului ''​kretprobe''​ este PID-ul procesului copil proaspăt creat, așa cum se întâmplă și în user space în cazul apelului [[http://​man7.org/​linux/​man-pages/​man2/​fork.2.html|fork]] pentru procesul părinte.  +
-</​note>​ +
- +
-Puteți folosi comanda ''​pstree -p''​ pentru a afișa ierarhia de procese a sistemului și pentru a verifica astfel, informațiile afișate de handler-ul de ''​kretprobe''​ în modulul de kernel. Puteți, deasemenea, confirma acest lucru verificând pid-ul procesului din proba anterioară ( ''​do_execveat_common''​). +
-==== Extra: Pentru acasă ​====+
  
 **1. [1KP] KDB** **1. [1KP] KDB**
  
-Intrați în directorul ''​9-kdb/''​. Activați KDB peste serială și intrați în modul KDB folosind SysRq.+Intrați în directorul ''​8-kdb/''​. Activați KDB peste serială și intrați în modul KDB folosind SysRq.
  
 Conectați-vă la pseudo-terminalul conectat la virtiocon0 folosind minicom, configurați KDB pentru a folosi portul serial hvc0 (''​echo hvc0 > /​sys/​module/​kgdboc/​parameters/​kgdboc''​) și activați-l folosind SysRq (Ctrl+O g). Analizați starea curentă a sistemului (''​help''​ pentru a vedea comenzile KDB disponibile). Continuați execuția kernelului folosind comand ''​go''​. Conectați-vă la pseudo-terminalul conectat la virtiocon0 folosind minicom, configurați KDB pentru a folosi portul serial hvc0 (''​echo hvc0 > /​sys/​module/​kgdboc/​parameters/​kgdboc''​) și activați-l folosind SysRq (Ctrl+O g). Analizați starea curentă a sistemului (''​help''​ pentru a vedea comenzile KDB disponibile). Continuați execuția kernelului folosind comand ''​go''​.
Line 301: Line 267:
 Analizați stacktrace-ul și determinați codul care a generat bugul. Cum putem afla din KDB adresa la care a fost încărcat modulul? Analizați stacktrace-ul și determinați codul care a generat bugul. Cum putem afla din KDB adresa la care a fost încărcat modulul?
  
-În paralel, folosiți GDB într-o nouă fereastră pentru a vizualiza codul pornind de la informațiile din KDB. ** Hint: ** Încărcați fișierul de simboluri. Folosiți ''​info line''​. ​+În paralel, folosiți GDB într-o nouă fereastră pentru a vizualiza codul pornind de la informațiile din KDB. 
 +** Hint: ** Încărcați fișierul de simboluri. Folosiți ''​info line''​. ​
  
 La scrierea în fișierul ''/​proc/​hello_kdb_break'',​ modulul va incrementa variabila ''​kdb_write_address''​. Intrați în KDB și setați un breakpoint pentru fiecare acces de scriere al variabilei ''​kdb_write_address''​. Reveniți în kernel pentru a declanșa o scriere folosind: <code bash> echo 1 > /​proc/​hello_kdb_break </​code>​ La scrierea în fișierul ''/​proc/​hello_kdb_break'',​ modulul va incrementa variabila ''​kdb_write_address''​. Intrați în KDB și setați un breakpoint pentru fiecare acces de scriere al variabilei ''​kdb_write_address''​. Reveniți în kernel pentru a declanșa o scriere folosind: <code bash> echo 1 > /​proc/​hello_kdb_break </​code>​
Line 324: Line 291:
 Porniți de la un modul existent. Porniți de la un modul existent.
  
-Investigați structura [[http://lxr.free-electrons.com/​source/​include/​linux/​sched.h?v=3.13#L1042|struct task_struct]],​ structura [[http://lxr.free-electrons.com/​source/​include/​linux/​mm_types.h?v=3.13#L344|struct mm_struct]] și structura [[http://lxr.free-electrons.com/​source/​include/​linux/​mm_types.h?v=3.13#L240|struct vm_area_struct]]. O zonă de memorie este indicată de o structură de tipul +Investigați structura [[https://elixir.bootlin.com/​linux/​v4.15.7/​source/​include/​linux/​sched.h#​L520|struct task_struct]],​ structura [[https://elixir.bootlin.com/​linux/​v4.15.7/​source/​include/​linux/​mm_types.h#​L356|struct mm_struct]] și structura [[https://elixir.bootlin.com/​linux/​v4.15.7/​source/​include/​linux/​mm_types.h#​L274|struct vm_area_struct]]. O zonă de memorie este indicată de o structură de tipul [[https://​elixir.bootlin.com/​linux/​v4.15.7/​source/​include/​linux/​mm_types.h#​L274|struct vm_area_struct]].
  
 Să includeți header-ele în care sunt definite structurile necesare. Să includeți header-ele în care sunt definite structurile necesare.
Line 331: Line 298:
 **4. [2KP] Dynamic Debugging** **4. [2KP] Dynamic Debugging**
  
-Intrați în directorul ''​10-dyndbg/''​ și compilați modulul ''​dyndbg.ko''​.+Intrați în directorul ''​9-dyndbg/''​ și compilați modulul ''​dyndbg.ko''​.
  
 Familiarizați-vă cu sistemul de fișiere ''​debugfs''​ montat în ''/​debug''​ și analizați conținutul fișierului ''/​debug/​dynamic_debug/​control''​. Inserați modulul dyndbg.ko și observați noul conținut al fișierului ''​dynamic_debug/​control''​. Familiarizați-vă cu sistemul de fișiere ''​debugfs''​ montat în ''/​debug''​ și analizați conținutul fișierului ''/​debug/​dynamic_debug/​control''​. Inserați modulul dyndbg.ko și observați noul conținut al fișierului ''​dynamic_debug/​control''​.
so2/laboratoare/lab02/exercitii.1519801998.txt.gz · Last modified: 2018/02/28 09:13 by ionel.ghita
CC Attribution-Share Alike 3.0 Unported
www.chimeric.de Valid CSS Driven by DokuWiki do yourself a favour and use a real browser - get firefox!! Recent changes RSS feed Valid XHTML 1.0