Đối với các chương trình không gian người dùng có liên quan, thật dễ dàng để đánh lừa chúng và giả mạo nội dung của bất kỳ tệp nào. Ví dụ: giả sử một chương trình C đang sử dụng /proc/cpuinfo
tệp để xác minh số sê-ri. Chương trình được bảo vệ bản sao và gắn liền với sê-ri và tôi không có mã nguồn. Tuy nhiên, tôi vẫn có thể chạy strace program 2>&1 | grep cpuinfo
, điều này sẽ tiết lộ một cái gì đó như:
open("/proc/cpuinfo", O_RDONLY) = 3
Tại thời điểm này, tôi có thể tạo một thư viện nhỏ, cpuinfo.so
với chức năng sau:
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);
}
Như bạn có thể thấy, tôi đang kiểm tra xem người dùng của thư viện có cố mở không /proc/cpuinfo
, trong trường hợp đó tôi mở /tmp/cpuinfo
thay thế.
Sau đó, tôi sẽ chạy chương trình được bảo vệ bản sao gốc LD_PRELOAD=/path/to/cpuinfo.so program
và nó sẽ vui vẻ đọc tệp giả mạo của tôi với suy nghĩ đó /proc/cpuinfo
, trong khi hoạt động chính xác với các tệp còn lại.
Lưu ý rằng nếu phần mềm được bảo vệ bản sao bao gồm các đối tượng kernel, sẽ khó đánh lừa hơn nhiều, vì nó có thể truy cập trực tiếp vào phần cứng. Tuy nhiên, phần mềm như vậy cũng sẽ chỉ hoạt động với kernel được xây dựng, khiến nó không thực tế để phân phối.