ARM架构kprobe应用及实现分析(5.0 打印寄存器的值)

kp.pre_handler = handler_pre;

在此函数中打印寄存器的值,才能对我们分析当时的情况有帮助。(如查看调用函数的参数值等)

static int handler_pre(struct kprobe *p, struct pt_regs *regs)
{
        printk(" kprobes name is %s pt_regs size is %d \n",p->symbol_name,sizeof(regs->uregs));
	return 0;
}

下面是生产一个寄存器对应的索引及寄存器的名字(用途),具体可以参考ARM的相关资料

一共18个寄存器

struct pt_regs {
 long uregs[18];
};

下面很多地方也用到了此数组的生成方法(perror等),我也班门弄斧下:)

struct Pair {
  const char* msg;
  int code;
};
#define  _ARM_REG_DEF(x,y)  { #x, y },
struct Pair _arm_register_strings[] = {
_ARM_REG_DEF(ARM_cpsr	        ,16)
_ARM_REG_DEF(ARM_pc		,15)
_ARM_REG_DEF(ARM_lr		,14)
_ARM_REG_DEF(ARM_sp		,13)
_ARM_REG_DEF(ARM_ip		,12)
_ARM_REG_DEF(ARM_fp		,11)
_ARM_REG_DEF(ARM_r10		,10)
_ARM_REG_DEF(ARM_r9		,9)
_ARM_REG_DEF(ARM_r8		,8)
_ARM_REG_DEF(ARM_r7		,7)
_ARM_REG_DEF(ARM_r6		,6)
_ARM_REG_DEF(ARM_r5		,5)
_ARM_REG_DEF(ARM_r4		,4)
_ARM_REG_DEF(ARM_r3		,3)
_ARM_REG_DEF(ARM_r2		,2)
_ARM_REG_DEF(ARM_r1		,1)
_ARM_REG_DEF(ARM_r0	        ,0)
_ARM_REG_DEF(ARM_ORIG_r0	,17)
};

dump出所有寄存器的值:

struct pt_regs regs;
char * name = NULL;
static int dump_arm_regs(unsigned long * buf)
{   
   int i=0;
   int j=0;
   char * detail = NULL;
   for(i=0;i<18;i++)
   {
      for (j=0;j<sizeof(_arm_register_strings);j++)
      {
         if(_arm_register_strings[j].code==i)
         {
            detail = _arm_register_strings[j].msg;
            break;
         }
      }
      printk(" %s  %02d : 0x%08x  : %10d : %20s\n",name,i,*(buf+i),*(buf+i),detail);
   }
   return 0;
}

最后handler_pre回调的时候,调用dump_arm_regs 到处所有寄存器的值,以便分析之用

static int handler_pre(struct kprobe *p, struct pt_regs *regs)
{
        printk(" kprobes name is %s pt_regs size is %d \n",p->symbol_name,sizeof(regs->uregs));
        dump_arm_regs(regs->uregs);
	return 0;
}
导出当时寄存器的值:
kprobes name is testAddadd5 pt_regs size is 72 
testAddadd5  00 : 0x00000011  :         17 :               ARM_r0
testAddadd5  01 : 0x00000022  :         34 :               ARM_r1
testAddadd5  02 : 0x00000033  :         51 :               ARM_r2
testAddadd5  03 : 0xc077c670  : -1065892240 :               ARM_r3
testAddadd5  04 : 0xc4b6b000  : -994660352 :               ARM_r4
testAddadd5  05 : 0xdbe8e000  : -605495296 :               ARM_r5
testAddadd5  06 : 0x00000000  :          0 :               ARM_r6
testAddadd5  07 : 0x00001482  :       5250 :               ARM_r7
testAddadd5  08 : 0xdc38f000  : -600248320 :               ARM_r8
testAddadd5  09 : 0xdbe8e000  : -605495296 :               ARM_r9
testAddadd5  10 : 0x00000000  :          0 :               ARM_r9
testAddadd5  11 : 0xdbe8ff8c  : -605487220 :               ARM_fp
testAddadd5  12 : 0x00000088  :        136 :               ARM_ip
testAddadd5  13 : 0xdbe8ff30  : -605487312 :               ARM_sp
testAddadd5  14 : 0xc005253c  : -1073404612 :               ARM_lr
testAddadd5  15 : 0xc0052368  : -1073405080 :               ARM_pc
testAddadd5  16 : 0x60000013  : 1610612755 :             ARM_cpsr
testAddadd5  17 : 0xffffffff  :         -1 :          ARM_ORIG_r0



ARM_pc == 0xc0052368
且system.map中: c0052368 T testAddadd5
两者相等与设想的一致

且 c0052538: ebffff8a  bl c0052368 <testAddadd5>
调用BL之后LR寄存器应该保存的是下一条指令的地址即:c005253c = c0052538 + 4
testAddadd5  14 : 0xc005253c  : -1073404612 :               ARM_lr
上面两者也一致,证明这个时候导出的寄存器的值是可信的

R0 R1 R2 R3 保存参数:testAddadd5(0x11,0x22,0x33,mytestbuf
其它参数保存在堆栈中

好了,导出寄存器值就介绍到这里,下篇将介绍导出堆栈的值,先休息了:)

 

 

 

 

 

 

 

 

 

 

 

 

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值