Найти последний символ файла и добавить после него строку? [дубликат]

Как насчет перехвата системного вызова 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
2
23.07.2016, 05:15
2 ответа

Чтобы избежать перезаписи всего файла, который вы пытаетесь найти, до конца файла, сделайте резервную копию одного символа и запишите.

Делать это с помощью обычных инструментов оболочки 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 "$!";
1
27.01.2020, 21:54

Правильно сформированный текстовый файл 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 /

    Для последней строки файла это помещает новых слов в конец строки, но перед последним символом новой строки.

    В замещающей команде $ означает конец строки.

5
27.01.2020, 21:54

Теги

Похожие вопросы