kprobe: update example with px

Going to try and upstream this later on
This commit is contained in:
Ciro Santilli
2018-07-05 09:49:59 +01:00
parent 046bc25b6b
commit 3d4e0c095d
3 changed files with 35 additions and 33 deletions

View File

@@ -4405,26 +4405,38 @@ TODO: can you get function arguments? https://stackoverflow.com/questions/276087
==== Kprobes
kprobes is an instrumentation mechanism that injects arbitrary code at a given address in a trap instruction, much like GDB. Oh, the good old kernel. :-)
....
./build -C 'CONFIG_KPROBES=y'
./run -F 'insmod /kprobe_example.ko && sleep 4 & sleep 4 &'
....
Then on guest:
....
insmod /kprobe_example.ko
sleep 4 & sleep 4 &'
....
Outcome: dmesg outputs on every fork:
....
<_do_fork> pre_handler: p->addr = 0x00000000e1360063, ip = ffffffff810531d1, flags = 0x246
<_do_fork> post_handler: p->addr = 0x00000000e1360063, flags = 0x246
<_do_fork> pre_handler: p->addr = 0x00000000e1360063, ip = ffffffff810531d1, flags = 0x246
<_do_fork> post_handler: p->addr = 0x00000000e1360063, flags = 0x246
....
Source: link:kernel_module/kprobe_example.c[]
Outcome: every fork spits out some extra printks of type:
TODO: it does not work if I try to immediately launch `sleep`, why?
....
<6>[ 2.011117] <_do_fork> pre_handler: p->addr = 0x00000000e1360063, ip = ffffffff810531d1, flags = 0x246
<6>[ 2.011622] <_do_fork> post_handler: p->addr = 0x00000000e1360063, flags = 0x246
<6>[ 2.021860] <_do_fork> pre_handler: p->addr = 0x00000000e1360063, ip = ffffffff810531d1, flags = 0x246
<6>[ 2.022331] <_do_fork> post_handler: p->addr = 0x00000000e1360063, flags = 0x246
insmod /kprobe_example.ko && sleep 4 & sleep 4 &
....
Docs: https://github.com/torvalds/linux/blob/v4.16/Documentation/kprobes.txt
Injects arbitrary code at a given address in a trap instruction, much like GDB. Oh the good old kernel. :-)
I don't think your code can refer to the surrounding kernel code however: the only visible thing is the value of the registers.
You can then hack it up to read the stack and read argument values, but do you really want to?

View File

@@ -1,5 +1,3 @@
/* Upstream: https://github.com/torvalds/linux/blob/v4.16/samples/kprobes/kprobe_example.c */
/*
* NOTE: This example is works on x86 and powerpc.
* Here's a sample kernel module showing the use of kprobes to dump a
@@ -29,28 +27,24 @@ static struct kprobe kp = {
static int handler_pre(struct kprobe *p, struct pt_regs *regs)
{
#ifdef CONFIG_X86
pr_info("<%s> pre_handler: p->addr = 0x%p, ip = %lx, flags = 0x%lx\n",
pr_info("<%s> pre_handler: p->addr = 0x%px, ip = %lx, flags = 0x%lx\n",
p->symbol_name, p->addr, regs->ip, regs->flags);
#endif
#ifdef CONFIG_PPC
pr_info("<%s> pre_handler: p->addr = 0x%p, nip = 0x%lx, msr = 0x%lx\n",
pr_info("<%s> pre_handler: p->addr = 0x%px, nip = 0x%lx, msr = 0x%lx\n",
p->symbol_name, p->addr, regs->nip, regs->msr);
#endif
#ifdef CONFIG_MIPS
pr_info("<%s> pre_handler: p->addr = 0x%p, epc = 0x%lx, status = 0x%lx\n",
pr_info("<%s> pre_handler: p->addr = 0x%px, epc = 0x%lx, status = 0x%lx\n",
p->symbol_name, p->addr, regs->cp0_epc, regs->cp0_status);
#endif
#ifdef CONFIG_TILEGX
pr_info("<%s> pre_handler: p->addr = 0x%p, pc = 0x%lx, ex1 = 0x%lx\n",
p->symbol_name, p->addr, regs->pc, regs->ex1);
#endif
#ifdef CONFIG_ARM64
pr_info("<%s> pre_handler: p->addr = 0x%p, pc = 0x%lx,"
pr_info("<%s> pre_handler: p->addr = 0x%px, pc = 0x%lx,"
" pstate = 0x%lx\n",
p->symbol_name, p->addr, (long)regs->pc, (long)regs->pstate);
#endif
#ifdef CONFIG_S390
pr_info("<%s> pre_handler: p->addr, 0x%p, ip = 0x%lx, flags = 0x%lx\n",
pr_info("<%s> pre_handler: p->addr, 0x%px, ip = 0x%lx, flags = 0x%lx\n",
p->symbol_name, p->addr, regs->psw.addr, regs->flags);
#endif
@@ -63,27 +57,23 @@ static void handler_post(struct kprobe *p, struct pt_regs *regs,
unsigned long flags)
{
#ifdef CONFIG_X86
pr_info("<%s> post_handler: p->addr = 0x%p, flags = 0x%lx\n",
pr_info("<%s> post_handler: p->addr = 0x%px, flags = 0x%lx\n",
p->symbol_name, p->addr, regs->flags);
#endif
#ifdef CONFIG_PPC
pr_info("<%s> post_handler: p->addr = 0x%p, msr = 0x%lx\n",
pr_info("<%s> post_handler: p->addr = 0x%px, msr = 0x%lx\n",
p->symbol_name, p->addr, regs->msr);
#endif
#ifdef CONFIG_MIPS
pr_info("<%s> post_handler: p->addr = 0x%p, status = 0x%lx\n",
pr_info("<%s> post_handler: p->addr = 0x%px, status = 0x%lx\n",
p->symbol_name, p->addr, regs->cp0_status);
#endif
#ifdef CONFIG_TILEGX
pr_info("<%s> post_handler: p->addr = 0x%p, ex1 = 0x%lx\n",
p->symbol_name, p->addr, regs->ex1);
#endif
#ifdef CONFIG_ARM64
pr_info("<%s> post_handler: p->addr = 0x%p, pstate = 0x%lx\n",
pr_info("<%s> post_handler: p->addr = 0x%px, pstate = 0x%lx\n",
p->symbol_name, p->addr, (long)regs->pstate);
#endif
#ifdef CONFIG_S390
pr_info("<%s> pre_handler: p->addr, 0x%p, flags = 0x%lx\n",
pr_info("<%s> pre_handler: p->addr, 0x%px, flags = 0x%lx\n",
p->symbol_name, p->addr, regs->flags);
#endif
}
@@ -95,7 +85,7 @@ static void handler_post(struct kprobe *p, struct pt_regs *regs,
*/
static int handler_fault(struct kprobe *p, struct pt_regs *regs, int trapnr)
{
pr_info("fault_handler: p->addr = 0x%p, trap #%dn", p->addr, trapnr);
pr_info("fault_handler: p->addr = 0x%px, trap #%dn", p->addr, trapnr);
/* Return 0 because we don't handle the fault. */
return 0;
}
@@ -112,14 +102,14 @@ static int __init kprobe_init(void)
pr_err("register_kprobe failed, returned %d\n", ret);
return ret;
}
pr_info("Planted kprobe at %p\n", kp.addr);
pr_info("Planted kprobe at %px\n", kp.addr);
return 0;
}
static void __exit kprobe_exit(void)
{
unregister_kprobe(&kp);
pr_info("kprobe at %p unregistered\n", kp.addr);
pr_info("kprobe at %px unregistered\n", kp.addr);
}
module_init(kprobe_init)

View File

@@ -207,7 +207,7 @@ static int pci_probe(struct pci_dev *dev, const struct pci_device_id *id)
/* RAM -> device. */
vaddr_from = dma_alloc_coherent(&(dev->dev), 4, &dma_handle_from, GFP_ATOMIC);
dev_info(&(dev->dev), "vaddr_from = %p\n", vaddr_from);
dev_info(&(dev->dev), "vaddr_from = %px\n", vaddr_from);
dev_info(&(dev->dev), "dma_handle_from = %llx\n", (unsigned long long)dma_handle_from);
*((volatile u32*)vaddr_from) = 0x12345678;
iowrite32((u32)dma_handle_from, mmio + IO_DMA_SRC);
@@ -217,7 +217,7 @@ static int pci_probe(struct pci_dev *dev, const struct pci_device_id *id)
/* device -> RAM. */
vaddr_to = dma_alloc_coherent(&(dev->dev), 4, &dma_handle_to, GFP_ATOMIC);
dev_info(&(dev->dev), "vaddr_to = %p\n", vaddr_to);
dev_info(&(dev->dev), "vaddr_to = %px\n", vaddr_to);
dev_info(&(dev->dev), "dma_handle_to = %llx\n", (unsigned long long)dma_handle_to);
/*
iowrite32(DMA_BASE, mmio + IO_DMA_SRC);