関数に kprobe を配置したので、kprobe のプリハンドラー関数でその引数の値を取得する必要があります。
これが私の機能です:
void foobar(int arg, int arg2, int arg3, int arg4, int arg5, int arg6, int arg7, int arg8)
{
printk("foobar called\n");
}
kprobe を配置し、関数を呼び出します。
...
kp.addr = (kprobe_opcode_t *) foobar;
register_kprobe(&kp);
foobar(0xdead1, 0xdead2, 0xdead3, 0xdead4, 0xdead5, 0xdead6, 0xdead7, 0xdead8);
そして最後にプリハンドラー関数 (ここから取得):
static int inst_generic_make_request(struct kprobe *p, struct pt_regs *regs)
{
printk(KERN_INFO "eax: %08lx ebx: %08lx ecx: %08lx edx: %08lx\n",
regs->ax, regs->bx, regs->cx, regs->dx);
printk(KERN_INFO "esi: %08lx edi: %08lx ebp: %08lx esp: %08lx\n",
regs->si, regs->di, regs->bp, regs->sp);
regs++;
//...
}
プリハンドラー関数からの出力は次のようになります (regs
ポインターを 3 回インクリメントしました)
May 10 22:58:07 kernel: [ 402.640994] eax: 000dead1 ebx: f7d80086 ecx: 000dead3 edx: 000dead2
May 10 22:58:07 kernel: [ 402.640996] esi: 00000000 edi: b77c8040 ebp: 00000000 esp: f7d8006c
May 10 22:58:07 kernel: [ 402.641006] eax: f7d8032c ebx: 000dead5 ecx: 000dead6 edx: 000dead7
May 10 22:58:07 kernel: [ 402.641007] esi: 000dead8 edi: f7d800e0 ebp: f7d80330 esp: 08049674
May 10 22:58:07 kernel: [ 402.641014] eax: 00000080 ebx: 0992b018 ecx: 0000108e edx: 0992b008
May 10 22:58:07 kernel: [ 402.641015] esi: 08049674 edi: b77c8040 ebp: bfe23fb8 esp: bfe23f50
関数の引数がfoobar
さまざまなレジスタに表示されるようになりました (ただし、? はどこにあり0xdead4
ますか)。それらはスタックにあるべきではありませんか? プリハンドラー関数からスタックにアクセスするにはどうすればよいですか? または、関数の型と数を知らずに関数の引数を取得するにはどうすればよいでしょうか? これは簡単な作業ではない (すべての値を取得することさえできない) ことはわかっていますが、おおよその値だけで十分です。2 つの関数の引数間の相関を計算していますが、正確な値は必要ありません。引数がスタックにプッシュされる呼び出し元関数のアセンブリ コードがあれば役に立ちますか)。