首页
论坛
课程
招聘
[原创](arm入门)反汇编分析一个arm函数调用的生死因果
2013-7-18 11:05 33180

[原创](arm入门)反汇编分析一个arm函数调用的生死因果

2013-7-18 11:05
33180
arm的资料没有x86丰富,但搞安卓底层又绕不开这个。我作为一个初学者走了不少弯路,那么现在我用一个实际的例子来分析一个最简单的arm函数调用过程,希望能帮到大家,如果有理解不正确之处请高手指出。

注:这里的指令实际上是thumb(thumb2?),每个指令2字节

C源码:------------------------------------------------------------------
#include <stdio.h>
#include <dlfcn.h>

void (*func)();
  
void sub() {
  void *p = dlopen("libxxx.so", RTLD_NOW);
  if (!p) {
    return;
  }
  else {
    // myfn是libxxx.so的一个函数,作用是打印"call myfn...!"
    func = (void (*)())dlsym(p,"myfn");
    func();
  }
}

int main()
{
  printf("RTLD_NOW=%d\n", RTLD_NOW);
  sub();
  return 0;
}

运行结果---------------------------------------------------------------


反汇编分析-------------------------------------------------------------
sub:
1.    84a0:  4808        ldr  r0, [pc, #32]  ; (84c4 <printf@plt+0x6c>)
2.    84a2:  2100        movs  r1, #0
3.    84a4:  b510        push  {r4, lr}
4.    84a6:  4c08        ldr  r4, [pc, #32]  ; (84c8 <printf@plt+0x70>)
5.    84a8:  4478        add  r0, pc
6.    84aa:  447c        add  r4, pc
7.    84ac:  f7ff efc8   blx  8440 <dlopen@plt>
8.    84b0:  b138        cbz  r0, 84c2 <printf@plt+0x6a>
9.    84b2:  4906        ldr  r1, [pc, #24]  ; (84cc <printf@plt+0x74>)
10.   84b4:  4479        add  r1, pc
11.   84b6:  f7ff efca   blx  844c <dlsym@plt>
12.   84ba:  4905        ldr  r1, [pc, #20]  ; (84d0 <printf@plt+0x78>)
13.   84bc:  5863        ldr  r3, [r4, r1]
14.   84be:  6018        str  r0, [r3, #0]
15.   84c0:  4780        blx  r0
16.   84c2:  bd10        pop  {r4, pc}



//   为5.做准备
1.   r0 = [0x84a0+4+32] = [0x84c4] = 0x48 

//   dlopen的参数2
2.   r1 = 0  

//   lr是sub的返回地址
3.   r4,lr 入栈 

//   为6.做准备
//   必须对齐到(0,4,8,c),所以0x84ca变成0x84c8
4.   r4 = [0x84a6+4+32] = [0x84ca] = [0x84c8] = 0xc26

//   dlopen的参数1 -> 0x84f4处存放字符串libxxx.so
5.   r0 = 0x48+0x84a8+4 = 0x84f4 

//   为13.做准备
6.   r4 = 0xc26+0x84aa+4= 0x90D4

//   参数r0&r1,返回值r0
7.   call dlopen

//   如果r0为0,则跳转到0x84c2
8.   条件跳转

//   为10.做准备
//   ce对齐到cc
9.   r1 = [0x84b2+4+24] = [0x84CE] = [0x84cc] = 0x46

//   dlsym的参数2 -> 0x84FE处存放字符串myfn
10.  r1 = 0x46+0x84b4+4 = 0x84FE

//   参数r0&r1,返回值r0,这个返回值就是myfn的地址
11.  call dlsym

//   为13.做准备
//   d2对齐到d0
12.  r1 = [0x84ba+4+20] = [0x84D2] = [0x84d0] = 0xfffffffc

//   r3是用来干嘛的呢,见14.
13.  r3 = [0x90D4+0xfffffffc] = [0x90d0] = 0x90f0

//   将myfn的地址保存
14.  [0x90f0] = r0

15.  call myfn

16.  出栈,将lr放入pc,该sub返回

修改--------------------------------------------------------------------
从以上分析得知,12-14行的作用是将myfn的地址缓存以便加快以后重复的调用(该程序只调用了一次)
如果这个分析是正确的,那么将12-14行去掉应该不会影响程序的正常执行

下面是试验(将12-14行替换成nop,机器码0xc046):


修改后的运行结果:


程序执行正常。

[看雪官方培训] Unicorn Trace还原Ollvm算法!《安卓高级研修班》2021年秋季班火热招生!!

上传的附件:
收藏
点赞0
打赏
分享
最新回复 (23)
雪    币: 23
活跃值: 活跃值 (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
zhouxgang 活跃值 2013-7-18 11:11
2
0
c涨姿势了
雪    币: 425
活跃值: 活跃值 (12)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
abcshijian 活跃值 2013-7-18 11:19
3
0
对新手很有帮助的说,THX。。。
雪    币: 1781
活跃值: 活跃值 (46)
能力值: ( LV9,RANK:370 )
在线值:
发帖
回帖
粉丝
fosom 活跃值 8 2013-7-18 11:30
4
0
顶一个,,,
雪    币: 114
活跃值: 活跃值 (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
dahwa 活跃值 2013-7-18 11:40
5
0
做个系列吧,系统的普及一下,造福人类!
雪    币: 485
活跃值: 活跃值 (281)
能力值: ( LV3,RANK:30 )
在线值:
发帖
回帖
粉丝
猫子 活跃值 2013-7-18 12:02
6
0
先做个Mark吧!
雪    币: 218
能力值: (RANK:10 )
在线值:
发帖
回帖
粉丝
逍遥枷锁 活跃值 2013-7-18 12:23
7
0
顶一下,表示来学习的,
雪    币: 86
活跃值: 活跃值 (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
threewind 活跃值 2013-7-21 00:08
8
0