Замена статической функции в модуле ядра

Люди,

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

имя файла: orig.c

int fun(void) {
    printk(KERN_ALERT "calling fun!\n");
    return 0;
}
int evil(void) {
    printk(KERN_ALERT "===== EVIL ====\n");
    return 0;
}
static int init(void) {
    printk(KERN_ALERT "Init Original!");
    fun();
    return 0;
}
void clean(void) {
    printk(KERN_ALERT "Exit Original!");
    return;
}
module_init(init);
module_exit(clean);

Затем я следую статье Стикса, чтобы заменить оригинальную функцию «fun» в symtab для вызова функции «evil», http://www.phrack.org/issues.html?issue=68&id=11

>objdump -t orig.ko
...
000000000000001b g     F .text  000000000000001b evil
0000000000000056 g     F .text  0000000000000019 cleanup_module
0000000000000036 g     F .text  0000000000000020 init_module
0000000000000000 g     F .text  000000000000001b fun
...

Выполнением эльфчгера

>./elfchger -s fun -v 1b orig.ko
[+] Opening orig.ko file...
[+] Reading Elf header...
    >> Done!
[+] Finding ".symtab" section...
    >> Found at 0xc630
[+] Finding ".strtab" section...
    >> Found at 0xc670
[+] Getting symbol' infos:
>> Symbol found at 0x159f8
>> Index in symbol table: 0x1d
[+] Replacing 0x00000000 with 0x0000001b... done!

Я могу успешно изменить таблицу символов веселья, чтобы она стала равной злу, и вставив модуль, вы увидите эффект:

000000000000001b g     F .text  000000000000001b evil
...
000000000000001b g     F .text  000000000000001b fun
> insmod ./orig.ko
> dmesg
[ 7687.797211] Init Original!
[ 7687.797215] ===== EVIL ====

Пока это работает нормально. Когда я изменил объявление fun на «static int fun (void)» и выполнил те же действия, что и выше, я обнаружил, что зло не вызывается. Кто-нибудь может дать мне какое-нибудь предложение?

Спасибо, Уильям

4 голоса | спросил William Tu 6 J0000006Europe/Moscow 2013, 13:02:31

1 ответ


0

Короткая версия . Объявление функции как статической делает ее локальной и запрещает экспорт символа. Таким образом, вызов связан статически, и динамический компоновщик никак не влияет на вызов во время загрузки.


Длинная версия

Объявление символа как «статического» не позволяет компилятору экспортировать символ, делая его локальным, а не глобальным. Вы можете убедиться в этом, посмотрев (отсутствует) «g» в выходных данных objdump или в строчном «t» (вместо «T») в выходных данных «nm». Компилятор может также встроить локальную функцию, в этом случае таблица символов не будет содержать ее вообще.

Локальные символы должны быть уникальными только для единицы перевода, в которой они определены. Если ваш модуль состоит из нескольких модулей перевода, вы можете использовать статическую функцию fun () в каждом из них. Затем nm или objdump готового .ko могут содержать несколько локальных символов, называемых fun.

Это также подразумевает, что локальные символы действительны только в их соответствующих единицах перевода, и также могут быть переданы (в вашем случае: call) только внутри этого блока. В противном случае, компоновщик просто не будет сейчас, какой вы имеете в виду. Таким образом, вызов static fun () уже связан во время компиляции перед загрузкой модуля.

Во время загрузки динамический компоновщик не будет вмешиваться в забавный локальный символ или ссылки (в частности, на вызовы) на него, поскольку:

  1. его локальная связь уже сделана
  2. есть потенциально больше символов с именем fun, и динамический компоновщик не сможет определить, какой из них вы имели в виду
ответил ovenror 12 J0000006Europe/Moscow 2013, 23:04:00

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

Популярные теги

security × 330linux × 316macos × 2827 × 268performance × 244command-line × 241sql-server × 235joomla-3.x × 222java × 189c++ × 186windows × 180cisco × 168bash × 158c# × 142gmail × 139arduino-uno × 139javascript × 134ssh × 133seo × 132mysql × 132