En lo que respecta a los programas de espacio de usuario, es bastante fácil engañarlos y falsificar el contenido de casi cualquier archivo. Por ejemplo, suponga que un programa C está usando un /proc/cpuinfo
archivo para verificar el número de serie. El programa está protegido contra copias y está vinculado a la serie, y no tengo el código fuente. Sin embargo, todavía puedo correr strace program 2>&1 | grep cpuinfo
, lo que revelará algo como:
open("/proc/cpuinfo", O_RDONLY) = 3
En este punto, puedo crear una pequeña biblioteca, cpuinfo.so
con la siguiente función:
int open(const char *file, int flags) {
static int (*real_open)(const char *file, int flags);
if(!real_open) real_open = dlsym(RTLD_NEXT, "open");
if(!strcmp(file, "/proc/cpuinfo")) file = "/tmp/cpuinfo";
return real_open(file, flags);
}
Como puede ver, estoy verificando si el usuario de la biblioteca intenta abrir /proc/cpuinfo
, en cuyo caso abro en su /tmp/cpuinfo
lugar.
Luego ejecutaré el programa original protegido contra copia como LD_PRELOAD=/path/to/cpuinfo.so program
, y felizmente leerá mi archivo falso pensando que es /proc/cpuinfo
, mientras funciona correctamente con el resto de los archivos.
Tenga en cuenta que si el software protegido contra copia incluye objetos del núcleo, será mucho más difícil engañarlo, ya que podría acceder al hardware directamente. Sin embargo, dicho software también solo funcionará con el núcleo para el que fue construido, lo que hace que sea poco práctico distribuirlo.