Domanda

Oltre al trucco LD_PRELOAD e ai moduli del kernel Linux che sostituiscono una determinata chiamata di sistema con una fornita da te, esiste qualche possibilità di intercettare una chiamata di sistema (ad esempio open), in modo che passi attraverso la tua funzione, prima di raggiungere l'effettivo open?

È stato utile?

Soluzione

se hai davvero bisogno di una soluzione potresti essere interessato al rootkit DR che realizza proprio questo, http://www.immunityinc.com/downloads/linux_rootkit_source.tbz2 l'articolo a riguardo è qui http://www.theregister.co.uk/2008/09/04/linux_rootkit_released/

Altri suggerimenti

Perché non puoi/non vuoi usare il file Trucco LD_PRELOAD?

Codice di esempio qui:

/*
 * File: soft_atimes.c
 * Author: D.J. Capelis
 *
 * Compile:
 * gcc -fPIC -c -o soft_atimes.o soft_atimes.c
 * gcc -shared -o soft_atimes.so soft_atimes.o -ldl
 *
 * Use:
 * LD_PRELOAD="./soft_atimes.so" command
 *
 * Copyright 2007 Regents of the University of California
 */

#define _GNU_SOURCE
#include <dlfcn.h>
#define _FCNTL_H
#include <bits/fcntl.h>

extern int errorno;

int (*_open)(const char * pathname, int flags, ...);
int (*_open64)(const char * pathname, int flags, ...);

int open(const char * pathname, int flags, mode_t mode)
{
    _open = (int (*)(const char * pathname, int flags, ...)) dlsym(RTLD_NEXT, "open");
    if(flags & O_CREAT)
        return _open(pathname, flags | O_NOATIME, mode);
    else
        return _open(pathname, flags | O_NOATIME, 0);
}

int open64(const char * pathname, int flags, mode_t mode)
{
    _open64 = (int (*)(const char * pathname, int flags, ...)) dlsym(RTLD_NEXT, "open64");
    if(flags & O_CREAT)
        return _open64(pathname, flags | O_NOATIME, mode);
    else
        return _open64(pathname, flags | O_NOATIME, 0);
}

Da quello che ho capito...è praticamente il trucco LD_PRELOAD o un modulo del kernel.Non c'è molta via di mezzo a meno che tu non voglia eseguirlo con un emulatore che possa intrappolare la tua funzione o riscrivere il codice sul binario effettivo per intrappolare la tua funzione.

Supponendo che non sia possibile modificare il programma e che non si possa (o non si voglia) modificare il kernel, l'approccio LD_PRELOAD è il migliore, presupponendo che l'applicazione sia abbastanza standard e non sia effettivamente una che tenta maliziosamente di oltrepassare la tua intercettazione.(In tal caso avrai bisogno di una delle altre tecniche.)

Valgrind può essere utilizzato per intercettare qualsiasi chiamata di funzione.Se è necessario intercettare una chiamata di sistema nel prodotto finito, ciò non sarà utile.Tuttavia, se provi a intercettare durante lo sviluppo, può essere molto utile.Ho utilizzato spesso questa tecnica per intercettare le funzioni di hashing in modo da poter controllare l'hash restituito a scopo di test.

Nel caso non lo sapessi, Valgrind viene utilizzato principalmente per trovare perdite di memoria e altri errori relativi alla memoria.Ma la tecnologia sottostante è fondamentalmente un emulatore x86.Emula il tuo programma e intercetta le chiamate a malloc/free ecc.La cosa buona è che non è necessario ricompilare per usarlo.

Valgrind ha una caratteristica che chiamano Avvolgimento di funzioni, che viene utilizzato per controllare l'intercettazione delle funzioni.Vedere la sezione 3.2 del Manuale Valgrind per dettagli.Puoi impostare il wrapper delle funzioni per qualsiasi funzione tu voglia.Una volta intercettata la chiamata, viene richiamata la funzione alternativa fornita.

Alcune applicazioni possono ingannare strace/ptrace in modo che non venga eseguito, quindi l'unica vera opzione che ho avuto è stata l'utilizzo di systemtap

Systemtap può intercettare un sacco di chiamate di sistema, se necessario, grazie alla corrispondenza dei caratteri jolly.Systemtap non è C, ma un linguaggio separato.In modalità base, il systemtap dovrebbe impedirti di fare cose stupide, ma può anche essere eseguito in "modalità esperto" che ritorna a consentire a uno sviluppatore di utilizzare C se necessario.

Non richiede di applicare patch al kernel (o almeno non dovrebbe), e una volta che un modulo è stato compilato, è possibile copiarlo da una casella di test/sviluppo e inserirlo (tramite insmod) su un sistema di produzione.

Devo ancora trovare un'applicazione Linux che abbia trovato un modo per aggirare/evitare di essere catturato dal systemtap.

Se solo lo desideri orologio cosa è aperto, vuoi guardare la funzione ptrace() o il codice sorgente dell'utilità strace della riga di comando.Se davvero lo vuoi intercettare la chiamata, magari per fargli fare qualcos'altro, penso che le opzioni che hai elencato - LD_PRELOAD o un modulo del kernel - siano le tue uniche opzioni.

Non ho la sintassi per farlo con garbo con un LKM estemporaneo, ma questo articolo fornisce una buona panoramica di ciò che dovresti fare: http://www.linuxjournal.com/article/4378

Potresti anche semplicemente applicare una patch alla funzione sys_open.Inizia alla riga 1084 di file/open.c a partire da linux-2.6.26.

Potresti anche vedere se non puoi utilizzare inotify, systemtap o SELinux per eseguire tutte queste registrazioni per te senza dover creare un nuovo sistema.

Se vuoi farlo solo per scopi di debug, guarda strace, che è integrato nella chiamata di sistema ptrace(2) che ti consente di collegare il codice quando viene eseguita una chiamata di sistema.Vedere la parte PTRACE_SYSCALL della pagina man.

Sembra che tu abbia bisogno di un auditd.

Auditd consente il tracciamento globale di tutte le chiamate di sistema o gli accessi ai file, con registrazione.Puoi impostare le chiavi per eventi specifici a cui sei interessato.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top