逆向-beginners之switch少量case

#include <stdio.h>

void f(int a)
{
    switch(a) {
        case 0: printf("zero\n");
                break;
        case 1: printf("one\n");
                break;
        case 2: printf("two\n");
                break;
        default: printf("something unknown\n"); 
                 break;
    }
}

int main()
{
    f(2);
}

#if 0

如果仅从汇编代码入手,无法判断上述函数是一个判断表达式较少的switch()语句、还是一组if语句。
确实可以认为,switch()语句是一种旨在简化大量嵌套if()语句设计的语法。

mov eax, [esp-4]
sub exa, 0
这两条指令可以检查EAX的值是否是零。如果EAX的值是零,ZF会被置1(也就是说0-0=1,这就可以提前设置ZF标志位),并会触发第一条条件转移
指令JE。如果EAX的值仍然不是零,则不会触发第一条转移指令。
做"eax=eax-1"的运算,若计算结果是零则做相应输出。

在把字符串指针存储到变量a之后,函数使用JMP调用printf。在调用printf函数的时候,调用方函数而没有使用常规的call指令。
这点不难释:调用方函数把参数推送入栈之后,的确通常通过CALL指令调用其他函数。这种情况下,CALL会把返回地址推送入栈、并通过
无条件转移的手段启用被调用方函数。

#endif

#if 0
/*
 * intel
 */

0000000000001149 <f>:
    1149:    f3 0f 1e fa              endbr64
    114d:    55                       push   %rbp
    114e:    48 89 e5                 mov    %rsp,%rbp
    1151:    48 83 ec 10              sub    $0x10,%rsp        // rsp=rsp-0x10
    1155:    89 7d fc                 mov    %edi,-0x4(%rbp)    // parameter=a
    1158:    83 7d fc 02              cmpl   $0x2,-0x4(%rbp)    // a-2
    115c:    74 30                    je     118e <f+0x45>    // 2-2=0, zf=1, jump
    115e:    83 7d fc 02              cmpl   $0x2,-0x4(%rbp)    // a-2
    1162:    7f 38                    jg     119c <f+0x53>    // ((SF xor OF) or ZF) = 0, jump
    1164:    83 7d fc 00              cmpl   $0x0,-0x4(%rbp)    // a-0
    1168:    74 08                    je     1172 <f+0x29>    // 0-0=0, zf=1, jump,
    116a:    83 7d fc 01              cmpl   $0x1,-0x4(%rbp)    // a-1
    116e:    74 10                    je     1180 <f+0x37>    // 1-1=0, zf=1, jump
    1170:    eb 2a                    jmp    119c <f+0x53>
    1172:    48 8d 3d 8b 0e 00 00     lea    0xe8b(%rip),%rdi        # 2004 <_IO_stdin_used+0x4>
    1179:    e8 d2 fe ff ff           callq  1050 <puts@plt>
    117e:    eb 29                    jmp    11a9 <f+0x60>    // break
    1180:    48 8d 3d 82 0e 00 00     lea    0xe82(%rip),%rdi        # 2009 <_IO_stdin_used+0x9>
    1187:    e8 c4 fe ff ff           callq  1050 <puts@plt>
    118c:    eb 1b                    jmp    11a9 <f+0x60>
    118e:    48 8d 3d 78 0e 00 00     lea    0xe78(%rip),%rdi        # 200d <_IO_stdin_used+0xd>
    1195:    e8 b6 fe ff ff           callq  1050 <puts@plt>
    119a:    eb 0d                    jmp    11a9 <f+0x60>
    119c:    48 8d 3d 6e 0e 00 00     lea    0xe6e(%rip),%rdi        # 2011 <_IO_stdin_used+0x11>
    11a3:    e8 a8 fe ff ff           callq  1050 <puts@plt>
    11a8:    90                       nop
    11a9:    90                       nop
    11aa:    c9                       leaveq
    11ab:    c3                       retq   

00000000000011ac <main>:
    11ac:    f3 0f 1e fa              endbr64
    11b0:    55                       push   %rbp
    11b1:    48 89 e5                 mov    %rsp,%rbp
    11b4:    bf 02 00 00 00           mov    $0x2,%edi
    11b9:    e8 8b ff ff ff           callq  1149 <f>
    11be:    b8 00 00 00 00           mov    $0x0,%eax
    11c3:    5d                       pop    %rbp
    11c4:    c3                       retq   
    11c5:    66 2e 0f 1f 84 00 00     nopw   %cs:0x0(%rax,%rax,1)
    11cc:    00 00 00
    11cf:    90                       nop

/*
 * arm
 */
000000000040055c <f>:
  40055c:    a9be7bfd     stp    x29, x30, [sp, #-32]!
  400560:    910003fd     mov    x29, sp
  400564:    b9001fa0     str    w0, [x29, #28]
  400568:    b9401fa0     ldr    w0, [x29, #28]
  40056c:    7100041f     cmp    w0, #0x1            // 1
  400570:    54000120     b.eq    400594 <f+0x38>  // b.none
  400574:    7100081f     cmp    w0, #0x2            // 2
  400578:    54000160     b.eq    4005a4 <f+0x48>  // b.none
  40057c:    7100001f     cmp    w0, #0x0
  400580:    540001a1     b.ne    4005b4 <f+0x58>  // b.any
  400584:    90000000     adrp    x0, 400000 <_init-0x3e8>    // =0
  400588:    911a8000     add    x0, x0, #0x6a0
  40058c:    97ffffb1     bl    400450 <puts@plt>
  400590:    1400000d     b    4005c4 <f+0x68>                // break;
  400594:    90000000     adrp    x0, 400000 <_init-0x3e8>    // =1
  400598:    911aa000     add    x0, x0, #0x6a8
  40059c:    97ffffad     bl    400450 <puts@plt>
  4005a0:    14000009     b    4005c4 <f+0x68>
  4005a4:    90000000     adrp    x0, 400000 <_init-0x3e8>    // =2
  4005a8:    911ac000     add    x0, x0, #0x6b0
  4005ac:    97ffffa9     bl    400450 <puts@plt>
  4005b0:    14000005     b    4005c4 <f+0x68>
  4005b4:    90000000     adrp    x0, 400000 <_init-0x3e8>    // !=0
  4005b8:    911ae000     add    x0, x0, #0x6b8
  4005bc:    97ffffa5     bl    400450 <puts@plt>
  4005c0:    d503201f     nop
  4005c4:    d503201f     nop
  4005c8:    a8c27bfd     ldp    x29, x30, [sp], #32
  4005cc:    d65f03c0     ret

00000000004005d0 <main>:
  4005d0:    a9bf7bfd     stp    x29, x30, [sp, #-16]!
  4005d4:    910003fd     mov    x29, sp
  4005d8:    52800040     mov    w0, #0x2                       // #2
  4005dc:    97ffffe0     bl    40055c <f>
  4005e0:    52800000     mov    w0, #0x0                       // #0
  4005e4:    a8c17bfd     ldp    x29, x30, [sp], #16
  4005e8:    d65f03c0     ret
  4005ec:    00000000     .inst    0x00000000 ; undefined
#endif
 

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值