Sono interessato a modificare gli interni del kernel, applicare patch, gestire driver e moduli del dispositivo, per il mio divertimento personale.
Esiste una risorsa completa per l'hacking del kernel, destinata a programmatori esperti?
Sono interessato a modificare gli interni del kernel, applicare patch, gestire driver e moduli del dispositivo, per il mio divertimento personale.
Esiste una risorsa completa per l'hacking del kernel, destinata a programmatori esperti?
Risposte:
**TODO** +editPic: Linux Kernel Developer -> (Ring Layer 0)
+addSection: Kernel Virtualization Engine
KERN_WARN_CODING_STYLE: Do not Loop unless you absolutely have to.
Libri consigliati per i non inizializzati
void *i
"Gli uomini non capiscono i libri fino a quando non hanno una certa quantità di vita, o comunque nessuno capisce un libro profondo, fino a quando non ha visto e vissuto almeno parte del suo contenuto". –Ezra Pound
Un viaggio di mille miglia-codice deve iniziare con un solo passo. Se sei confuso su quale dei seguenti libri per cominciare, non preoccuparti, scegli uno di quelli a tua scelta. Non tutti quelli che vagano sono persi. Poiché tutte le strade alla fine si collegano all'autostrada , esplorerai nuove cose nel tuo viaggio nel kernel man mano che le pagine procedono senza incontrare alcun vicolo cieco e alla fine ti collegherai a code-set
. Leggi con attenzione e ricorda: il codice non è letteratura .
Ciò che rimane non è una cosa o un'emozione o un'immagine o un'immagine mentale o un ricordo o persino un'idea. È una funzione. Un processo di qualche tipo. Un aspetto della vita che potrebbe essere descritto come una funzione di qualcosa di "più grande". E quindi, sembra che non sia realmente "separato" da quel qualcos'altro. Come la funzione di un coltello - tagliare qualcosa - in realtà non è separata dal coltello stesso. La funzione potrebbe essere o non essere in uso al momento, ma è potenzialmente MAI separata.
Algoritmo di Solovay Strassen derivato per test di primalità :
Leggi per non contraddire e confutare; né credere e dare per scontato; né per trovare discorsi e discorsi; ma pesare e considerare. Alcuni libri devono essere assaggiati, altri da inghiottire e alcuni da masticare e digerire: cioè alcuni libri devono essere letti solo in alcune parti, altri da leggere, ma non curiosamente, e alcuni pochi da leggere interamente e con diligenza e attenzione.
static void tasklet_hi_action(struct softirq_action *a)
{
struct tasklet_struct *list;
local_irq_disable();
list = __this_cpu_read(tasklet_hi_vec.head);
__this_cpu_write(tasklet_hi_vec.head, NULL);
__this_cpu_write(tasklet_hi_vec.tail, this_cpu_ptr(&tasklet_hi_vec.head));
local_irq_enable();
while (list) {
struct tasklet_struct *t = list;
list = list->next;
if (tasklet_trylock(t)) {
if (!atomic_read(&t->count)) {
if (!test_and_clear_bit(TASKLET_STATE_SCHED,
&t->state))
BUG();
t->func(t->data);
tasklet_unlock(t);
continue;
}
tasklet_unlock(t);
}
local_irq_disable();
t->next = NULL;
*__this_cpu_read(tasklet_hi_vec.tail) = t;
__this_cpu_write(tasklet_hi_vec.tail, &(t->next));
__raise_softirq_irqoff(HI_SOFTIRQ);
local_irq_enable();
}
}
Core Linux (5 -> 1 -> 3 -> 2 -> 7 -> 4 -> 6)
“La natura non ha né kernel né shell; lei è tutto in una volta ”- Johann Wolfgang von Goethe
Reader dovrebbe essere ben versato con i concetti del sistema operativo ; una buona comprensione dei processi di lunga durata e delle sue differenze con i processi con brevi raffiche di esecuzione; tolleranza agli errori nel rispetto dei vincoli in tempo reale soft e hard. Durante la lettura, è importante capire e n/ack
le scelte di progettazione fatte dal sorgente del kernel Linux nei sottosistemi core.
I thread [e] i segnali [sono] una scia dipendente dalla piattaforma di miseria, disperazione, orrore e follia (~ Anthony Baxte). Detto questo, dovresti essere un esperto di autovalutazione C, prima di immergerti nel kernel. Dovresti anche avere una buona esperienza con liste collegate, pile, code, alberi neri rossi, funzioni hash e così via.
volatile int i;
int main(void)
{
int c;
for (i=0; i<3; i++) {
c = i&&&i;
printf("%d\n", c); /* find c */
}
return 0;
}
La bellezza e l'arte della fonte del kernel Linux risiede nell'offuscamento deliberato del codice usato insieme. Ciò è spesso necessario per trasmettere il significato computazionale che coinvolge due o più operazioni in modo pulito ed elegante. Ciò è particolarmente vero quando si scrive codice per l'architettura multi-core.
Video lezioni su Real-Time Systems , Pianificazione attività , memoria di compressione , barriere di memoria , SMP
#ifdef __compiler_offsetof
#define offsetof(TYPE,MEMBER) __compiler_offsetof(TYPE,MEMBER)
#else
#define offsetof(TYPE, MEMBER) ((size_t) &((TYPE *)0)->MEMBER)
#endif
Driver di dispositivo Linux (1 -> 2 -> 4 -> 3 -> 8 -> ...)
"La musica non ti porta avanti. Devi portarla avanti rigorosamente con la tua capacità di concentrarti su quel piccolo nucleo di emozioni o storie". - Debbie Harry
Il tuo compito è sostanzialmente quello di stabilire un'interfaccia di comunicazione ad alta velocità tra il dispositivo hardware e il kernel del software. È necessario leggere il foglio dati / manuale di riferimento hardware per comprendere il comportamento del dispositivo, i suoi stati di controllo e dati e i canali fisici forniti. Conoscenza dell'assemblaggio per la tua particolare architettura e buona conoscenza dell'hardware VLSI Descrizione I linguaggi come VHDL o Verilog ti aiuteranno a lungo termine.
D : Ma perché devo leggere le specifiche hardware?
A : Perché "C'è un abisso di carbonio e silicio che il software non può colmare" - Rahul Sonnad
Tuttavia, quanto sopra non rappresenta un problema per gli algoritmi computazionali ( codice del driver - elaborazione della metà inferiore ), poiché può essere completamente simulato su una macchina di Turing universale . Se il risultato calcolato è vero nel dominio matematico , è certo che sia vero anche nel dominio fisico .
Lezioni video su driver di dispositivo Linux (Lec. 17 e 18), Anatomia di un driver KMS incorporato , Pin Control e aggiornamento GPIO , Common Clock Framework , Scrivi un vero driver Linux - Greg KH
static irqreturn_t phy_interrupt(int irq, void *phy_dat)
{
struct phy_device *phydev = phy_dat;
if (PHY_HALTED == phydev->state)
return IRQ_NONE; /* It can't be ours. */
/* The MDIO bus is not allowed to be written in interrupt
* context, so we need to disable the irq here. A work
* queue will write the PHY to disable and clear the
* interrupt, and then reenable the irq line.
*/
disable_irq_nosync(irq);
atomic_inc(&phydev->irq_disable);
queue_work(system_power_efficient_wq, &phydev->phy_queue);
return IRQ_HANDLED;
}
Kernel Networking (1 -> 2 -> 3 -> ...)
"Chiamalo un clan, chiamalo una rete, chiamalo una tribù, chiamalo una famiglia: qualunque cosa tu lo chiami, chiunque tu sia, ne hai bisogno." - Jane Howard
Comprendere una procedura dettagliata del pacchetto nel kernel è una chiave per comprendere la rete del kernel. Capirlo è d'obbligo se vogliamo capire Netfilter o IPSec internals e altro. Le due strutture più importanti del livello di rete del kernel linux sono: struct sk_buff
estruct net_device
static inline int sk_hashed(const struct sock *sk)
{
return !sk_unhashed(sk);
}
Debug del kernel (1 -> 4 -> 9 -> ...)
A meno che nel comunicare con esso si dica esattamente ciò che si intende, i problemi sono destinati a risultare. ~ Alan Turing, sui computer
Brian W. Kernighan, nel documento Unix for Beginners (1979), ha dichiarato: "Lo strumento di debug più efficace è ancora un attento esame, unito a dichiarazioni di stampa posizionate con giudizio". Sapere cosa raccogliere ti aiuterà a ottenere rapidamente i dati giusti per una diagnosi rapida. Il grande scienziato informatico Edsger Dijkstra una volta disse che i test potevano dimostrare la presenza di bug ma non la loro assenza. Le buone pratiche investigative dovrebbero bilanciare la necessità di risolvere rapidamente i problemi, la necessità di sviluppare le tue capacità e l'uso efficace degli esperti in materia.
Ci sono momenti in cui colpisci il fondo, nulla sembra funzionare e finisci tutte le tue opzioni. È allora che inizia il vero debug. Un bug può fornire l'interruzione necessaria per staccare da una fissazione sulla soluzione inefficace.
Lezioni video su debug e profilazione del kernel , analisi core dump , debug multicore con GDB , controllo delle condizioni di gara multi-core , elettronica di debug
/* Buggy Code -- Stack frame problem
* If you require information, do not free memory containing the information
*/
char *initialize() {
char string[80];
char* ptr = string;
return ptr;
}
int main() {
char *myval = initialize();
do_something_with(myval);
}
/* “When debugging, novices insert corrective code; experts remove defective code.”
* – Richard Pattis
#if DEBUG
printk("The above can be considered as Development and Review in Industrial Practises");
#endif
*/
File system (1 -> 2 -> 6 -> ...)
"Volevo avere memoria virtuale, almeno perché accoppiata ai file system". - Ken Thompson
Su un sistema UNIX, tutto è un file; se qualcosa non è un file, è un processo, ad eccezione di pipe e socket denominati. In un file system, un file è rappresentato da un inode
tipo di numero seriale contenente informazioni sui dati effettivi che compongono il file. Il file system virtuale Linux VFS
memorizza nella cache le informazioni nella memoria di ciascun file system man mano che viene montato e utilizzato. È necessario prestare molta attenzione per aggiornare correttamente il file system poiché i dati all'interno di queste cache vengono modificati man mano che i file e le directory vengono creati, scritti ed eliminati. La più importante di queste cache è la cache buffer, che è integrata nel modo in cui i singoli file system accedono ai loro dispositivi di archiviazione a blocchi sottostanti.
Lezioni video su sistemi di archiviazione , file system Flash Friendly
long do_sys_open(int dfd, const char __user *filename, int flags, umode_t mode)
{
struct open_flags op;
int fd = build_open_flags(flags, mode, &op);
struct filename *tmp;
if (fd)
return fd;
tmp = getname(filename);
if (IS_ERR(tmp))
return PTR_ERR(tmp);
fd = get_unused_fd_flags(flags);
if (fd >= 0) {
struct file *f = do_filp_open(dfd, tmp, &op);
if (IS_ERR(f)) {
put_unused_fd(fd);
fd = PTR_ERR(f);
} else {
fsnotify_open(f);
fd_install(fd, f);
}
}
putname(tmp);
return fd;
}
SYSCALL_DEFINE3(open, const char __user *, filename, int, flags, umode_t, mode)
{
if (force_o_largefile())
flags |= O_LARGEFILE;
return do_sys_open(AT_FDCWD, filename, flags, mode);
}
Sicurezza (1 -> 2 -> 8 -> 4 -> 3 -> ...)
"UNIX non è stato progettato per impedire ai suoi utenti di fare cose stupide, poiché ciò impedirebbe loro anche di fare cose intelligenti". - Doug Gwyn
Nessuna tecnica funziona se non viene utilizzata. L'etica cambia con la tecnologia.
" F × S = k " il prodotto di libertà e sicurezza è una costante. - Le leggi di Niven
La crittografia costituisce la base della fiducia online. L'hacking sta sfruttando i controlli di sicurezza in un elemento tecnico, fisico o umano. Proteggere il kernel da altri programmi in esecuzione è un primo passo verso un sistema sicuro e stabile, ma questo ovviamente non è abbastanza: un certo grado di protezione deve esistere anche tra diverse applicazioni utente-terra. Gli exploit possono essere indirizzati a servizi locali o remoti.
"Non puoi hackerare il tuo destino, la forza bruta ... hai bisogno di una porta sul retro, un canale laterale nella vita." - Clyde Dsouza
I computer non risolvono i problemi, eseguono soluzioni. Dietro ogni codice algoritmico non deterministico , c'è una mente determinata . - / var / log / dmesg
Lezioni video su crittografia e sicurezza della rete , spazi dei nomi per la sicurezza , protezione contro gli attacchi remoti , Linux embedded sicuro
env x='() { :;}; echo vulnerable' bash -c "echo this is a test for Shellsock"
Origine del kernel (0.11 -> 2.4 -> 2.6 -> 3.18)
"Come il vino, la padronanza della programmazione del kernel matura con il tempo. Ma, a differenza del vino, diventa più dolce nel processo". --Lawrence Mucheka
Potresti non pensare che i programmatori siano artisti, ma la programmazione è una professione estremamente creativa. È una creatività basata sulla logica. L'educazione informatica non può rendere nessuno programmatore esperto più che studiare pennelli e pigmenti può rendere qualcuno un pittore esperto. Come già sapete, c'è una differenza tra conoscere il sentiero e percorrerlo; è della massima importanza rimboccarsi le maniche e sporcarsi le mani con il codice sorgente del kernel. Infine, con la tua conoscenza del kernel così acquisita , ovunque tu vada, brillerai .
I programmatori immaturi imitano; i programmatori maturi rubano; i programmatori cattivi deturpano ciò che prendono e i programmatori buoni lo trasformano in qualcosa di meglio, o almeno in qualcosa di diverso. Il buon programmatore salda il suo furto in un sentimento unico, completamente diverso da quello da cui è stato strappato.
Lezioni video sulle ricette del kernel
linux-0.11
├── boot
│ ├── bootsect.s head.s setup.s
├── fs
│ ├── bitmap.c block_dev.c buffer.c char_dev.c exec.c
│ ├── fcntl.c file_dev.c file_table.c inode.c ioctl.c
│ ├── namei.c open.c pipe.c read_write.c
│ ├── stat.c super.c truncate.c
├── include
│ ├── a.out.h const.h ctype.h errno.h fcntl.h
│ ├── signal.h stdarg.h stddef.h string.h termios.h
│ ├── time.h unistd.h utime.h
│ ├── asm
│ │ ├── io.h memory.h segment.h system.h
│ ├── linux
│ │ ├── config.h fdreg.h fs.h hdreg.h head.h
│ │ ├── kernel.h mm.h sched.h sys.h tty.h
│ ├── sys
│ │ ├── stat.h times.h types.h utsname.h wait.h
├── init
│ └── main.c
├── kernel
│ ├── asm.s exit.c fork.c mktime.c panic.c
│ ├── printk.c sched.c signal.c sys.c system_calls.s
│ ├── traps.c vsprintf.c
│ ├── blk_drv
│ │ ├── blk.h floppy.c hd.c ll_rw_blk.c ramdisk.c
│ ├── chr_drv
│ │ ├── console.c keyboard.S rs_io.s
│ │ ├── serial.c tty_io.c tty_ioctl.c
│ ├── math
│ │ ├── math_emulate.c
├── lib
│ ├── close.c ctype.c dup.c errno.c execve.c _exit.c
│ ├── malloc.c open.c setsid.c string.c wait.c write.c
├── Makefile
├── mm
│ ├── memory.c page.s
└── tools
└── build.c
Linux_source_dir/Documentation/*
I principianti del kernel Linux sono un'ottima risorsa.
Ti suggerisco di leggere " Linux Kernel in a Nutshell ", di Greg Kroah-Hartman e " Understanding the Linux Kernel ", di Robert Love. Deve leggere :)
Linux Device Driver è un'altra buona risorsa. Ti darebbe un altro modo per entrare nei meccanismi interni. Dalla prefazione:
Questo è, in superficie, un libro sulla scrittura di driver di dispositivo per il sistema Linux. Questo è un obiettivo degno, ovviamente; è probabile che il flusso di nuovi prodotti hardware non rallenti presto e qualcuno dovrà far funzionare tutti quei nuovi gadget con Linux. Ma questo libro parla anche di come funziona il kernel Linux e di come adattare il suo funzionamento ai tuoi bisogni o interessi. Linux è un sistema aperto; con questo libro, speriamo, sia più aperto e accessibile a una più ampia comunità di sviluppatori.
Vedi The Linux Documentation Project . In particolare la "Guida ai moduli del kernel Linux".
Linux Kernel 2.4 Internals è un'altra risorsa online da guardare. Sembra adottare un approccio piuttosto "radicato", iniziando con l'avvio. Ecco il sommario:
E, per renderlo ancora più dolce, c'è una nuova Linux Kernel Development Third Edition di Robert Love e Slashdot ha una recensione.
Inizia con Linux Kernel Primer di Claudia Salzberg et al. Buono per cominciare con i principianti. Il libro di Robert Love non è sicuramente il libro con cui i principianti dovrebbero iniziare. Il libro degli ultimi è al di sopra del livello intermedio.