• 开始逆向objc基础准备(二)我的平台是simulator-x86_64


    建项目运行中断调试,lldb中显示寄存器看到有rax-r15, stm0-stm7, xmm0-xmm15, ymm0-ymm15,即为x64体系支持sse4。

    再在lldb中查看寄存器别名得到以下对应:

    rax  
    rbx  
    rcx arg4
    rdx arg3
    rdi arg1
    rsi arg2
    rbp fp
    rsp sp
    r8 arg5
    r9 arg6
    r10  
    r11  
    r12  
    r13  
    r14  
    r15  
    rip pc
    rflags flags
    cs  
    fs  
    gs  

    函数传参数的方式一清二楚,不是以前ia32时代传到街知巷闻的参数从右往左依次压栈的方式(系统调用和__fastcall以及汇编函数除外),函数传参数依次使用rdi,rsi,rdx,rcx,r8,r9。除此之外还用上xmm0-xmm7寄存器。

    请看下面代码:

    /////////////////////////////////////////////////////////////////////
    //
    // SaveRegisters
    //
    // Pushes a stack frame and saves all registers that might contain
    // parameter values.
    //
    // On entry:
    //        stack = ret
    //
    // On exit: 
    //        %rsp is 16-byte aligned
    //    
    /////////////////////////////////////////////////////////////////////
    
    .macro SaveRegisters
    
        push    %rbp
        .cfi_def_cfa_offset 16
        .cfi_offset rbp, -16
        
        mov    %rsp, %rbp
        .cfi_def_cfa_register rbp
        
        sub    $$0x80+8, %rsp        // +8 for alignment
    
        movdqa    %xmm0, -0x80(%rbp)
        push    %rax            // might be xmm parameter count
        movdqa    %xmm1, -0x70(%rbp)
        push    %a1
        movdqa    %xmm2, -0x60(%rbp)
        push    %a2
        movdqa    %xmm3, -0x50(%rbp)
        push    %a3
        movdqa    %xmm4, -0x40(%rbp)
        push    %a4
        movdqa    %xmm5, -0x30(%rbp)
        push    %a5
        movdqa    %xmm6, -0x20(%rbp)
        push    %a6
        movdqa    %xmm7, -0x10(%rbp)
        
    .endmacro

    除了上面提到的寄存器外,r12-r15和rbx的用途能用下面几处反汇编就明白了。

    然后翻看调用栈下几个栈的反汇编:

    14 - CFRunLoopRunSpecific

    15 - -[UIApplication _run]

    16 - UIApplicationMain

    UIKit`UIApplicationMain:
        0x10f0c1bf6 <+0>:   pushq  %rbp
        0x10f0c1bf7 <+1>:   movq   %rsp, %rbp
        0x10f0c1bfa <+4>:   pushq  %r15
        0x10f0c1bfc <+6>:   pushq  %r14
        0x10f0c1bfe <+8>:   pushq  %r13
        0x10f0c1c00 <+10>:  pushq  %r12
        0x10f0c1c02 <+12>:  pushq  %rbx
        0x10f0c1c03 <+13>:  pushq  %rax
        0x10f0c1c04 <+14>:  movq   %rcx, %rbx
        0x10f0c1c07 <+17>:  movq   %rsi, %r15
        0x10f0c1c0a <+20>:  movl   %edi, %r12d
    UIKit`-[UIApplication _run]:
        0x10f0bce26 <+0>:   pushq  %rbp
        0x10f0bce27 <+1>:   movq   %rsp, %rbp
        0x10f0bce2a <+4>:   pushq  %r15
        0x10f0bce2c <+6>:   pushq  %r14
        0x10f0bce2e <+8>:   pushq  %r12
        0x10f0bce30 <+10>:  pushq  %rbx
        0x10f0bce31 <+11>:  movq   %rdi, %rbx
        0x10f0bce34 <+14>:  callq  0x10fb23e34               ; symbol stub for: objc_autoreleasePoolPush
        0x10f0bce39 <+19>:  movq   %rax, %r14
        0x10f0bce3c <+22>:  xorl   %eax, %eax
        0x10f0bce3e <+24>:  callq  0x10f4c6d50               ; _UIAccessibilityInitialize
        0x10f0bce43 <+29>:  movq   0xc68766(%rip), %rsi      ; "_registerForUserDefaultsChanges"
        0x10f0bce4a <+36>:  movq   0xce632f(%rip), %r15      ; (void *)0x000000010e344800: objc_msgSend
        0x10f0bce51 <+43>:  movq   %rbx, %rdi
    CoreFoundation`CFRunLoopRunSpecific:
        0x10e7d7c40 <+0>:   pushq  %rbp
        0x10e7d7c41 <+1>:   movq   %rsp, %rbp
        0x10e7d7c44 <+4>:   pushq  %r15
        0x10e7d7c46 <+6>:   pushq  %r14
        0x10e7d7c48 <+8>:   pushq  %r13
        0x10e7d7c4a <+10>:  pushq  %r12
        0x10e7d7c4c <+12>:  pushq  %rbx
        0x10e7d7c4d <+13>:  subq   $0xe8, %rsp
        0x10e7d7c54 <+20>:  movl   %edx, -0xec(%rbp)
        0x10e7d7c5a <+26>:  movsd  %xmm0, -0xe8(%rbp)
        0x10e7d7c62 <+34>:  movq   %rsi, %r14
        0x10e7d7c65 <+37>:  movq   %rdi, %r12
        0x10e7d7c68 <+40>:  movq   0x311459(%rip), %rax      ; (void *)0x00000001114c0070: __stack_chk_guard
        0x10e7d7c6f <+47>:  movq   (%rax), %rax
        0x10e7d7c72 <+50>:  movq   %rax, -0x30(%rbp)

    代码的共通点都是在函数开始运算之前将r12-r15以及rbx压入栈,r12-r15以及rbx主要用于函数局部变量或临变量。在UIApplicationMain函数中一开始入栈保存后,马上将输入参数传送到rbx,r15,r12进行运算。

    已经约模弄清楚了一条路了,下面就开始反汇编逆向分析,但我的平台是simulator x64。

    ps:后面还会介绍objc其它传参方式, 以及windows和linux(也就是vc与gcc)在x64平台的传参方式。

  • 相关阅读:
    动态可配置表单的设计构思
    mysql之视图
    mysql学习之数据备份和恢复
    mysqli操作
    mysql登录出现1045错误修改方法
    mysql之简单的多表查询
    sql优化的方法总结
    mysql语句操作
    linux 批量替换文件内容
    zend framework 数据库操作(DB操作)总结
  • 原文地址:https://www.cnblogs.com/bbqzsl/p/5070577.html
Copyright © 2020-2023  润新知