反汇编 之C 用指针和目标地址运算调用函数

#include <stdio.h>

/*
 * 用指针和复杂的目标地址运算来调用函数
 */

int func1()
{
    return 1;
}

int func2()
{
    return 2;
}

int func3()
{
    return 3;
}

void main()
{
    int x;
    long a[3] = {(long)func1, (long)(func2), (long)func3};
    int (*f)();

    for (x = 0; x < 3; x++) {
        f = (int (*)())a[x];
        f();
    }
}

#if 0

/*
 * intel
 */

0000000000001149 <func1>:
    1149:    f3 0f 1e fa              endbr64
    114d:    55                       push   %rbp            // rbp=rsp, rsp+8 ===> movq %rsp,(%rbp), addq $8, (%rsp)
    114e:    48 89 e5                 mov    %rsp,%rbp    // rbp = rsp
    1151:    b8 01 00 00 00           mov    $0x1,%eax    // return 1
    1156:    5d                       pop    %rbp            // rbp=rsp, rsp+8 ===> movq %rsp,(%rbp), addq $8, (%rsp)
    1157:    c3                       retq                // ===> pop %rip

0000000000001158 <func2>:
    1158:    f3 0f 1e fa              endbr64
    115c:    55                       push   %rbp
    115d:    48 89 e5                 mov    %rsp,%rbp
    1160:    b8 02 00 00 00           mov    $0x2,%eax    // return 2
    1165:    5d                       pop    %rbp
    1166:    c3                       retq   

0000000000001167 <func3>:
    1167:    f3 0f 1e fa              endbr64
    116b:    55                       push   %rbp
    116c:    48 89 e5                 mov    %rsp,%rbp
    116f:    b8 03 00 00 00           mov    $0x3,%eax    // return 3
    1174:    5d                       pop    %rbp
    1175:    c3                       retq   

0000000000001176 <main>:
    1176:    f3 0f 1e fa              endbr64
    117a:    55                       push   %rbp            // rbp=rsp, rsp+8 ===> movq %rsp,(%rbp), addq $8, (%rsp)
    117b:    48 89 e5                 mov    %rsp,%rbp    // rbp = rsp
    117e:    48 83 ec 30              sub    $0x30,%rsp    // rsp = rsp-0x30
    1182:    64 48 8b 04 25 28 00     mov    %fs:0x28,%rax    # 把fs的偏移值x28放入rax
                                                            # 指向特定于线程或定义的结构
                                                            # %fs:0x28主要是用来起sentinel(哨兵)的作用,
    1189:    00 00
    118b:    48 89 45 f8              mov    %rax,-0x8(%rbp)    # 防止overflow的,即使用了8字节进行安全保护
    118f:    31 c0                    xor    %eax,%eax        # eax 清零
    1191:    48 8d 05 b1 ff ff ff     lea    -0x4f(%rip),%rax        # 1149 <func1>    1198 - 0x4f = 1149
    1198:    48 89 45 e0              mov    %rax,-0x20(%rbp)            // rbp-0x20 = func1
    119c:    48 8d 05 b5 ff ff ff     lea    -0x4b(%rip),%rax        # 1158 <func2>    11a3 - 0x4b = 1158
    11a3:    48 89 45 e8              mov    %rax,-0x18(%rbp)            // rbp-0x18 = func2
    11a7:    48 8d 05 b9 ff ff ff     lea    -0x47(%rip),%rax        # 1167 <func3>    11ae - 0x47 = 1167
    11ae:    48 89 45 f0              mov    %rax,-0x10(%rbp)            // rbp-0x10 = func3

    11b2:    c7 45 d4 00 00 00 00     movl   $0x0,-0x2c(%rbp)            // rbp-0x2c = 0
    11b9:    eb 1d                    jmp    11d8 <main+0x62>            // jump
    11bb:    8b 45 d4                 mov    -0x2c(%rbp),%eax            // eax = rbp-0x2c (0, 1, 2)
    11be:    48 98                    cltq                            // rax <--- eax
    11c0:    48 8b 44 c5 e0           mov    -0x20(%rbp,%rax,8),%rax    // rax = (rbp + [0|1|2] * 8) - 0x20 = [rpb-0x20, rpb-0x18, rbp-0x10]
    11c5:    48 89 45 d8              mov    %rax,-0x28(%rbp)            // rbp-0x28 = rax = function
    11c9:    48 8b 55 d8              mov    -0x28(%rbp),%rdx            // rdx = rbp-0x28 = function
    11cd:    b8 00 00 00 00           mov    $0x0,%eax                // exa = 0
    11d2:    ff d2                    callq  *%rdx                    // function()
    11d4:    83 45 d4 01              addl   $0x1,-0x2c(%rbp)        // rbp-0x2c =+ 1
    11d8:    83 7d d4 02              cmpl   $0x2,-0x2c(%rbp)        // 0x2 - (rbp-0x2c)
    11dc:    7e dd                    jle    11bb <main+0x45>        // <=
    11de:    90                       nop
    11df:    48 8b 45 f8              mov    -0x8(%rbp),%rax        // 防止overflow
    11e3:    64 48 33 04 25 28 00     xor    %fs:0x28,%rax        // fs:0x28 = 0
    11ea:    00 00
    11ec:    74 05                    je     11f3 <main+0x7d>        // 上面xor指令结果为零,执行正常退出,否则溢出检测失败报错
    11ee:    e8 5d fe ff ff           callq  1050 <__stack_chk_fail@plt> // 溢出检测
    11f3:    c9                       leaveq                        // ===> mov %rbp,%rsp, pop %rbp
    11f4:    c3                       retq                        // ===> pop %rip
    11f5:    66 2e 0f 1f 84 00 00     nopw   %cs:0x0(%rax,%rax,1)    // 用于填补func之间的空白功能和main保持位元组对齐的功能
    11fc:    00 00 00
    11ff:    90                       nop

/*
 * armv8
 */

000000000040051c <func1>:
  40051c:    52800020     mov    w0, #0x1                       // #1
  400520:    d65f03c0     ret

0000000000400524 <func2>:
  400524:    52800040     mov    w0, #0x2                       // #2
  400528:    d65f03c0     ret

000000000040052c <func3>:
  40052c:    52800060     mov    w0, #0x3                       // #3
  400530:    d65f03c0     ret

0000000000400534 <main>:
  400534:    a9bc7bfd     stp    x29, x30, [sp, #-64]!    // sp = sp-64, sp=fp=x29, sp+8=lr=x30
  400538:    910003fd     mov    x29, sp                    // fp = sp
  40053c:    90000000     adrp    x0, 400000 <_init-0x3b0>    // x0 = 400000
  400540:    91196000     add    x0, x0, #0x658            // x0 = 400658
  400544:    910063a2     add    x2, x29, #0x18            // x2 = x29(fp)+0x18
  400548:    aa0003e3     mov    x3, x0                    // x3 = 400658
  40054c:    a9400460     ldp    x0, x1, [x3]            // x0 = x3[400658], x1 = x3+8[400658+8]
  400550:    a9000440     stp    x0, x1, [x2]            // [x29(fp)+0x18] = x0 = [400658], [x29(fp)+0x18+8] = x1 = [400658+8]
  400554:    f9400860     ldr    x0, [x3, #16]            // x0 = [x3+16] = [400658+16]
  400558:    f9000840     str    x0, [x2, #16]            // x2+16 = [x29(fp)+0x18+16] = x0 = [400658+16]
  40055c:    b9003fbf     str    wzr, [x29, #60]            // x29+60 = 0
  400560:    1400000b     b    40058c <main+0x58>
  400564:    b9803fa0     ldrsw    x0, [x29, #60]        // x0 = x29+60
  400568:    d37df000     lsl    x0, x0, #3                // [0, 8, 16]
  40056c:    910063a1     add    x1, x29, #0x18            // x1 = x29(fp)+0x18
  400570:    f8606820     ldr    x0, [x1, x0]            // x0 = (x29(fp)+0x18) + (0|8|16)
  400574:    f9001ba0     str    x0, [x29, #48]            // save x0
  400578:    f9401ba0     ldr    x0, [x29, #48]            // read x0
  40057c:    d63f0000     blr    x0                        // function()
  400580:    b9403fa0     ldr    w0, [x29, #60]            // w0 = x29+60
  400584:    11000400     add    w0, w0, #0x1            // w0 = 1, 2
  400588:    b9003fa0     str    w0, [x29, #60]            // save w0
  40058c:    b9403fa0     ldr    w0, [x29, #60]            // read w0
  400590:    7100081f     cmp    w0, #0x2                // 0,1,2
  400594:    54fffe8d     b.le    400564 <main+0x30>    // <=
  400598:    d503201f     nop
  40059c:    a8c47bfd     ldp    x29, x30, [sp], #64        // fp=x29 = sp, lr=x30 = sp + 8, sp = sp+64
  4005a0:    d65f03c0     ret
  4005a4:    00000000     .inst    0x00000000 ; undefined

/*
 * armv7
 */

 00010460 <func1>:
   10460:    e52db004     push    {fp}        ; (str fp, [sp, #-4]!)
   10464:    e28db000     add    fp, sp, #0
   10468:    e3a03001     mov    r3, #1
   1046c:    e1a00003     mov    r0, r3
   10470:    e24bd000     sub    sp, fp, #0
   10474:    e49db004     pop    {fp}        ; (ldr fp, [sp], #4)
   10478:    e12fff1e     bx    lr

0001047c <func2>:
   1047c:    e52db004     push    {fp}        ; (str fp, [sp, #-4]!)
   10480:    e28db000     add    fp, sp, #0
   10484:    e3a03002     mov    r3, #2
   10488:    e1a00003     mov    r0, r3
   1048c:    e24bd000     sub    sp, fp, #0
   10490:    e49db004     pop    {fp}        ; (ldr fp, [sp], #4)
   10494:    e12fff1e     bx    lr

00010498 <func3>:
   10498:    e52db004     push    {fp}        ; (str fp, [sp, #-4]!)
   1049c:    e28db000     add    fp, sp, #0
   104a0:    e3a03003     mov    r3, #3
   104a4:    e1a00003     mov    r0, r3
   104a8:    e24bd000     sub    sp, fp, #0
   104ac:    e49db004     pop    {fp}        ; (ldr fp, [sp], #4)
   104b0:    e12fff1e     bx    lr

000104b4 <main>:
   104b4:    e92d4800     push    {fp, lr}
   104b8:    e28db004     add    fp, sp, #4
   104bc:    e24dd018     sub    sp, sp, #24
    int x;
    long a[3] = {(long)func1, (long)(func2), (long)func3};
   104c0:    e59f2054     ldr    r2, [pc, #84]    ; 1051c <main+0x68>            r2 = pc+84 = variable = 10530
   104c4:    e24b3018     sub    r3, fp, #24            ; r3 = fp-24
   104c8:    e8920007     ldm    r2, {r0, r1, r2} ; memory ---> register        r0=r2=10530, r1=r2+4=10534, r2=r2+8=10538
   104cc:    e8830007     stm    r3, {r0, r1, r2} ; register ---> memory        (fp-24)=r0=10530, (fp-20)=r1=10534, (fp-16)=r2=10538
    int (*f)();

    for (x = 0; x < 3; x++) {
   104d0:    e3a03000     mov    r3, #0           ; x = 0
   104d4:    e50b3008     str    r3, [fp, #-8]    ; save x
   104d8:    ea00000a     b    10508 <main+0x54>
        f = (int (*)())a[x];
   104dc:    e51b3008     ldr    r3, [fp, #-8]   ; x
   104e0:    e1a03103     lsl    r3, r3, #2      ; r3 = x << 2 , [0, 4, 8]
   104e4:    e24b2004     sub    r2, fp, #4      ; r2 = fp - 4
   104e8:    e0823003     add    r3, r2, r3      ; r3 = r2 + r3 [0|4|8] --> (fp-4)+[0|4|8]
   104ec:    e5133014     ldr    r3, [r3, #-20]    ; 0xffffffec    r3 = 0:[(fp-4)-20], 1:[(fp-4)+4-20], 2:[(fp-4)+8-20]
   104f0:    e50b300c     str    r3, [fp, #-12]  ; save function address, 0:r3=(fp-24), 1:r3=(fp-20), 2:r3=(fp-16)
        f();
   104f4:    e51b300c     ldr    r3, [fp, #-12] ; load function address
   104f8:    e12fff33     blx    r3             ; execl
{
    int x;
    long a[3] = {(long)func1, (long)(func2), (long)func3};
    int (*f)();

    for (x = 0; x < 3; x++) {
   104fc:    e51b3008     ldr    r3, [fp, #-8]        ; r3 = x
   10500:    e2833001     add    r3, r3, #1            ; r3 = x + 1
   10504:    e50b3008     str    r3, [fp, #-8]        ; fp-8 = x
   10508:    e51b3008     ldr    r3, [fp, #-8]        ; r3 = x
   1050c:    e3530002     cmp    r3, #2                ; 0, 1, 2
   10510:    dafffff1     ble    104dc <main+0x28>    ; <=
        f = (int (*)())a[x];
        f();
    }
}
   10514:    e24bd004     sub    sp, fp, #4
   10518:    e8bd8800     pop    {fp, pc}
   1051c:    00010530     .word    0x00010530

#endif

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值