实战ios破解--通过UI找关键函数
0x0 About
本文记录破解一个cydia中收费deb软件过程,如下为一个截图,其中权限
所在UI显示未授权
0x1 通过UI找函数的2种方法
-
ios通过cydia安装
flex_injected
,并在要破解的软件中使用flex_injected
这种方法很方便,效率很高,可通过点击app中的flex_injected
功能区的select
,再点击对应UI再点击views
按钮,通过views
中的不同颜色来直接定位对应UI和UI对应的类 -
通过cycript注入要破解的软件,然后通过
[#0x... setHidden:YES]
来找到UI后再找函数 这种方法比上面的方法麻烦,需要通过这里的命令来查找,一般是通过[[UIApp keyWindow] recursiveDescription]
得到的结果逐个元素进行排除来得到目标UI对象.有以下2点注意事项- cycript设置查看ui对应函数时用到的?expand命令失效时可以这样弥补
[[UIApp keyWindow] recursiveDescription].toString()
- cycript查找ui对应的元素可通过找几个主要的大树枝,如果大树枝
[#0x... setHidden:YES]
后发现要找的UI不显示了则说明要找的UI在这个大树枝里面,然后再大树枝里通过[#0x... setHidden:YES]
逐渐找到最终的小树枝.通过cycript找UI这条路一般不用,除非用flex_injected找不到(有些app无法使用flex_injected)
- cycript设置查看ui对应函数时用到的?expand命令失效时可以这样弥补
0x2 破解过程
step1 找到ui对应的元素
本文要破解的app是cydia里安装的,可能有一些反破解机制,导致无法直接使用ida
调试,也无法使用flex_injected
分析ui,于是使用上面的第2种方法,也即通过cycript
注入目标进程来通过排除法查找上图中权限
这个ui对应的函数.
1.[[UIApp keyWindow] recursiveDescription]
得到结果如下
@[#"<UIWindow: 0x1763dd20; frame = (0 0; 375 667); gestureRecognizers = <NSArray: 0x1763d390>; layer = <UIWindowLayer: 0x175c9d90>>",#"<UITextEffectsWindow: 0x1766ac70; frame = (0 0; 375 667); opaque = NO; autoresize = W+H; layer = <UIWindowLayer: 0x17779950>>"]
cy# [[UIApp keyWindow] recursiveDescription].toString()
`<UIWindow: 0x1763dd20; frame = (0 0; 375 667); gestureRecognizers = <NSArray: 0x1763d390>; layer = <UIWindowLayer: 0x175c9d90>>
| <UIView: 0x188ca2f0; frame = (0 0; 375 667); autoresize = W+H; gestureRecognizers = <NSArray: 0x188c9dd0>; layer = <CALayer: 0x188ca290>>
| | <UIView: 0x188caeb0; frame = (0 0; 375 667); autoresize = W+H; layer = <CALayer: 0x188caf70>>
| | | <UILayoutContainerView: 0x1776c2c0; frame = (0 0; 270 667); hidden = YES; autoresize = RM+H; gestureRecognizers = <NSArray: 0x188c8590>; layer = <CALayer: 0x188a3de0>>
| | | | <UINavigationTransitionView: 0x17690e60; frame = (0 0; 270 667); clipsToBounds = YES; autoresize = W+H; layer = <CALayer: 0x17690f40>>
| | | | | <UIViewControllerWrapperView: 0x17618e30; frame = (0 0; 270 667); autoresize = W+H; layer = <CALayer: 0x177a19d0>>
| | | | | | <UITableView: 0x18509c00; frame = (0 0; 270 667); clipsToBounds = YES; autoresize = W+H; gestureRecognizers = <NSArray: 0x18854560>; layer = <CALayer: 0x188cca20>; contentOffset: {0, 0}; contentSize: {270, 0}>
| | | | | | | <UITableViewWrapperView: 0x18509800; frame = (0 0; 270 667); gestureRecognizers = <NSArray: 0x188ca6b0>; layer = <CALayer: 0x1776f3b0>; contentOffset: {0, 0}; contentSize: {270, 667}>
| | | | | | | <UIImageView: 0x17650ce0; frame = (264.5 657; 2.5 7); alpha = 0; opaque = NO; autoresize = LM; userInteractionEnabled = NO; layer = <CALayer: 0x188d37b0>>
| | | | | | | <UIImageView: 0x17653de0; frame = (260 661.5; 7 2.5); alpha = 0; opaque = NO; autoresize = TM; userInteractionEnabled = NO; layer = <CALayer: 0x17643050>>
| | | | <UINavigationBar: 0x188be470; frame = (0 20; 270 44); opaque = NO; autoresize = W; gestureRecognizers = <NSArray: 0x17607230>; layer = <CALayer: 0x188c8380>>
| | | | | <_UINavigationBarBackground: 0x17693b10; frame = (0 -20; 270 64); opaque = NO; autoresize = W; userInteractionEnabled = NO; layer = <CALayer: 0x188c36
`
2.[#0x1763dd20 setHidden:YES]
之后发现看不到看不到要找的UI(权限
对应的ui)了,说明目标ui在0x1763dd20
的子视图中
3.查看0x1763dd20
的子视图0x188ca2f0
设置隐藏后的效果,[#0x188ca2f0 setHidden:YES]
后发现看不到目标UI,说明目标UI还在0x188ca2f0
的子视图中
4.查看0x188ca2f0
的子视图设置隐藏后的效果,[#0x188caeb0 setHidden:YES]
后发现看不到目标UI,说明目标UI还在0x188caeb0
子视图中
5.[#0x1776c2c0 setHidden:YES]
之后发现目标UI没有被隐藏,说明目标UI不在0x1776c2c0
这条树枝中,但是上面[[UIApp keyWindow] recursiveDescription]
的结果中可以看出0x188caeb0
的子树枝中只有0x1776c2c0
,而0x1776c2c0
的确不是目标UI的父树枝,也许是目标app做了什么隐藏手段导致这样的结果(通过[[UIApp keyWindow] recursiveDescription]
中不能直接看到目标UI)
6.于是通过[#0x188caeb0 subviews]
查看,看看能不能看到除了0x1776c2c0
之外的子树枝,结果如下
@[#"<UILayoutContainerView: 0x1776c2c0; frame = (0 0; 270 667); autoresize = RM+H; gestureRecognizers = <NSArray: 0x188c8590>; layer = <CALayer: 0x188a3de0>>",#"<JhAAAYzaNsFTriWR: 0x188cb0c0; frame = (0 0; 375 667); autoresize = W+H; layer = <CALayer: 0x188cb2e0>>"]
说明0x188caeb0
除了0x1776c2c0
之外还有0x188cb0c0
这个子树枝
7.[#0x188cb0c0 subviews]
结果如下
@[#"<UILayoutContainerView: 0x1763c960; frame = (0 0; 375 667); autoresize = W+H; layer = <CALayer: 0x1763c7d0>>"]
8.上面只有一个子视图,肯定不是目标UI(权限
对应UI),继续查看它的子视图,[#0x1763c960 subviews]
,结果如下
@[#"<UITransitionView: 0x1763be80; frame = (0 0; 375 667); clipsToBounds = YES; autoresize = W+H; layer = <CALayer: 0x1763bcf0>>",#"<UITabBar: 0x1763c450; frame = (0 618; 375 49); autoresize = W+TM; tintColor = UIDeviceRGBColorSpace 0 0.733333 0.223529 1; layer = <CALayer: 0x1763c2a0>>"]
9.[#0x1763be80 setHidden:YES]
之后看不到目标UI
10.[#0x1763be80 subviews]
@[#"<UIViewControllerWrapperView: 0x18e19dc0; frame = (0 0; 375 667); autoresize = W+H; layer = <CALayer: 0x18e26d30>>"]
11.[#0x18e19dc0 subviews]
@[#"<UILayoutContainerView: 0x188ba100; frame = (0 0; 375 667); autoresize = W+H; gestureRecognizers = <NSArray: 0x188bb900>; layer = <CALayer: 0x188ba1d0>>"]
12.[#0x188ba100 subviews]
@[#"<UINavigationTransitionView: 0x188bac60; frame = (0 0; 375 667); clipsToBounds = YES; autoresize = W+H; layer = <CALayer: 0x188bb2b0>>",#"<UINavigationBar: 0x188ba200; frame = (0 20; 375 44); opaque = NO; autoresize = W; gestureRecognizers = <NSArray: 0x188ba9b0>; layer = <CALayer: 0x188ba320>>"]
13.[#0x188bac60 setHidden:YES]
后发现看不到目标UI
14.[#0x188bac60 subviews]
@[#"<UIViewControllerWrapperView: 0x188c2c00; frame = (0 0; 375 667); autoresize = W+H; layer = <CALayer: 0x17604980>>"]
15.[#0x188c2c00 subviews]
@[#"<UITableView: 0x17c0a600; frame = (0 0; 375 667); clipsToBounds = YES; autoresize = W+H; gestureRecognizers = <NSArray: 0x188d56d0>; layer = <CALayer: 0x18980810>; contentOffset: {0, -64}; contentSize: {375, 921}>"]
16.[#0x17c0a600 subviews]
@[#"<UITableViewWrapperView: 0x184f6c00; frame = (0 0; 375 603); gestureRecognizers = <NSArray: 0x177716e0>; layer = <CALayer: 0x177a05b0>; contentOffset: {0, 0}; contentSize: {375, 603}>",#"<UIImageView: 0x18e64bd0; frame = (3 548.5; 369 2.5); alpha = 0; opaque = NO; autoresize = TM; userInteractionEnabled = NO; layer = <CALayer: 0x18e64ba0>>",#"<UILabel: 0x1892a0f0; frame = (0 871; 375 50); text = '\xc2\xa9 361\xe4\xb8\x80\xe9\x94\xae\xe6\x96\xb0\xe6\x9c\xba'; userInteractionEnabled = NO; layer = <_UILabelLayer: 0x1892a200>>",#"<UITableViewHeaderFooterView: 0x1894ea80; frame = (0 639.5; 375 38); text = '\xe5\xb8\xae\xe5\x8a\xa9'; hidden = YES; autoresize = W; layer = <CALayer: 0x18980ab0>>",#"<UITableViewHeaderFooterView: 0x18f05eb0; frame = (0 276; 375 38); text = '\xe8\xae\xbe\xe7\xbd\xae'; autoresize = W; layer = <CALayer: 0x18f060e0>>",#"<UITableViewHeaderFooterView: 0x18f08bb0; frame = (0 96.5; 375 74); text = '\xe6\x9d\x83\xe9\x99\x90(\xe7\xbd\x91\xe7\xbb\x9c\xe4\xb8\x80\xe7\x9b\xb4\xe5\xa4\x84\xe4\xba\x8e[\xe5\x8a\xa0\xe8\xbd\xbd\xe4\xb8\xad]\xe7\x9a\x84\xe8\xa7\xa3\xe5\x86\xb3\xe6\x96\xb9\xe6\xb3\x95\xef\xbc\x9a1. \xe5\x88\x87\xe6\x8d\xa2...'; autoresize = W; layer = <CALayer: 0x18f08b80>>",#"<UIImageView: 0x18e646f0; frame = (369.5 3; 2.5 353.5); alpha = 0; opaque = NO; autoresize = LM; userInteractionEnabled = NO; layer = <CALayer: 0x18e64960>>"]"')'"]
17.[#0x184f6c00 setHidden:YES]
发现看不到目标UI
18.[#0x184f6c00 subviews]
@[#"<UITableViewCell: 0x18f37a20; frame = (0 578; 375 44); text = '\xe5\xa4\x87\xe4\xbb\xbd\xe8\xbf\x81\xe7\xa7\xbb'; autoresize = W; layer = <CALayer: 0x18f379f0>>",#"<UITableViewCell: 0x18f3a5a0; frame = (0 534; 375 44); text = 'VPN\xe4\xbb\xa3\xe7\x90\x86'; autoresize = W; layer = <CALayer: 0x18f3a570>>",#"<taNoXRDjKPBbiCJk: 0x18f4d750; baseClass = UITableViewCell; frame = (0 35; 375 44); text = '\xe7\x83\xad\xe9\x97\xa8\xe6\x8e\xa8\xe8\x8d\x90'; autoresize = W; layer = <CALayer: 0x18fbeac0>>",#"<UITableViewCell: 0x18f49aa0; frame = (0 170.5; 375 44); text = '\xe6\x9c\xba\xe5\x99\xa8\xe7\xa0\x81'; autoresize = W; layer = <CALayer: 0x18f49a70>>",#"<UITableViewCell: 0x17531390; frame = (0 214.5; 375 44); text = '\xe6\x9d\x83\xe9\x99\x90'; autoresize = W; layer = <CALayer: 0x17531580>>",#"<UITableViewCell: 0x189d7520; frame = (0 314; 375 44); text = '\xe6\x96\xb0\xe6\x9c\xba\xe6\x97\xb6\xe8\x87\xaa\xe5\x8a\xa8\xe5\xa4\x87\xe4\xbb\xbd'; autoresize = W; layer = <CALayer: 0x189d7710>>",#"<UITableViewCell: 0x189e1250; frame = (0 358; 375 44); text = '\xe6\x96\xb0\xe6\x9c\xba\xe6\x97\xb6\xe6\xb8\x85\xe7\xa9\xba\xe5\x89\xaa\xe8\xb4\xb4\xe6\x9d\xbf'; autoresize = W; layer = <CALayer: 0x189e1440>>",#"<UITableViewCell: 0x189013c0; frame = (0 809.5; 375 44); text = 'Tinyapps.cn'; hidden = YES; autoresize = W; layer = <CALayer: 0x189186f0>>",#"<UITableViewCell: 0x18e18960; frame = (0 765.5; 375 44); text = '\xe6\xa3\x80\xe6\x9f\xa5\xe6\x96\xb0\xe7\x89\x88\xe6\x9c\xac'; hidden = YES; autoresize = W; layer = <CALayer: 0x18eb08d0>>",#"<UITableViewCell: 0x17530760; frame = (0 721.5; 375 44); text = '\xe8\x84\x9a\xe6\x9c\xac\xe8\xb0\x83\xe7\x94\xa8\xe6\x8c\x87\xe5\x8d\x97'; hidden = YES; autoresize = W; layer = <CALayer: 0x1908b2d0>>",#"<UITableViewCell: 0x18f3f990; frame = (0 677.5; 375 44); text = '\xe4\xbd\xbf\xe7\x94\xa8\xe8\xaf\xb4\xe6\x98\x8e'; hidden = YES; autoresize = W; layer = <CALayer: 0x18e2b090>>",#"<UITableViewCell: 0x189e6d40; frame = (0 446; 375 44); text = '\xe8\x87\xaa\xe5\x8a\xa8\xe6\x9b\xb4\xe6\x8d\xa2IP(\)'"]
19.[#0x18f37a20 setHidden:YES]
,[#0x18f4d750 setHidden:YES]
发现目标UI没有被隐藏
20.[#0x18f49aa0 setHidden:YES]
发现待破解app截图中的机器码
对应UI被隐藏
21.[#0x17531390 setHidden:YES]
发现待破解app截图中的权限
对应UI被隐藏,说明这就是要找的UI元素
step2 找到ui元素对应的函数
1.尝试通过<<ios应用逆向工程>>
或这里的[button_object allTargets]
和[button_object allControlEvent]
的方法没有找到对应的UI函数
2.于是尝试通过nextResponder
找出关键类
对于一个view调用nextResponder,要么返回对应的C,要么返回其superview.我们可以通过recursiveDescription拿到所有view,遍历一遍则必定为出现C
对目标UI元素0x17531390
调用nextResponder
,结果是superview,不是Controller,继续调用0x17531390
的superview的nextResponder
,结果不是Controller,继续这样,大概第三次调用nextResponder
时得到Controller,结果如下
#"<DfzeGXHoBCzYUNyG: 0x1884b8c0>"
3.在ida
中查看这个类有什么函数,内容如下
-[DfzeGXHoBCzYUNyG initWithTitle:] __text 0028DC58 0000006C 00000018 FFFFFFF9 . . . . . T .
-[DfzeGXHoBCzYUNyG viewDidLoad] __text 0028DCC4 00000386 0000003C 00000050 . . . . . T .
-[DfzeGXHoBCzYUNyG viewWillAppear:] __text 0028E076 0000020C 00000028 00000020 . . . . . T .
-[DfzeGXHoBCzYUNyG YnDNWxqNaCCuowFk] __text 0028E282 00000186 00000028 FFFFFFF9 . . . . . T .
-[DfzeGXHoBCzYUNyG qtuIqLxznDvYaGTr] __text 0028E408 00000186 00000028 FFFFFFF9 . . . . . T .
-[DfzeGXHoBCzYUNyG getIPAddresses] __text 0028E58E 000001F2 0000004C FFFFFFF9 . . . . . T .
-[DfzeGXHoBCzYUNyG DtFVEldRKFDYPxLj] __text 0028E780 0000013A 00000034 FFFFFFF9 . . . . . T .
sub_28E8BA __text 0028E8BA 0000017E 00000028 FFFFFFF9 . . . . . . .
-[DfzeGXHoBCzYUNyG TAKrPPOSDHgLhdlg:] __text 0028F054 0000005C 00000018 FFFFFFF9 . . . . . T .
-[DfzeGXHoBCzYUNyG CjBOqjnWPaaJQnAu:] __text 0028F0B0 0000005C 00000018 FFFFFFF9 R . . . . T .
-[DfzeGXHoBCzYUNyG UNTxpTxBxJoWIeZP:] __text 0028F10C 0000017E 00000038 FFFFFFF9 . . . . . T .
-[DfzeGXHoBCzYUNyG TVOkxTgmPvvUQgyG] __text 0028F28A 000000E6 00000014 FFFFFFF9 . . . . . T .
-[DfzeGXHoBCzYUNyG ByPwWewvzRduvJAZ:] __text 0028F370 000006D0 00000050 0000015C . . . . . T .
-[DfzeGXHoBCzYUNyG lMMzCjtHIpwhEYDe] __text 0028FA40 0000008A 00000010 FFFFFFF9 . . . . . T .
-[DfzeGXHoBCzYUNyG lFgomfELMhFbEmAP] __text 0028FACA 0000045A 00000038 000000A0 . . . . . T .
sub_28FF28 __text 0028FF28 000000EE 00000020 FFFFFFF9 . . . . . . .
sub_290126 __text 00290126 000000EE 00000020 FFFFFFF9 . . . . . . .
-[DfzeGXHoBCzYUNyG TsKjfpgzwErnqaRz] __text 00290326 000003A6 00000088 00000050 R . . . . T .
-[DfzeGXHoBCzYUNyG dFslcfROBneVXIcP] __text 002906CC 000000F4 00000028 FFFFFFF9 R . . . . T .
-[DfzeGXHoBCzYUNyG gvUiVteWORiIBItH] __text 002908C2 000001F2 00000030 FFFFFFF9 R . . . . T .
-[DfzeGXHoBCzYUNyG dvgqYNRRWfWlzrMR] __text 00290AB4 000001F2 00000024 FFFFFFF9 . . . . . T .
-[DfzeGXHoBCzYUNyG cYPTTHyfdZrmlGeJ] __text 00290CA6 00000442 0000003C FFFFFFF9 . . . . . T .
-[DfzeGXHoBCzYUNyG qmBOCGqdppELEuhx:] __text 002910FC 000006AE 00000064 00000014 . . . . . T .
sub_2917AA __text 002917AA 00000014 . . . . . . .
sub_2917BE __text 002917BE 00000014 R . . . . . .
sub_2917D2 __text 002917D2 00000002 R . . . . . .
-[DfzeGXHoBCzYUNyG xkbtCZfVnlokDiQQ] __text 002917DE 0000023C 00000058 FFFFFFF9 . . . . . T .
-[DfzeGXHoBCzYUNyG actionSheet:didDismissWithButtonIndex:] __text 00291A1A 000000B2 0000002C FFFFFFF9 R . . . . T .
sub_291ACC __text 00291ACC 00000030 R . . . . . .
sub_291AFC __text 00291AFC 00000006 R . . . . . .
-[DfzeGXHoBCzYUNyG QKcrTsEUijhKlYkK] __text 00291B08 00000362 00000044 FFFFFFF9 . . . . . T .
sub_291E6A __text 00291E6A 0000061C 00000068 FFFFFFF9 R . . . . . .
sub_292486 __text 00292486 00000078 00000010 FFFFFFF9 . . . . . . .
sub_2924FE __text 002924FE 00000008 R . . . . . .
-[DfzeGXHoBCzYUNyG numberOfSectionsInTableView:] __text 00292506 00000004 R . . . . T .
-[DfzeGXHoBCzYUNyG tableView:numberOfRowsInSection:] __text 0029250A 00000018 R . . . . T .
-[DfzeGXHoBCzYUNyG tableView:titleForHeaderInSection:] __text 00292522 0000037E 00000070 FFFFFFF9 . . . . . T .
-[DfzeGXHoBCzYUNyG tableView:cellForRowAtIndexPath:] __text 002928A0 00002022 00000060 000005A4 . . . . . T .
-[DfzeGXHoBCzYUNyG OhUMmGPeGwZZDBtc] __text 002950D6 00000198 00000014 00000034 R . . . . T .
sub_29526E __text 0029526E 00000028 R . . . . . .
sub_295296 __text 00295296 00000008 R . . . . . .
-[DfzeGXHoBCzYUNyG jmkaknJHAflckoIm] __text 002952A2 000003BC 00000018 00000008 R . . . . T .
-[DfzeGXHoBCzYUNyG rOOryYkvHSZTcyEr] __text 002956CC 00000092 00000018 FFFFFFF9 R . . . . T .
-[DfzeGXHoBCzYUNyG PeRitUKptnhtvumt] __text 00295762 0000009C 00000014 FFFFFFF9 . . . . . T .
-[DfzeGXHoBCzYUNyG WEGZcpPXhqEpYzTJ:] __text 0029605E 000000FC 00000018 FFFFFFF9 . . . . . T .
-[DfzeGXHoBCzYUNyG VbuxthvxmYrmdAnn] __text 002962E6 00000012 R . . . . T .
-[DfzeGXHoBCzYUNyG FtJrvgWmZdeEYCrm] __text 00296308 00000010 R . . . . T .
-[DfzeGXHoBCzYUNyG setFtJrvgWmZdeEYCrm:] __text 00296318 00000010 R . . . . T .
发现类名和大部分类函数都没有具体的意义,可能是都被混淆了,一个一个函数查看有没有线索,在DfzeGXHoBCzYUNyG tableView:cellForRowAtIndexPath
函数中发现一些字符串
v25 = objc_msgSend(v24, "localizedStringForKey:value:table:", CFSTR("License"), &stru_657918, 0);
v46 = objc_msgSend(v45, "localizedStringForKey:value:table:", CFSTR("valid till %@"), &stru_657918, 0);
以及一些其他的在截图中被打码部分的对应字符串,到这里,想到应该把手机的系统语言设置成English
,这样破解起来更清晰,将手机系统语言设置成英文后,app截图如下
step3 暴破
上图可看到对应的License
和Unauthorized
,由于这里的函数大多被混淆了,现在尝试通过关键字进行破解,在ida
的strings
窗口中搜索Unauthorized,找到后双击,在IDA view
窗口中右键查看调用了此处的代码,没有找到什么有用的信息.后来通过在app中点击使用正常功能的对应按钮,弹出警告窗口如下
图中显示”License not activated,please purchase”,在strings窗口中搜索这串字符,找到调用这串字符相关的代码,如下图
涉及3个函数,分别是+[UrsUiQqCjhigLsxP bYYENZFgIdldmiUx]
,sub_ACB60
,-[UrsUiQqCjhigLsxP tableView:didSelectRowAtIndexPath:]
,将这3处分别patch(if xxx jump xxx,改成if not xxx jump xxx),将patch后的文件替换手机中的对应文件(find / -name "appname"
),重新在手机中运行app,验证成功破解
如果需要将破解后的app保留以备后用,可将deb文件重新打包,可参考这里
0x3 后记
后来尝试重新动态调试破解,有以下绕过反调试过程
绕过反调试
这个app直接使用ida远程调试时会发现无法调试,为了找到反调试代码,在app入口start
函数处下断点(可在ida的Exports
视图中快速找到start
函数),内容如下
int __fastcall start(int a1, int a2)
{
int v2; // r5
int v3; // r6
int v4; // r0
int v5; // r8
void *v6; // r0
int v7; // r0
int v8; // r4
int v9; // r5
v2 = a2;
v3 = a1;
v4 = sub_2E3686();
v5 = objc_autoreleasePoolPush(v4);
v6 = objc_msgSend(&OBJC_CLASS___JefhStRvMGfrygNL, "class");
v7 = NSStringFromClass(v6);
v8 = objc_retainAutoreleasedReturnValue(v7);
v9 = UIApplicationMain(v3, v2, 0, v8);
objc_release(v8);
objc_autoreleasePoolPop(v5);
return v9;
}
在start函数里step over
单步调试,发现运行到sub_2e3686
函数中有个ptrace
调用,这是一种反调试方法(其他反调试方法可参考这里).于是将ptrace的调用nop掉,然后patch原可执行文件后重新远程调试
注意
1.这里由于是远程调试,ida可能在将patch内容写入到原文件时有个bug.因为远程调试时在调试设置中的可执行文件的路径是远程手机上的路径,如这里的路径是/Applications/xxx.app/xxx
,在ida中edit|patch program|apply patches to input file
时无法将修改的内容写入到远程手机上的app,需要在patch前将input file的路径设置为ida所在pc本地的已经存在的可执行文件,但是这个设置不能在edit|patch program|apply patches to input file
弹出的对话框中设置,在这里设置后发现没有成功path,需要在debugger|process option
这里设置,设置好后再去edit|patch program|apply patches to input file
可成功patch到IDA所在pc的可执行文件,patch完成后再将本地所在的可执行文件拷贝到远程手机中,再重新进行远程调试
2.在远程调试时,ida默认不勾选下图中的suspend on debugging start
和suspend on process entry point
,这两个选项要手动勾上,因为如果被调试的程序有反调试机制
而没有勾选这两个选项,则不能在反调试代码运行前将被调试程序中断下来,因为这里是远程调试,一般需要rebase program,只有rebase program后断点才会正常中断.如果没有勾选这两个选项则会在人工rebase program前(也即正常调试目标程序前)就发生了反调试代码的运行,这样就无法调试了
3.cydia中的deb有些是32位的,要根据具体情况选择用32位的ida还是用64位的ida,如果app的位数与ida的位数不一致会导致hex-rays decompiler
插件会不起作用,或者在rebase program时出问题.如果发现ida使用remote ios debugger+usb调试时ida还经常是”卡”的状态,很有可能是因为app的位数与ida位数不一致造成(如64位的app用到了32位的ida调试)