私は初期のカーネルプログラミングに取り組んでいましたが、ioctlシステムコールの代わりに/ hookを使用しようとしていました。モジュールを使ってsyscallテーブルにフックする
ターゲットシステムは、カーネル3.10のmips(o32)システムです。
私はx86ベースのシステムで見た類似のプロジェクト/例に基づいて、私はうまくいくと思った基本的なスニペットに到達しました。私はSystem.mapにアクセスできないが、sys_call_tableアドレスに気づいたので、アドレス上での試みはターゲットシステム上の/proc/kallsyms
に基づいている。私はこのアドレスがカーネルビルドからビルドに変わることを知っていますが、それは今のところ問題ではありません。これは実験目的のみのものです。その全体が
モジュール:
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/syscalls.h>
static u32 **sct = (u32**)0x80008660; // `grep sys_call_table /proc/kallsyms`
asmlinkage int (*ioctl_orig)(s32 fd, u32 cmd, void* addr);
asmlinkage int ioctl_new(s32 fd, u32 cmd, void* addr)
{
printk("[IOC] Intercepted ioctl 0x%x to addr 0x%p\n", cmd, addr);
return ioctl_orig(fd, cmd, addr);
}
static int __init _enter(void)
{
ioctl_orig = (void*)sct[__NR_ioctl];
sct[__NR_ioctl] = (u32*)ioctl_new;
printk("[IOC] Original IOCTL addr: %p\n", ioctl_orig);
printk("[IOC] New IOCTL addr: %p\n", sct[__NR_ioctl]);
return 0;
}
static void __exit _exit(void)
{
sct[__NR_ioctl] = (u32 *)ioctl_orig;
printk("[IOC] Unloaded\n");
}
module_init(_enter);
module_exit(_exit);
MODULE_LICENSE("GPL");
明らかにこれは動作しないか、私はここに壁をこすることはありません。モジュールは正常にロードされ、_enter
/_exit
からprintk
が実際に表示されますが、何らかの方法でカーネルに向けてioctlsを実行すると何も起こりません(私は、迎え入れられたioctlメッセージをioctl_new
から見ることになります)間違った箇所を修正しています。
質問:明らか
- :私は間違って何をしているのですか?
/proc/kallsyms
は、syscallテーブルの先頭に正しいポインタを提供できますか。sys_ioctl
に関連付けられた値が/proc/kallsyms
の*sct[__NR_ioctl]
と一致する必要がありますか、何か不足していますか?- 正しくキャスティングされていますか?
- mctに適用できるsctableを変更するこの方法はありますか?
"私が間違って何をしているのですか?" x86では、同じことをするには、いくつかのasm行でページ保護を無効にする必要があります。私はmipsに相当するものがあると思います。 – purplepsycho
"私は'/proc/kallsyms' ...に頼ることができますか?"あなたのシステムに' 'kallsyms_lookup_name(" sys_call_table ")関数が存在しましたか?それはあなたに必要なものを返すはずです(https://stackoverflow.com/a/39202118/1212012) – purplepsycho
cr0ページ保護ビットを認識しています私はMIPSで同様のメカニズムの証拠が見つかりませんでした。 – bjorn