Как насчет перехвата системного вызова mkdir
с помощью LD_PRELOAD
...?
$ ls
test.c
$ cat test.c
#define _GNU_SOURCE
#include <string.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <dlfcn.h>
typedef int (*orig_mkdir_func_type)(const char *path, mode_t mode);
int mkdir(const char *path, mode_t mode) {
if(!strcmp(path, "shop")) return 1;
orig_mkdir_func_type orig_func;
orig_func = (orig_mkdir_func_type)dlsym(RTLD_NEXT, "mkdir");
return orig_func(path, mode);
}
$ gcc -shared -fPIC test.c -o test.so
$ LD_PRELOAD='./test.so' mkdir test
$ LD_PRELOAD='./test.so' mkdir shop
mkdir: cannot create directory ‘shop’: No such file or directory
$ ls
test test.c test.so
Обратите внимание, что внутри этого обработчика вы можете зарегистрировать PID процесса, который вместо этого хочет создать этот каталог:
$ cat test.c
#define _GNU_SOURCE
#include <string.h>
#include <stdio.h>
#include <unistd.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <dlfcn.h>
typedef int (*orig_mkdir_func_type)(const char *path, mode_t mode);
int mkdir(const char *path, mode_t mode) {
if(!strcmp(path, "shop")) {
FILE* fp = fopen("/tmp/log.txt", "w");
fprintf(fp, "PID of evil script: %d\n", (int)getpid());
fclose(fp);
}
orig_mkdir_func_type orig_func;
orig_func = (orig_mkdir_func_type)dlsym(RTLD_NEXT, "mkdir");
return orig_func(path, mode);
}
$ gcc -shared -fPIC test.c -o test.so
$ LD_PRELOAD='./test.so' mkdir shop
$ cat /tmp/log.txt
PID of evil script: 8706
Вам нужно поместить это в ~ / .bashrc
root (или того, кто запускает ваше приложение), чтобы гарантировать, что это будет использоваться:
export LD_PRELOAD=/path/to/test.so
Чтобы избежать перезаписи всего файла, который вы пытаетесь найти, до конца файла, сделайте резервную копию одного символа и запишите.
Делать это с помощью обычных инструментов оболочки Unix немного ненадежно.
Однако есть Perl, который делает все. Вы также можете использовать Ruby, Python или любой другой полнофункциональный язык сценариев.
Пример Perl:
#!/usr/bin/env perl
use strict;
use Fcntl qw(:seek);
open(F, '+<', 'testfile') or die "$!";
seek(F, -1, SEEK_END) or die "$!";
print F "new data\n";
close(F) or die "$!";
Правильно сформированный текстовый файл unix должен иметь завершающую новую строку в конце файла. Для достижения желаемого, строка должна быть помещена перед , что существующий завершающий символ новой строки.
Рассмотрим этот тестовый файл:
$ cat File
1
2
3
Теперь давайте добавим слова в последнюю строку перед последним символом новой строки:
$ sed '$s/$/new words/' File
1
2
3new words
Или, если вы хотите отредактировать файл на месте, используйте -i
параметр:
sed -i.bak '$s/$/new words/' File
Как это работает:
$
Первый $
указывает sed выполнять только команду, которая следует за последней строкой файла.
s / $ / new words /
Для последней строки файла это помещает новых слов
в конец строки, но перед последним символом новой строки.
В замещающей команде $
означает конец строки.