1

do_execve に jprobe フックを設定して、実行されたすべてのプログラムをキャッチしたいと考えています。

私のコードは <= 3.2 Linux カーネル (debian) で動作しています。これは、Linux カーネル 3.2 での私の出力です。

[  628.534037] registered: do_execve, ret: 0
[  723.995797] execve: /usr/bin/vi
[  726.807025] execve: /bin/dmesg

4.1カーネルでは同じ結果(すべてが登録されています)ですが、「execve」はありません:

[ 8621.430568] registered: do_execve, ret: 0

そして、これは私のコードです:

static struct jprobe jprobe_hooks[] = {
{
    .entry = jdo_execve,
    .kp = { .symbol_name = "do_execve" }
}};

static long jdo_execve(const char *filename, const char __user *const __user *argv, const char __user *const __user *envp, struct pt_regs *regs)
{
   printk(KERN_INFO "execve: %s", filename );
}

// 
// registration
//
int ret, x, reg_error;

reg_error = 0;
for (x = 0; x < sizeof(jprobe_hooks) / sizeof(jprobe_hooks[0]); x++)
{
    ret = register_jprobe(&jprobe_hooks[x]);
    if (ret < 0)
    {
        printk(KERN_INFO "register_jprobe failed, returned %d, item: %s\n", ret, jprobe_hooks[x].kp.symbol_name);
        reg_error++;
    }
    else
    {
        printk(KERN_INFO "registered: %s, ret: %u\n", jprobe_hooks[x].kp.symbol_name, ret);
    }
}

kallsyms で grep を実行すると、3.2 になります。

 grep do_execv /proc/kallsyms
 ffffffff81100650 T do_execve

そして4.2で:

grep do_execv /proc/kallsyms
ffffffff811d2950 T do_execve
ffffffff811d2980 T do_execveat

関数を次のように変更しようとしました (do_execve プロトタイプが変更されたため)。

static int jdo_execve(struct filename *fname, const char __user *const __user *__argv, const char __user *const __user *__envp)
{
    int i = 0;

    printk(KERN_INFO "execve: %s ", fname->name );
}

それでも役に立ちませんでした。

do_fork や sys_open などの他の関数にはフックを設定できますが、do_execve には設定できません。なんで?誰にもアイデアがありますか?なぜ機能しなくなったのですか?

編集:

do_execveat もフックしています。

 static int jdo_execveat(int fd, struct filename *fname, const char __user *const __user *__argv, const char __user *const __user *__envp, int flags)
4

1 に答える 1

2

jprobe メッセージを妨げる可能性のある問題がいくつかあります。

  1. 印刷メッセージprintk(KERN_INFO "execve: %s", filename );を改行で終了しないため、ログ バッファはフラッシュされません。
  2. APIが変更されました。ファイル名パラメータdo_execvestruct filename.
  3. あなたの jprobe コードはばかげています: モジュール エントリがありません。jprobe ルーチンはjprobe_return()call で終了する必要があります。「samples/kprobes」にあるカーネル ソース ツリーのサンプルを見てください。

それを修正してみてください - 多分それは助けになるでしょう.

とにかく、私は自分で試してみました -ここにコードがあります - そして物事は確かに奇妙に見えます. モジュールをロードすると、2 つの jprobe が登録されます。1 つは do_execve 用で、もう 1 つは do_execveat 用です。しかし、プログラムを実行してもメッセージは表示されません。しかし、私が見ているのは、次のような定期的なメッセージです。

jprobe: execve: /usr/lib/systemd/systemd-cgroups-agent

これは、jprobe 自体は機能しますが、すべてのexecve呼び出しでは機能しないことを意味します。

そのため、本当に呼び出されていることを確認するために呼び出す単純な C プログラムを作成しましたが、まだ何も起こりません execpt systemd-cgroups-agent.execve

于 2015-09-07T10:09:20.387 に答える