2012-10-06 66 views
2

我試圖將端口RR0D Rasta Ring0 Debugger從32位Linux移植到64位Linux。我已經使用vim regex將32位gcc內聯彙編轉換爲64位,正如我的問題所述:How to convert Linux 32-bit gcc inline assembly to 64-bit code?錯誤:無法插入模塊。模塊中的未知符號

我正在使用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 ./rr0d.ko以root身份insmod的模塊,我得到:

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_SEGMENTvars.h#define創建一個常數,即包括在幾個.c文件與#include "vars.h"

vars.h#define RING_HOOO_SEGMENT基本#ifdef塊是這一個:

#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該模塊?

回答

2
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將向下傳遞之前串聯這些字符串彙編程序。

+0

實際上,兩個內聯彙編行都在'#define'塊內。 ''movq RING_HOOO_SEGMENT,%rax \ n \ t「\'是以這種方式定義的塊:'#define HOOK_INT_HEADER_ASM(old_hooker)\ _asm _(」\ t「\」pushq%rax \ n \ t「\'.. 。另一行對於Microsoft C來說是一樣的。但是,由於該行位於'#define'塊中,並且我不知道如何在'#define'塊內替換'RING_HOOO_SEGMENT'的方法,所以我決定硬編碼(和評論),現在,該模塊現在加載但崩潰的Linux'BUG:無法處理[xxxx.yyyyyy]內核尋呼請求在00000000ffffd000'.但這是一個不同的問題。 – nrz

+0

@nrz,你仍然可以做我說的,即使在一個定義塊中,它會被替換多次,直到沒有宏留在體內 – bdonlan

+0

你是對的我可能有一些錯誤導致編譯失敗,使用'「movq」RING_HOOO_SEGMENT「 ,%rax \ n \ t「\'但我修復了它,現在編譯。 – nrz

相關問題