[iOS逆向工程] 在汇编语言调试中获取当前实例句柄

在分析Safari行为的时候想到要用objective-c的特性随时可以语义化的查看一下UIView的各种状态,比如在UIView方法内部设了个断点,想看一下当前视图结构。只要得到当前实例的句柄就可以了。查了一些资料,记录一下。

函数参数的传递

iOS Simulator里应用是跑在32bits模式下的(在Activity Monitor可以看到),依据<<Mac OS Debug Magic>>里关于Intel 32bits参数传递的定义:

Table 2 : Accessing parameters on Intel 32-bit

(64bits是先使用通用寄存器来传递参数,不足时再使用其它方式)

What GDB Syntax
return address *(int*)$esp
first parameter *(int*)($esp+4)
second parameter *(int*)($esp+8)
... and so on  

如果已经进入到函数体,也就是过函数参数处理部分(开场位置, prologue), 参数就要到调用帧寄存器(frame register)ebp中去获取了。

Table 3 : Accessing parameters after the prologue

What GDB Syntax
previous frame *(int*)$ebp
return address *(int*)($ebp+4)
first parameter *(int*)($ebp+8)
second parameter *(int*)($ebp+12)
... and so on  

返回值存放在EAX寄存器中。

既然知道参数是如何存储的,那C++和Objective-C是如何传递当前实例的句柄的呢?

答案在同一份文档的这里:

当在汇编语言下调试Cocoa代码,请记住以下运行时特性:

  • The Objective-C compiler adds two implicit parameters to each method, the first of which is a pointer to the object being called (self).
  • The second implicit parameter is the method selector (_cmd). In Objective-C this is of type SEL;
    in GDB you can print this as a C string.
  • The Objective-C runtime dispatches methods via a family of C function. The most commonly seen is objc_msgSend, but some architectures use objc_msgSend_stret for
    methods which returns structures, and some architectures useobjc_msgSend_fpret for methods that return floating point values. There are also equivalent functions for calling super (objc_msgSendSuper and
    so on).
  • The first word of any Objective-C object (the isa field) is a pointer to the object's class.

就是函数调用时第一个参数就是操作对应的对象(如果自己的方法,就是self了), 第二参数就是selector method.

实战

分析一下CALayer::addSublayer中的执行情况,

在这里使用lldb memory指令:

(lldb) me read -s4 -fx -c4 `$esp`
0xb01dd28c: 0x0000a07c 0x0929e170 0x04e7aad3 0x1386d750

再调用一个检查一下句柄:

(lldb) po [0x0929e170 description] 或者

(lldb) po [`*(int*)($esp+4)` description]
(id) $102 = 0x0929e210 <CALayer: 0x929e170>

 (*注意, `不是单引号!  如果这个对象是UIView, 使用recursiveDescription你就知道它的威力了! )


(lldb) po [*(0x0929e170) isHidden]
(id) $105 = 0x00000001 [no Objective-C description available]

这样就可以调用其它方法进行操作了。

再次验证一下第二个参数:

(lldb) me read -s4 -fs 0x4e7aad3 

或者 

(lldb) me read -s4 -fs `*(int*)($esp+8)`

0x04e7aad3: "addSublayer:"

0x04e7aae0: NULL

用一个检查UIView层次的实例来展示它的强大:

(lldb) po [[`*(int*)($esp+4)` superview] recursiveDescription]

(id) $7 = 0x0719f940 <UIWebSelectionView: 0x107d74e0; frame = (0 0; 0 0); layer = <CALayer: 0x107d7620>>

   | <UIView: 0x107d7770; frame = (0 0; 0 0); userInteractionEnabled = NO; layer = <CALayer: 0x107d77d0>>

   | <UIWebSelectionOutline: 0x759b340; frame = (-2 -2; 4 4); userInteractionEnabled = NO; layer = <CALayer: 0x75963e0>>

   |    | <UIView: 0x759b3f0; frame = (0 0; 0 0); layer = <CALayer: 0x759d580>>

   |    | <UIView: 0x759da60; frame = (0 0; 0 0); layer = <CALayer: 0x759bfb0>>

   |    | <UIView: 0x759be40; frame = (0 0; 0 0); layer = <CALayer: 0x759db30>>

   |    | <UIView: 0x718d150; frame = (0 0; 0 0); layer = <CALayer: 0x719f650>>

附注:

*如果是C++, 则第一个参数就是this,所以也很方便查。而函数返回值放在EAX中,在ret位置设个断点,也可以很方便查看。

*这个调试过程最好使用LLDB, 它对Objective-C的支持要好很多。

Reference:

  iOS Debug Magic

  Mac OS Debug Magic

转载请注明出处: http://blog.csdn.net/horkychen

时间: 2024-10-22 08:13:31

[iOS逆向工程] 在汇编语言调试中获取当前实例句柄的相关文章

指针-调试中获取获取的时间直接用ToDataTime转为出现问题

问题描述 调试中获取获取的时间直接用ToDataTime转为出现问题 从图中看出我用System::Convert::ToDataTime(buf)进行强制类型转换,buf指针放上去已经有时间值了,可是为啥这步会出现从boolean类型到DataTime强制类型转换无效,应该怎么解决,或者有什么其他办法吗

iOS逆向工程——非越狱调试

其实iOS的逆向分析业界已经十分成熟了,网上也有许多有趣的尝试(一步一步实现iOS微信自动抢红包(非越狱).本文着重于如何在非越狱机器上进行调试,出于学习及总结的目的,记录于此. 本文以破解游戏梦幻西游为例,逐步讲解整个调试流程. ->工具 完成整个过程需要准备以下几个必要工具: 1.iOSOpenDev,用于允许在Xcode上创建Dylib工程: 2.yololib,用于为二进制文件注入Dylib: 3.class-dump,用于导出 decrypted 的二进制文件的头文件: 4.Capta

iOS逆向工程使用LLDB的USB连接调试第三方App_IOS

LLDB是Low Level Debugger的简称,在iOS开发的调试中LLDB是经常使用的,LLDB是Xcode内置的动态调试工具.使用LLDB可以动态的调试你的应用程序,如果你不做其他的额外处理,因为debugserver缺少task_for_pid权限,所以你只能使用LLDB来调试你自己的App.那么本篇博客中就要使用LLDB来调试从AppStore下载安装的App,并且结合着Hopper来分析第三方App内部的结构.LLDB与Hopper的结合,会让你看到不一样的东西,本篇博客就会和你

IOS中获取各种文件的目录路径的方法

其实每个APP的程序都是单独的一个文件夹,每个APP之间相互之间独立,所以它们的文件夹也是独立的,这个文件夹就是沙盒(Sandbox).沙盒好处,安全; 坏处,程序之间彼此共享数据较为困难. 1)如何找到应用程序的沙盒源文件? 一般沙盒源文件都存放在~/Library/Application Support/iPhone Simulator/版本号/Applications/的文件夹中,但是这个Library(中文名叫资源库)文件夹是隐藏的.所以需要方法才能点击进去:在Finder中按CMD+S

ios-急急急!!!!iOS如何在程序中获取到手机日历中的日程关键字信息,求大神解救

问题描述 急急急!!!!iOS如何在程序中获取到手机日历中的日程关键字信息,求大神解救 急急急!!!!iOS如何在程序中获取到手机日历中的日程关键字信息,求大神解救 急急急!!!!iOS如何在程序中获取到手机日历中的日程关键字信息,求大神解救 解决方案 http://download.csdn.net/download/rlk5h/8376341

iOS中获取系统相册中的图片实例_IOS

本文介绍了iOS中获取系统相册中的图片,在很多应用中都能用到,可以获取单张图片,也可以同时获取多张图片,废话不多说了,看下面吧. 一.获取单张图片 思路: 1.利用UIImagePickerController可以从系统自带的App(照片\相机)中获得图片 2.设置代理,遵守代理协议 注意这个UIImagePickerController类比较特殊,需要遵守两个代理协议 @interface ViewController () <UIImagePickerControllerDelegate,

IOS中获取本地通讯录联系人以及汉字首字母排序_IOS

iOS中获取手机通讯录中的联系人信息: /*** 加载本地联系人*/ - (void)loadLocalContacts { //新建一个通讯录类 ABAddressBookRef addressBooks = nil; if (DeviceVersion < 6.0) { addressBooks = ABAddressBookCreate(); } else { addressBooks = ABAddressBookCreateWithOptions(NULL, NULL); //获取通讯

请问,如何在xamarin ios 中获取到wifi流量

问题描述 请问,如何在xamarinios中获取到wifi流量我知道用object-c语言可以访问+(NSArray*)getDataCounters{BOOLsuccess;structifaddrs*addrs;conststructifaddrs*cursor;conststructif_data*networkStatisc;}使用这个ifaddrs结构访问到流量,但是在咱们xamarinios中如何获取wifi流量?

iOS逆向工程之Hopper中的ARM指令

虽然前段时间ARM被日本软银收购了,但是科技是无国界的,所以呢ARM相关知识该学的学.现在看ARM指令集还是倍感亲切的,毕竟大学里开了ARM这门课,并且做了不少的实验,当时自我感觉ARM这门课学的还是可以的.虽然当时感觉学这门课以后似乎不怎么用的上,可曾想这不就用上了吗,不过之前学的都差不多忘了,还得捡起来呢.ARM指令集是精简指令集,从名字我们就能看出指令的个数比那些负责指令集要少一些.当然本篇所涉及的ARM指令集是冰山一角,不过也算是基础,可以阅读Hopper中的汇编了,实践出真知,看多了自