Last active
September 5, 2023 02:26
-
-
Save dzeban/8bde57c1608e467f7a95 to your computer and use it in GitHub Desktop.
jprobes for execve and execveat
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <stdio.h> | |
#include <stdlib.h> | |
#include <unistd.h> | |
int main(int argc, char *argv[]) | |
{ | |
char *newargv[] = { NULL, "-l", NULL }; | |
char *newenviron[] = { NULL }; | |
newargv[0] = argv[1]; | |
execve(argv[1], newargv, newenviron); | |
/* execve returns only on error */ | |
perror("execve"); | |
return 0; | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <linux/kernel.h> | |
#include <linux/module.h> | |
#include <linux/kprobes.h> | |
/* Proxy routine having the same arguments as actual do_execve() routine */ | |
int jdo_execve(struct filename *filename, | |
const char __user *const __user *__argv, | |
const char __user *const __user *__envp) | |
{ | |
pr_info("jprobe: execve: %s\n", filename->name); | |
/* Always end with a call to jprobe_return(). */ | |
jprobe_return(); | |
return 0; | |
} | |
/* Proxy routine having the same arguments as actual do_execveat() routine */ | |
int jdo_execveat(int fd, struct filename *filename, | |
const char __user *const __user *__argv, | |
const char __user *const __user *__envp, | |
int flags) | |
{ | |
pr_info("jprobe: execveat: %s\n", filename->name); | |
/* Always end with a call to jprobe_return(). */ | |
jprobe_return(); | |
return 0; | |
} | |
static struct jprobe jprobe_execve = { | |
.entry = jdo_execve, | |
.kp = { | |
.symbol_name = "do_execve", | |
}, | |
}; | |
static struct jprobe jprobe_execveat = { | |
.entry = jdo_execveat, | |
.kp = { | |
.symbol_name = "do_execveat", | |
}, | |
}; | |
static int __init jprobe_init(void) | |
{ | |
int ret; | |
ret = register_jprobe(&jprobe_execve); | |
if (ret < 0) { | |
pr_info("register_jprobe failed, returned %d\n", ret); | |
return -1; | |
} | |
pr_info("Planted jprobe at %p, handler addr %p\n", | |
jprobe_execve.kp.addr, jprobe_execve.entry); | |
ret = register_jprobe(&jprobe_execveat); | |
if (ret < 0) { | |
pr_info("register_jprobe failed, returned %d\n", ret); | |
return -1; | |
} | |
pr_info("Planted jprobe at %p, handler addr %p\n", | |
jprobe_execveat.kp.addr, jprobe_execveat.entry); | |
return 0; | |
} | |
static void __exit jprobe_exit(void) | |
{ | |
unregister_jprobe(&jprobe_execve); | |
pr_info("Unregistered execve jprobe\n"); | |
unregister_jprobe(&jprobe_execveat); | |
pr_info("Unregistered execveat jprobe\n"); | |
} | |
module_init(jprobe_init) | |
module_exit(jprobe_exit) | |
MODULE_LICENSE("GPL"); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
hello,I have two same machines, both are x86 architecture, ubuntu with kernel version 4.4.131.,when i try to printk "const char __user *const __user *__argv",the one is running,the other kernel panic. if i should change some configs to make program read user space data?