Jprobes
Use
Similar to Kprobes and return probes, the difference is that Kprobes can insert a probe at any instruction, jprobes insert the probe only at the function entrance, and return probes insert the probe when the function returns.
"Interface description""Reference samples/kprobes/jprobe_example.c"
#include <linux/kprobes.h>
int register_jprobe (struct jprobe *jp);
void Unregister_jprobe (struct jprobe *jp);
int enable_jprobe (struct jprobe *jp);
int disable_jprobe (struct jprobe *jp);
"Foreign article"
I'm going to write about this one. Precautions for using Kprobe and Jprobe:
Handler that are registered with Kprobe and Retprobe run in the Atomic (atomic) context because they are in a handler function that runs in the INT3 exception handler or debug (Debug) interrupt, and both are executed under the premise of shutting down the current CPU interrupt. In contrast, jprobe is much more flexible, and the execution environment of the handler that is registered with it is no different from the original execution environment, and the stack environment and CPU registers are the same.
Because Jprobe performs a user-registered handler before having to save the field (mainly the value of the CPU register before the INT3), Jprobe handler is not able to destroy the value of the register, but can change the value of the variable in the stack, Kprobe will not have these restrictions, it has full access to the system, on the other hand, Kprobe is much more dangerous than jprobe, if simply print some system information, recommend with Jprobe, do not risk!
The jprobe mechanism is similar to the implementation of the setjmp and longjmp of the user space, in fact, the annotation part of its kernel code is also analogous, so the code snippet registered with Register_jprobe must finally be returned with Jprobe_return, Of course, unless you want it to be gone forever. This is just like the handler registered with Kprobe must be a function that can be returned. So far, so much can be thought of.
BTW: Look at the kernel code of Kprobe, found some places still some defects, such as some places with preempt_disable () closed preemption, but when the function error returned, and did not open preemption. Do not know the latest kernel has not fixed these details, too lazy to see, there should be no official hairstyle version will open this option. So the article title mentioned in the possibility of injection is relatively small, originally this thing appeared in the background is to facilitate the debugging of the kernel developer work!
Instance
/*JPROBE_TEST.C * *
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/fs.h>
#include <linux/uio.h>
#include <linux/kprobes.h>
#include <linux/kallsyms.h>
/*
* Jumper probe for Do_fork.
* Mirror principle enables access to arguments of the probed routine
* From the probe handler.
*/
/* Proxy routine having the same arguments as actual do_fork () routine */
Long Jdo_fork (
unsigned long clone_flags,
unsigned long Stack_start,
struct Pt_regs *regs,
unsigned long stack_size,
int __user * Parent_tidptr,
int __user * child_tidptr) {
PRINTK ("Jprobe:clone_flags=0x%lx, STACK_SIZE=0X%LX, regs=0x%p\n", Clone_flags, Stack_size, regs);
/* always end with a call to Jprobe_return (). */
Jprobe_return ();
/*notreached*/
return 0;
}
static struct Jprobe My_jprobe = {
. Entry = (kprobe_opcode_t *) jdo_fork
};
int Init_module (void) {
int ret;
MY_JPROBE.KP.ADDR = (kprobe_opcode_t *) kallsyms_lookup_name ("Do_fork");
if (!MY_JPROBE.KP.ADDR) {
PRINTK ("couldn ' t find%s to plant jprobe\n", "do_fork");
return-1;
}
if (ret = Register_jprobe (&my_jprobe)) <0) {
PRINTK ("Register_jprobe failed, returned%d\n", ret);
return-1;
}
PRINTK ("Planted jprobe at%p, handler addr%p\n", my_jprobe.kp.addr, My_jprobe.entry);
return 0;
}
void Cleanup_module (void) {unregister_jprobe (&my_jprobe); PRINTK ("Jprobe unregistered\n"); }
Module_license ("GPL");
Summary of Linux kernel debugging methods Jprobes