ARM架构kprobe应用及实现分析(6.0 导出堆栈的值)

本文详细阐述了在ARM架构下通过函数参数导出并打印堆栈数据的过程,包括如何处理超过四个参数的情况,以及如何利用堆栈指针(SP)进行数据的准确定位和展示。通过实际代码示例展示了如何实现堆栈数据的导出与打印,最终输出展示了堆栈中心数据及其周围数据,验证了导出堆栈数据的可信性。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

上篇讲过了导出寄存器的值

但是当函数参数多余4个的话(R0 R1 R2 R3 ),其他的值会保存在堆栈中,所以必须导出SP附近的值才能查看其它参数的值

此函数实现如下:

第一个参数为SP的值,第二个是一SP为中心要打印周围栈的数据

static int dump_arm_stack(unsigned int * _addr , unsigned int addrSize)
{   
   int i=0;
   int j=0;
   int word_per_line=4;
   unsigned int * addr = _addr;
   addr = addr + word_per_line*addrSize;

   for(i=0;i<addrSize*2;i++)
   {
         char * middlestack = "---";
         if(i==addrSize)
         {
            middlestack = "$$$";
         }
         printk(" addr:0x%08x %s 0x%08x 0x%08x 0x%08x 0x%08x \n", \
                                    (addr-(i*word_per_line+0)),\
                                    middlestack, \
                                    *(addr-(i*word_per_line+0)),\
                                    *(addr-(i*word_per_line+1)),\
                                    *(addr-(i*word_per_line+2)),\
                                    *(addr-(i*word_per_line+3)) \
                                    );
   }
   return 0;
}

实际调用(regs->uregs[13] 即为stack pointer):

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);
        dump_arm_stack((unsigned int *)regs->uregs[13],5);
	return 0;
}

当探测到实际printk输出如下:

//导出当时堆栈的值
<4>[ 9749.267927]-(0)[186:adbd] addr:0xdbe8ff80 --- 0xdbe8ffa4 0x00000000 0xdbe8e000 0xc000e0a4
<4>[ 9749.269044]-(0)[186:adbd] addr:0xdbe8ff70 --- 0x00000002 0x00043d34 0x00042ff4 0x00000035
<4>[ 9749.270161]-(0)[186:adbd] addr:0xdbe8ff60 --- 0x00000035 0x80045430 0x00000000 0xc8131300
<4>[ 9749.271278]-(0)[186:adbd] addr:0xdbe8ff50 --- 0xdbe8ff7c 0x00000000 0x00000001 0x00000000
<4>[ 9749.272395]-(0)[186:adbd] addr:0xdbe8ff40 --- 0x00000001 0xc063bd50 0x00000088 0x00000055
<4>[ 9749.273512]-(0)[186:adbd] addr:0xdbe8ff30 $$$ 0x00000044 0xc00872a4 0xc00524fc 0xdbe8ff30   //这里是当时堆栈的中心
<4>[ 9749.274629]-(0)[186:adbd] addr:0xdbe8ff20 --- 0xdbe8ff8c 0x00000000 0xdbe8e000 0xdc38f000
<4>[ 9749.275746]-(0)[186:adbd] addr:0xdbe8ff10 --- 0x00001482 0x00000000 0xdbe8e000 0xc4b6b000
<4>[ 9749.276864]-(0)[186:adbd] addr:0xdbe8ff00 --- 0xc06309f4 0x60000013 0xdbe8ff1c 0xc063bd98
<4>[ 9749.277981]-(0)[186:adbd] addr:0xdbe8fef0 --- 0xc00873c8 0xffffffff 0x60000013 0xc0052368

testAddadd5(0x11,0x22,0x33,mytestbuf,0x44,0x55,0x88);

可以看出上面printk输出红色部分与第5,6,7的传入的参数是一致的。

说明导出的stack的值是可信的。

 

 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值