1.查看系统函数调用关系
dump_state(regs);
利用dump_stack();查看调用关系
2.查看函数地址
# cat /proc/kallsyms | grep ip_rcv
c071c3e0t ip_rcv_finish
c071c9a9 T ip_rcv
kp.addr = (kprobe_opcode_t *)0xc071c9a9;
3.查看函数参数数据
利用jprobes 自定义探测函数,探测函数参数根据目标函数参数和关系的数据定义
#include <linux/module.h>
#include <linux/kprobes.h>
#include <linux/kallsyms.h>
#include <linux/serial_core.h>
struct kprobe kp;
#define uart_circ_empty(circ)((circ)->head == (circ)->tail)
static struct jprobe my_probe;
int handler_pre(struct kprobe *p, structpt_regs *regs)
{
dump_stack();
return 0;
}
void my_handler (struct uart_port *port){
struct circ_buf *xmit;
int i;
xmit = &port->state->xmit;
for(i=xmit->tail-xmit->head;i<0;i--) {
printk("buf[%d]=%x\n",xmit->tail,xmit->buf[xmit->tail]);
xmit->tail = (xmit->tail+ 1);
if (uart_circ_empty(xmit))
break;
}
jprobe_return();
}
static __init int init_kprobe_sample(void)
{
unsigned long ret;
kp.pre_handler = handler_pre;
ret = kallsyms_lookup_name("serial_omap_start_tx");
printk("ret=%lx\n",ret);
kp.addr=(kprobe_opcode_t *) ret;
register_kprobe(&kp);
my_probe.kp.addr = (kprobe_opcode_t *)0x0c01fd680;
my_probe.entry = (kprobe_opcode_t*)my_handler;
register_jprobe(&my_probe);
return 0;
}
static __exit void cleanup_kprobe_sample(void)
{
unregister_jprobe(&my_probe);
unregister_kprobe(&kp);
}
module_init(init_kprobe_sample);
module_exit(cleanup_kprobe_sample);
MODULE_LICENSE("GPL");