美文网首页
iOS逆向-06: OC反汇编 + 汇编总结

iOS逆向-06: OC反汇编 + 汇编总结

作者: 恍然如梦_b700 | 来源:发表于2021-05-03 17:33 被阅读0次

OC反汇编

FYPerson * p = [FYPerson person];//objc_msgSend x0 , x1
image.png

从汇编我们可以看出x0和x1分别是id 和 SEL,也就是oc方法的两个隐藏参数


image.png

我现在手机是iOS14系统,可以看到这个版本已经进行了优化,将直接调用objc_alloc_init,而不是alloc消息发送。


image.png
调用完之后可以看到x0已经是一个oc对象
image.png
这句代码之后会对强引用+1,又会release,我们看看内部如何实现
image.png

给strong修饰的对象进行return+1,给旧对象进行release-1
p的指针 &p, 而x1此时为nil
在方法中就会将p = nil, 然后释放 p指向的内存区域
为什么要释放呢,看这里


image.png
因为这里并没有自动释放池包裹。

通过工具反汇编

image.png
通过hopper我们可以清晰的看到方法的调用以及参数
双击objc_cls_ref_FYPerson进入
image.png
可以看到OBJC_CLASS$_FYPerson 是一个类对象,我们再通过mach-o看一下这个对象的位置
image.png
可以看到这个类对象就存在data段里
同样sel也一样方式查看
image.png
双击person
image.png
image.png
hopper通过读mach-o就能找到字符串,这也就是hopper可以还原的原因

block

在逆向分析时,我们想知道block的实现也就是找到invoke,block可以作为参数,也可以直接执行,但是大部分都是作为参数回调
底层结构

#define BLOCK_DESCRIPTOR_2 1
struct Block_descriptor_2 {
    // requires BLOCK_HAS_COPY_DISPOSE
    BlockCopyFunction copy;
    BlockDisposeFunction dispose;
};

#define BLOCK_DESCRIPTOR_3 1
struct Block_descriptor_3 {
    // requires BLOCK_HAS_SIGNATURE
    const char *signature;
    const char *layout;     // contents depend on BLOCK_HAS_EXTENDED_LAYOUT
};

struct Block_layout {
    void *isa;
    volatile int32_t flags; // contains ref count
    int32_t reserved;
    BlockInvokeFunction invoke;
    struct Block_descriptor_1 *descriptor;
    // imported variables
};
int a = 10;
    
    void(^block)(void) = ^() {
        NSLog(@"block--%d",a);
    };
    block();
image.png

可以看到,使用了外部变量,此时是一个栈block,

image.png
调用完objc_retainBlock之后,变为了堆block,这里可以参考我之前的关于oc-block的文章
image.png
通过反汇编工具就可以很方便的分析,如果不通过这个工具就要在mach-o中找到地址,才能知道是个block,所以反汇编工具非常实用,我们接下来看看这个工具的调用流程
void test3(){NSLog(@"123");}
void test2(){test3();}
void test1(){test2();}

void test(){
    int a = 2;
    if (a < 0) {
        test1();
    }else{
        test2();
    }
}
int main(int argc, char * argv[]) {

//    FYPerson * p = [FYPerson person];//objc_msgSend x0 , x1
//    p.name = @"boy";
//    p.age = 18;
//    
    int a = 10;
    
    void(^block)(void) = ^() {
        NSLog(@"block--%d",a);
    };
    if (a > 0) {
        test();
    }else{
        test1();
    }
    
    block();
    
    return 0;
}

流程图

image.png

伪代码


image.png

不好读,可以通过使用IDA,这个东西既可以静态分析,也可以动态调试,但是这个东西很贵。mac的破解版本不太好找,所以用虚拟机,使用windows版本。

关于汇编的内容就先写到这里,想更多的了解汇编推荐看一看 王爽的汇编语言这本书,非常推荐

总结:

  1. cpu是64位还是32位的,看吞吐量,也就是数据总线的宽度。
  2. 进制
    1024 = 1k 数量单位
    1024B = 1KB 容量单位
    进制转换
  3. 寄存器
    64位有32个通用寄存器,x、w
    pc 指令指针寄存器
    sp 栈顶
    fp 栈底 x29,函数嵌套的时候通过fp为参照

  4. sub sp 拉伸栈空间,16字节对齐
    ldr (load register)读
    str(store register)取
    b 改变pc,bl 改变lr x30
    ret 读lr 跳转
  5. 函数调用栈
    拉伸,栈平衡 之后局部变量就没有了
    x0寄存器为返回值,参数最好不要超过8个
    cpsr 状态寄存器
    NZCV, 32位 ,高四位
  6. if while switch
    cmp 减法,不影响目标寄存器,影响NZCV
    b.le b.ge等等
  7. adrp (address page)
    寻址
    结合add
    低12位清零,+ n左移3位 + add

相关文章

网友评论

      本文标题:iOS逆向-06: OC反汇编 + 汇编总结

      本文链接:https://www.haomeiwen.com/subject/gjoxdltx.html