首页
论坛
课程
招聘
[原创]初识iOS逆向学习笔记之Hopper
2021-7-9 13:49 10141

[原创]初识iOS逆向学习笔记之Hopper

2021-7-9 13:49
10141

0x00 前言

第一次学习iOS逆向开发,并且本人没有任何正向开发基础,现学现用,目前使用的是monkeydev模版,集成了各种框架,直接拖入ipa(已砸壳)应用就能一键重打包编译,并且自带了几个反反调试(也是经过这2天各种百度资料了解)
在逆向过程中,总会遇到一些莫名其妙的闪退和更复杂的反调试,目前也还没解决,所以打算先从oc语法以及熟悉hopper操作开始学起,为此本帖作为笔记,仅供参考哈,因为可能有很多错误。

0x01 初学oc代码

目前使用的是xcode15进行开发,闲着没事写了一个很简单的http请求demo,接下来根据代码来解读这些语法的执行意思,代码如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
//添加查询
-(IBAction)clickSelect :(id)sender{
    NSString *host = @"http://tb.*****.cn";
    NSString *url = [NSString stringWithFormat:@"%@/soft.php?method=getBuffInfo&buffId=%@",host,textField.text];
    NSString *retString = [self httpGet:url];
    [self.view endEditing:YES];
 
}
 
 
- (NSDate *)httpGet:(NSString *)url{
    NSString *urlString = [NSString stringWithFormat:url];
    NSMutableURLRequest *request = [[NSMutableURLRequest alloc] init];
    [request setURL:[NSURL URLWithString:urlString]];
    [request setHTTPMethod:@"GET"];
    NSString *accept = [NSString stringWithFormat:@"application/xml,application/xhtml+xml,text/html;q=0.9,text/plain;q=0.8,image/png,*/*;q=0.5"];
    [request addValue:accept forHTTPHeaderField: @"Accept"];
    NSData *returnData = [NSURLConnection sendSynchronousRequest:request returningResponse:nil error:nil];
    NSString *string = [[NSString alloc] initWithData:returnData encoding:NSUTF8StringEncoding];
    return returnData;
}

这是一个使用某个ID查询其详细信息的http请求,
代码所示一共2个函数
clickSelect :是绑定了button按钮的事件,在按钮点击时触发。
httpGet:自己定义的一个http请求函数,直接传递url然后返回请求到的正文

0x02 oc代码解读分析

首先代码是通过点击button执行clickSelect函数,而oc里面定义string字符串目前大部分都是使用 NSString *变量名 都方式进行定义,这3行代码比较好理解,而调用函数的方法和其他语言大不相同,使用的是[],目前主要解读这部分

1
NSString *url = [NSString stringWithFormat:@"%@/soft.php?method=getBuffInfo&buffId=%@",host,textField.text];

相当于平时js或java的含义是

1
url = string.stringWithFormat("%@/soft.php?method=getBuffInfo&buffId=%@",host,extField.text)

返回值 = [class对象 方法:参数,参数,参数,方法:参数)
而下面比较复杂的是httpget的一个请求函数的代码,我们一行行的解读

1
2
3
4
//oc
NSString *urlString = [NSString stringWithFormat:url];
//js
var urlstring = string.stringWithFormat(url)
1
2
3
4
//oc
NSMutableURLRequest *request = [[NSMutableURLRequest alloc] init];
//js
var request = new NSMutableURLRequest()
1
2
3
4
5
6
7
8
//oc
[request setURL:[NSURL URLWithString:urlString]];
[request setHTTPMethod:@"GET"];
[request addValue:accept forHTTPHeaderField: @"Accept"];
//js
request.setUrl(nsurl.urlwithString(urlstring))
request.setHTTPMethod("GET")
request.addValue(accept).forHTTPHeaderField("accept")

后面的大同小异,到这里就大概懂了oc语法了

0x03 使用hopper逆向解读

通过Xcode的product->archives 打包成ipa安装包,接着拖入hopper进行查看反汇编
图片描述
通过搜索关键字,直接就定位到了函数名字,我们来查看汇编代码进行对比它的oc代码吧。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
                     -[ViewController clickSelect:]:
00000001000057d0         sub        sp, sp, #0x40                               ; Objective C Implementation defined at 0x100006054 (instance method)
00000001000057d4         stp        x22, x21, [sp, #0x10]
00000001000057d8         stp        x20, x19, [sp, #0x20]
00000001000057dc         stp        x29, x30, [sp, #0x30]
00000001000057e0         add        x29, sp, #0x30
00000001000057e4         mov        x19, x0
00000001000057e8         nop
                       :执行NSString *host = @"http://tb.******.cn";
                          NSString *url = [NSString stringWithFormat:@"%@/soft.php?method=getBuffInfo&buffId=%@",host,textField.text];
00000001000057ec         ldr        x20, =_OBJC_CLASS_$_NSString                ; _OBJC_CLASS_$_NSString
00000001000057f0         nop
00000001000057f4         ldr        x0, =0x0
00000001000057f8         nop
00000001000057fc         ldr        x1, =aText                                  ; "text",@selector(text)
0000000100005800         bl         imp___stubs__objc_msgSend                   ; objc_msgSend
0000000100005804         mov        x29, x29
0000000100005808         bl         imp___stubs__objc_retainAutoreleasedReturnValue ; objc_retainAutoreleasedReturnValue
000000010000580c         mov        x21, x0
0000000100005810         nop
0000000100005814         ldr        x1, =aStringwithform                        ; 对象属性名, "stringWithFormat:",@selector(stringWithFormat:)
0000000100005818         adr        x8, #0x1000080d0                            ; 参数1(host), @"http://tb.*****.cn"
000000010000581c         nop
0000000100005820         stp        x8, x0, [sp]                                ; 入堆栈?
                     urlRaw:
0000000100005824         adr        x2, #0x1000080f0                            ; 对象属性初始字符串, @"%@/soft.php?method=getBuffInfo&buffId=%@"
0000000100005828         nop
000000010000582c         mov        x0, x20                                     ; X20 = 对象class(nsstring)
0000000100005830         bl         imp___stubs__objc_msgSend                   ; [??? aStringwithform:], objc_msgSend
0000000100005834         mov        x29, x29
0000000100005838         bl         imp___stubs__objc_retainAutoreleasedReturnValue ; objc_retainAutoreleasedReturnValue
000000010000583c         mov        x20, x0                                     ; 暂且认为x20是存放 nsstring 后的返回值
0000000100005840         mov        x0, x21
0000000100005844         bl         imp___stubs__objc_release                   ; objc_release
                     ·: 执行NSString *retString = [self httpGet:url];
0000000100005848         nop
000000010000584c         ldr        x1, =aHttpget                               ; "httpGet:",@selector(httpGet:)
0000000100005850         mov        x0, x19                                     ; X19 = self
0000000100005854         mov        x2, x20                                     ; 将nsstring返回值(x20),存入参数2
0000000100005858         bl         imp___stubs__objc_msgSend                   ; objc_msgSend
000000010000585c         mov        x29, x29
0000000100005860         bl         imp___stubs__objc_retainAutoreleasedReturnValue ; objc_retainAutoreleasedReturnValue
0000000100005864         mov        x21, x0                                     ; 获得httpget后的返回值
0000000100005868         nop
                     ~:执行[self.view Endediting:YES]
000000010000586c         ldr        x1, =aView                                  ; "view",@selector(view)
0000000100005870         mov        x0, x19                                     ; Self
0000000100005874         bl         imp___stubs__objc_msgSend                   ; objc_msgSend
0000000100005878         mov        x29, x29
000000010000587c         bl         imp___stubs__objc_retainAutoreleasedReturnValue ; objc_retainAutoreleasedReturnValue
0000000100005880         mov        x19, x0
0000000100005884         nop
0000000100005888         ldr        x1, =aEndediting                            ; "endEditing:",@selector(endEditing:)
000000010000588c         movz       w2, #0x1                                    ; argument "instance" for method imp___stubs__objc_msgSend
0000000100005890         bl         imp___stubs__objc_msgSend                   ; objc_msgSend
0000000100005894         mov        x0, x19                                     ; 释放self
0000000100005898         bl         imp___stubs__objc_release                   ; objc_release
000000010000589c         mov        x0, x21                                     ; 释放httpget
00000001000058a0         bl         imp___stubs__objc_release                   ; objc_release
00000001000058a4         mov        x0, x20
00000001000058a8         ldp        x29, x30, [sp, #0x30]
00000001000058ac         ldp        x20, x19, [sp, #0x20]
00000001000058b0         ldp        x22, x21, [sp, #0x10]
00000001000058b4         add        sp, sp, #0x40
00000001000058b8         b          imp___stubs__objc_release                   ; objc_release
                        ; endp

这里的汇编代码就相当于刚刚的selectClick事件里面的4行代码了,经过我仔细揣摩,在后面加上了注释,并且我在每个分快区分了函数的执行段,下面主要分析它的执行方式。

 

这里发现它调用函数都是bl imp_stubsobjc_msgSend的方式来调用的,而寄存器的x0,x1,x2的代表相当于oc语法的:
x0 = [x0 x1:x2]
返回值 = [对象 方法属性:参数]

 

我们看到,其中执行的oc语句:

1
NSString *url = [NSString stringWithFormat:@"%@/soft.php?method=getBuffInfo&buffId=%@",host,textField.text];

对应的汇编就是

1
2
3
4
5
6
7
ldr x20,_OBJ_CLASS_$_NSString
ldd x1,=aStringwithform
adr x8, #0x1000080d0
stp x8,x0,[sp]
adr x2, #0x1000080f0
mov x0, x20
bl imp___stubs__objc_msgSend

通过刚才的的x0,x1,x2调用关系,就知道
mov x0,x20 其中x20就是一开始的nsstring,它先赋值给x0作为对象,紧接着就是x1,x1就对应的方法属性为stringWithFormat:的值,x2它就是从内存地址#0x1000080f0取到的字符串 "%@/soft.php?method=getBuffInfo&buffId=%@" 而后面的host以及textField.text是格式化的参数,它是以堆栈的方式,用stp将x8和x0入栈,而x8也看到是通过#0x1000080d0取到的字符串,而x0在最开始通过text方法将组件的输入内容取出来。

0x04 总结

这是我个人学习了2天的理解,可能还挺多错误,还望指正,因为目前只是站在表面的层面上去理解这些代码含义,真正想深入研究确实要从整个iOS的运行机制,文件类型等去深入了解,但这也是一个循环渐进的过程,先从表面理解的开始撸起来吧~


[注意] 欢迎加入看雪团队!base上海,招聘安全工程师、逆向工程师多个坑位等你投递!

收藏
点赞0
打赏
分享
最新回复 (2)
雪    币: 3738
活跃值: 活跃值 (585)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
MsScotch 活跃值 2021-7-30 09:57
2
0
一般的程序,关注 msgSend,它是一切的同向多方的渠道。
雪    币: 1448
活跃值: 活跃值 (1935)
能力值: ( LV5,RANK:70 )
在线值:
发帖
回帖
粉丝
kzzll 活跃值 2021-8-12 19:38
3
0
MsScotch 一般的程序,关注 msgSend,它是一切的同向多方的渠道。
是的,我学了fishhook才知道。
游客
登录 | 注册 方可回帖
返回