Как сделать бинарный инструментарий системного вызова BRK?(x86-64 Linux) (может быть, valgrind?) - PullRequest
0 голосов
/ 01 ноября 2011

Я бы хотел, чтобы инструмент syscall brk (и другие вызовы, но это в первом порядке, это наиболее важно для меня) в с учетом двоичного файла (предпочтительно на фактическом syscall / sysenter уровень (x86-64 и x86) совершения sys_brk вызова).

Основная цель:

  • Часть песочницы, которая отдает фиксированный объем памяти для заключенного в тюрьму процесса
  • Итак, я бы хотел избавиться от системных вызовов brk (и, наиболее предпочтительно, от других в следующем порядке) и симулировать выделение памяти под фиксированный предел . Фиксированный предел - это объем памяти, доступный для программы. (Вы можете думать об этом, как о создании своего рода песочницы с фиксированным объемом доступной памяти)

Как реализовать (одно из) несколько возможных решений (или ваше решение):

  • просто изменив инструкции на NOP
  • Поскольку brk возвращает 0 в случае успеха, имитируйте его успех с помощью операций установки, которые устанавливают состояние памяти (регистра), так как brk будет вызываться с успехом.
  • Более сложный ... инструмент с кодом (или вызовом функции), который имитирует успешное распределение памяти под фиксированным пределом.
  • Наиболее гибкий (возможно, излишний в моем случае) преобразовать этот системный вызов в вызов функции и добавить предоставленную функцию в двоичный файл.

Данный двоичный файл - это код, который может быть вредоносным в одной из двух (наиболее предпочтительно в обеих :)) формах:

  • разделяемая библиотека - здесь я могу настроить среду перед вызовом функции (например, сделать вызов brk контролируемым образом)
  • двоичный файл программы - в этом случае нам нужно предоставить программе фиксированный объем памяти (вызывающей стороной или при запуске программы "один системный вызов"), поскольку она не может быть выделена. Пример вызова такой программы должен быть включен в ответ.

Поскольку проблема тесно связана со многими другими аспектами, я постарался сделать все возможное, чтобы отделить ее как вопрос, но, пожалуйста, дайте мне совет, если мне следует указать что-то более или менее.

Ответы с реализацией, ссылки на ресурсы (книги, учебные пособия) приветствуются.

(меня больше всего интересует Linux и решение, надежное , чтобы людям, готовящим двоичные файлы, даже на ассемблере, не приходилось беспокоиться о выполнении своего кода)

Ответы [ 2 ]

1 голос
/ 06 ноября 2011

LD_PRELOAD будет перехватывать C-вызовы brk (), но не будет перехватывать фактический системный вызов (инструкция int / syscall). Переносимых способов их перехватить не существует, но в Linux ptrace сделает это. Память также может быть выделена программе с помощью mmap (), так что вам нужно будет также перехватить этот вызов.

Конечно, вы действительно ищете: rlimit ().

0 голосов
/ 03 ноября 2011

Да, я не думаю, что вы хотите Вальгринда для этого.

Вы можете использовать трюки LD_PRELOAD или компоновщика для захвата brk (2): см. Эти другие обсуждения:

Вставка функции в Linux без dlsym

Переопределение 'malloc' с использованием механизма LD_PRELOAD

Код может выглядеть следующим образом:

#include <unistd.h>
#include <dlfcn.h>

/* prototype int brk(void *addr); */

static int (*real_brk)(void *addr) = NULL;

int brk(void * addr) {

    real_brk = dlsym(RTLD_NEXT, "brk");
    if (real_brk == NULL) {
            fprintf(stderr, "error mapping brk: %s\n", dlerror());
            return -1;
    }
    printf("calling brk(2) for %p\n", addr);
    return (real_brk (addr));
}`   

и затем LD_PRELOAD, чтобы перехватить brk (2)

...