Ошибка: не удалось вставить модуль. Неизвестный символ в модуле
Я пытаюсь портировать RR0D Rasta Ring0 Debugger с 32-битного Linux на 64-битный Linux. Я преобразовал 32-битную встроенную сборку gcc в 64-битную, используя vim regex, как указано в моем вопросе: Как преобразовать 32-битную встроенную сборку gcc в Linux в 64-битный код?
Я использую GCC с -m64
флаг. Целевая среда - Linux x86-64, версия ядра 3.5.5.
Makefile
является следующим:
EXTRA_CFLAGS += -O2 -Wall -DLINUX_26 -m64
OBJ := module_nux.o breakpoint.o buffering.o command.o disasmbak.o idt.o
OBJ += keyboard.o page.o video.o utils.o import_symb.o core_rr0d.o pci.o
MODULE := rr0d.o
obj-m := $(MODULE)
rr0d-objs := $(OBJ)
default:
make -C /lib/modules/`uname -r`/build/ SUBDIRS=`pwd` modules
clean:
rm -f *.o .*.o.cmd .*.ko.cmd *.mod.c *~
rm -rf .tmp_versions
mrproper:
make clean
rm -f *.ko
make
дает много предупреждений, таких как warning: cast to pointer from integer of different size [-Wint-to-pointer-cast]
а также warning: cast from pointer to integer of different size [-Wpointer-to-int-cast]
, но это, вероятно, не имеет отношения к теме.
Последние строки вывода make
вероятно, важные из них:
/home/user/code/rr0d/0.3/core_rr0d.c: In function ‘cleanup_rr0d’:
/home/user/code/rr0d/0.3/core_rr0d.c:1938:36: warning: cast from pointer to integer of different size [-Wpointer-to-int-cast]
CC [M] /home/user/code/rr0d/0.3/pci.o
LD [M] /home/user/code/rr0d/0.3/rr0d.o
Building modules, stage 2.
MODPOST 1 modules
WARNING: "RING_HOOO_SEGMENT" [/home/user/code/rr0d/0.3/rr0d.ko] undefined!
CC /home/user/code/rr0d/0.3/rr0d.mod.o
LD [M] /home/user/code/rr0d/0.3/rr0d.ko
make[1]: Leaving directory `/home/user/code/kernel/linux-3.5.5'
Так, RING_HOOO_SEGMENT
не определено
Когда я пытаюсь insmod
модуль с insmod ./rr0d.ko
как root я получаю:
Error: could not insert module ./rr0d.ko: Unknown symbol in module
Проверка с dmesg | tail -n 1
дает следующий вывод:
[15975.412346] rr0d: Unknown symbol RING_HOOO_SEGMENT (err 0)
Итак, неизвестный символ окончательно RING_HOOO_SEGMENT
,
RING_HOOO_SEGMENT
константа, созданная с #define
в vars.h
, что входит в несколько .c
файлы с #include "vars.h"
,
Самое важное #ifdef
блок из vars.h
с #define RING_HOOO_SEGMENT
это один:
#ifdef LINUX_26
#define fake_naked
#if defined(__GNUC__)
// the line below is the important one.
#define RING_HOOO_SEGMENT "$0x7b"
//#define RING_HOOO_SEGMENT "$0x60"
#elif defined(_MSC_VER)
#define RING_HOOO_SEGMENT 0x7b
#endif
#else /* LINUX_24 */
#define fake_naked _asm_("\t" \
"add $0x08, %esp\n\t" \
"popl %ebp\n" \
);
#if defined(__GNUC__)
#define RING_HOOO_SEGMENT "$0x18"
#elif defined(_MSC_VER)
#define RING_HOOO_SEGMENT 0x18
#endif
#define RING_HOOO_SEGMENT_VALUE 0x18
#endif /* LINUX_26 */
Очевидно, если #define RING_HOOO_SEGMENT "$0x7b"
(в #if defined(__GNUC__)
внутри #ifdef LINUX_26
), код не будет компилироваться, поэтому ясно, что RING_HOOO_SEGMENT
определяется
Grepping для RING_HOOO_SEGMENT
дает следующие совпадения:
$ grep 'RING_HOOO_SEGMENT' *.c *.o *.ko
core_rr0d.c: "movq RING_HOOO_SEGMENT, %rax\n\t"\
core_rr0d.c: __asm{ movq RING_HOOO_SEGMENT, %rax}\
Binary file rr0d.ko matches
И то и другое core_rr0d.c
ряды встроены в сборку. core_rr0d.c
содержит #include "vars.h"
так что должно быть хорошо.
Также бинарный модуль rr0d.ko
совпадает, поэтому он содержит строку RING_HOOO_SEGMENT
(в некоторой форме), даже если insmod ./rr0d.ko
не удается с Error: could not insert module ./rr0d.ko: Unknown symbol in module
,
Любые идеи, что может быть причиной этой проблемы и как поступить, чтобы иметь возможность insmod
модуль?
1 ответ
core_rr0d.c: "movq RING_HOOO_SEGMENT, %rax\n\t"\
Здесь RING_HOOO_SEGMENT находится в строке (вероятно, является частью встроенного блока ассемблера). Таким образом, препроцессор не заменит RING_HOOO_SEGMENT
и он передается как-есть ассемблеру, где определение RING_HOOO_SEGMENT
не доступен.
К счастью, RING_HOOO_SEGMENT
сам по себе определяется как строка "$0x7b"
, поэтому мы можем использовать конкатенацию строк во время компиляции:
"movq " RING_HOOO_SEGMENT ", %rax\n\t"\
Препроцессор заменит RING_HOOO_SEGMENT
за "$0x7b"
затем GCC объединит эти строки перед передачей ассемблеру.