2

Jprobes を使用して Linux カーネルで関数 'do_execve()' へのフックを実行しようとしていますが、特定のシステムで問題が発生しています。Ubuntu 12、64ビット(カーネルバージョン3.11)でオンラインで見つけたこのコードを使用してみました:

Hook.c:

/* Trace do_execv.  Taken basically from Documentation/kprobes.txt */
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/sched.h>
#include <linux/kprobes.h>
#include <linux/kallsyms.h>

/*
 * Pre-entry point for do_execve.
 */
static int my_do_execve(char * filename,
                        char __user *__user *argv,
                        char __user *__user *envp,
                        struct pt_regs * regs)
{
        printk("do_execve for %s from %s\n", filename, current->comm);
        /* Always end with a call to jprobe_return(). */
        jprobe_return();
        /*NOTREACHED*/
        return 0;
}

static struct jprobe my_jprobe = {
        .entry = (kprobe_opcode_t *) my_do_execve
};

int init_module(void)
{
        int ret;
        my_jprobe.kp.addr = 
                (kprobe_opcode_t *) kallsyms_lookup_name("do_execve");
        if (!my_jprobe.kp.addr) {
                printk("Couldn't find %s to plant jprobe\n", "do_execve");
                return -1;
        }

        if ((ret = register_jprobe(&my_jprobe)) <0) {
                printk("register_jprobe failed, returned %d\n", ret);
                return -1;
        }
        printk("Planted jprobe at %p, handler addr %p\n",
               my_jprobe.kp.addr, my_jprobe.entry);
        return 0;
}

void cleanup_module(void)
{
        unregister_jprobe(&my_jprobe);
        printk("jprobe unregistered\n");
}

MODULE_LICENSE("GPL");

メイクファイル:

# This is taken straight from Documentation/kprobes.txt

obj-m := trace-exec.o
KDIR := /lib/modules/$(shell uname -r)/build
PWD := $(shell pwd)
default:
    $(MAKE) -C $(KDIR) SUBDIRS=$(PWD) modules
clean:
    rm -f *.mod.c *.ko *.o

モジュールは期待どおりに機能しました。最初にシステム上で正しくコンパイルされ、次に関数「insmod」で挿入されました (ROOT 権限で)。dmesg を実行すると、正しい出力が表示されます。

Planted Jprobes at [ADDRESS HERE], handler addr [ADDRESS HERE]
do_execve for /bin/sh from wcstatusd [PRINTED FOR ANY EXECUTED PROCESS]

この問題は、Ubuntu 14、64 ビット (カーネル バージョン 3.13) システムで同じコードを試したときに発生しました。システムで再コンパイルして、以前のシステムで行ったのと同じように挿入しましたが、今回は機能しませんでした。エラーは発生せず、成功メッセージ (「Planted jprobe at [ADDRESS WAS HERE], handler addr [ADDRESS WAS HERE]」) が出力されますが、「do_execve」行は出力されません。Google をスキャンしましたが、説明や解決策が見つかりませんでした。何か案は?

注: Ubuntu 14 で「do_fork()」をフックしてみましたが、うまくいきました。これは「do_execve()」を使ったもので、何が何だかわかりません!

4

1 に答える 1