2

RR0D Rasta Ring0 Debuggerを 32 ビット Linux から 64 ビット Linux に移植しようとしています。私の質問で述べたように、vim regex を使用して32 ビット gcc インライン アセンブリを 64 ビットに変換しました。

-m64フラグ付きのgccを使用しています。ターゲット環境は、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

makewarning: 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

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"

withの重要な#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"(in #if defined(__GNUC__)inside #ifdef LINUX_26) がコメントアウトされている場合、コードはコンパイルされないため、RING_HOOO_SEGMENT定義されることは明らかです。

forRING_HOOO_SEGMENTを grep すると、次の一致が得られます。

$ 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.koError: could not insert module ./rr0d.ko: Unknown symbol in module

insmodこの問題の理由と、モジュールに進む方法について何か考えはありますか?

4

1 に答える 1

2
core_rr0d.c:    "movq RING_HOOO_SEGMENT, %rax\n\t"\

ここで、RING_HOOO_SEGMENT は文字列内にあります (おそらくインライン アセンブラ ブロックの一部)。そのため、プリプロセッサは を置換せずRING_HOOO_SEGMENT、 の定義が利用できないアセンブラにそのまま渡されRING_HOOO_SEGMENTます。

幸いなことに、RING_HOOO_SEGMENTそれ自体が string として定義されている"$0x7b"ため、コンパイル時の文字列連結を使用できます。

"movq " RING_HOOO_SEGMENT ", %rax\n\t"\

プリプロセッサは を置換RING_HOOO_SEGMENT"$0x7b"、GCC はこれらの文字列を連結してからアセンブラに渡します。

于 2012-10-07T00:29:27.940 に答える