2015-12-11 1 views
3

Я пытаюсь изменить strace, чтобы захватить файл syscall и изменить файл, который фактически открыт. Например, пользователь пытается: открыть (OUT, "> input.txt"), но файл, который действительно будет открыт, это «input.txt.version1».Изменение strace для захвата и замены имени файла в открытом syscall

У меня был некоторый успех, когда длина нового имени точно такая же, как длина старого имени, используя ptrace (PTRACE_POKEDATA, pid, addr, laddr). Я перехватываю открытый вызов в open.c и изменяю umoven в util.c, чтобы вызывать вместо того, чтобы заглядывать, чтобы заменить символы.

Но это терпит неудачу, когда новое имя файла больше, поскольку оно может превышать длину массива исходного файла. Мне действительно нужно заменить указатель на массив символов новым указателем на мою собственную строку.

Имя файла находится в tcp-> u_arg [0], который является регистром rdi на системах x86. Я попытался вариации следующих не повезло:

struct user_regs_struct  x86_64_r; 
uint64_t *const x86_64_rdi_ptr = (uint64_t *) &x86_64_r.rdi; 
ptrace(PTRACE_POKEDATA, tcp->pid, x86_64_rdi_ptr, &newPath); 

Как я могу заменить имя файла с новым пути произвольной длины? Ответ с использованием только ptrace вместо модификации strace также будет прекрасен. strace просто заботится о многих других проблемах уже.

+0

К downvoter: пожалуйста, объясните. –

+0

Зачем это делать? Похоже на вредоносное программное обеспечение. – Olaf

+0

@Olaf Это может быть полезно для отладки ... –

ответ

5

Не ptrace, ни strace, но вы можете сделать это с помощью LD_PRELOAD, подключив функцию open.

Редактировать: в соответствии с комментарием @JonathanLeffler, я попытался исправить прототип функции hook, чтобы обрабатывать аргумент mode (если дано). Я не уверен на 100%, что это всегда будет работать, но оно должно дать представление о как это сделать.

hook.c

#define _GNU_SOURCE 
#include <dlfcn.h> 
#include <stdio.h> 
#include <string.h> 
#include <sys/types.h> //mode_t 
#include <stdarg.h> //va_arg 

typedef int (*pfn_open_t)(const char *pathname, int flags, mode_t mode); 

int open(const char *pathname, int flags, ...) 
{ 
    pfn_open_t o_open; 
    va_list val; 
    mode_t mode; 
    o_open = (pfn_open_t)dlsym(RTLD_NEXT,"open"); 
    // Extract vararg (mode) 
    va_start(val, flags); 
    mode = va_arg(val, mode_t); 
    va_end(val); 
    if(strcmp(pathname, "origfile") == 0) 
    { 
     puts("opening otherfile\n"); 
     return o_open("otherfile", flags, mode); 
    } 
    else 
    { 
     printf("opening %s\n", pathname); 
     return o_open(pathname,flags, mode); 
    } 
} 

компилировать код как общий объект:

gcc -shared -fPIC hook.c -o libhook.so -ldl 

запустить программу с крюком:

$ LD_PRELOAD=path/to/libhook.so myprogram 
+0

Это интересный подход. Я вернусь и поработаю над этим. Я предполагаю, что это может работать для любого системного вызова? – michael

+0

Выбор нитей: ваш тип 'pfn_open_t' не соответствует официальному прототипу' open() ', который имеет параметр' ... ', как вы точно знаете. Если флаги включают O_CREAT, вам необходимо передать этот третий параметр. –

+0

@JonathanLeffler - Спасибо, что указали это. Я проигнорировал эту проблему, когда отправил ответ, но это важный вопрос для решения. Я попытаюсь исправить это. Если у вас есть решение в руке - не стесняйтесь редактировать мой ответ или публиковать его отдельно. Я буду рад его видеть :) – MByD

Смежные вопросы