首页
社区
课程
招聘
[原创]iOS加固浅谈之字符串加密
发表于: 2017-5-31 21:20 25283

[原创]iOS加固浅谈之字符串加密

2017-5-31 21:20
25283

我来科锐学习了不少时间了,发点学习记录,虽然科锐没教iOS,但是学习思路是想通的,本人之前做了几年iOS开发,苦于工作加班严重和逆向难入门,所以来到科锐学习Windows逆向,以求曲线救国。这里感谢钱老师的教导。
iOS代码保护

在大多数iOS应用中,一些工具,比如Clutch,class-dump,cycript,lldb,theos.对应用程序的结构,代码逻辑,运行流程,可以做到很容易的分析。然后进行应用的破解,篡改,重签名。所以很有必要对代码做一些保护。


iOS代码保护思路:
可以从逆向分析的方式入手:
1.静态分析:针对这种情况可以把字符串加密,类名方法名混淆,代码混淆
2.调试 :反调试
3.注入 :反注入

      4.中间人攻击 :https, 证书验证, 数据加密


下面依次介绍下实例:
字符串加密:
- (void)viewDidLoad {
    [super viewDidLoad];
    // Do any additional setup after loading the view, typically from a nib.
    
    NSLog(@"Hello CR25");
}

比如这种字符串,我们看看其反汇编代码:

0000000100006794         sub        sp, sp, #0x30                               ; Objective C Implementation defined at 0x1000080f8 (instance method), DATA XREF=0x1000080f8

0000000100006798         stp        x29, x30, [sp, #0x20]

000000010000679c         add        x29, sp, #0x20

00000001000067a0         mov        x8, sp

00000001000067a4         adrp       x9, #0x100008000

00000001000067a8         add        x9, x9, #0xc88                              ; @selector(viewDidLoad)

00000001000067ac         adrp       x10, #0x100008000

00000001000067b0         add        x10, x10, #0xca8                            ; 0x100008ca8

00000001000067b4         stur       x0, [x29, #-0x8]

00000001000067b8         str        x1, [sp, #0x10]

00000001000067bc         ldur       x0, [x29, #-0x8]

00000001000067c0         str        x0, sp

00000001000067c4         ldr        x10, x10

00000001000067c8         str        x10, [sp, #0x8]

00000001000067cc         ldr        x1, x9

00000001000067d0         mov        x0, x8

00000001000067d4         bl         imp___stubs__objc_msgSendSuper2

00000001000067d8         adrp       x0, #0x100008000                            ; argument #1 for method imp___stubs__NSLog

00000001000067dc         add        x0, x0, #0x60                               ; @"Hello CR25"

00000001000067e0         bl         imp___stubs__NSLog

00000001000067e4         ldp        x29, x30, [sp, #0x20]

00000001000067e8         add        sp, sp, #0x30

00000001000067ec         ret

CR25明文,如果我们这里是程序的敏感信息的话,分析者就会很容易找到我们的敏感信息。这里需要给字符串加密,然后运行时进行动态解密。

这里为了举例,我只做了简单的异或,具体算法你可以根据需求自己选择。

字符串加密后源码:

- (void)viewDidLoad {
    [super viewDidLoad];
    // Do any additional setup after loading the view, typically from a nib.
    
    NSLog(DecodeOcString(&_7VA7EOJRUDOSFIS));
}

再看看反汇编:


                     -[ViewController viewDidLoad]:

0000000100006660         sub        sp, sp, #0x40                               ; Objective C Implementation defined at 0x1000080e0 (instance method), DATA XREF=0x1000080e0

0000000100006664         stp        x29, x30, [sp, #0x30]

0000000100006668         add        x29, sp, #0x30

000000010000666c         add        x8, sp, #0x10

0000000100006670         adrp       x9, #0x100008000

0000000100006674         add        x9, x9, #0xc70                              ; @selector(viewDidLoad)

0000000100006678         adrp       x10, #0x100008000

000000010000667c         add        x10, x10, #0xca8                            ; 0x100008ca8

0000000100006680         stur       x0, [x29, #-0x8]

0000000100006684         stur       x1, [x29, #-0x10]

0000000100006688         ldur       x0, [x29, #-0x8]

000000010000668c         str        x0, [sp, #0x10]

0000000100006690         ldr        x10, x10

0000000100006694         str        x10, [sp, #0x18]

0000000100006698         ldr        x1, x9

000000010000669c         mov        x0, x8

00000001000066a0         bl         imp___stubs__objc_msgSendSuper2

00000001000066a4         adrp       x8, #0x100008000                            ; argument #1 for method __B97DE2E4_175_F0C445_2D3_29549CFFE480

00000001000066a8         add        x0, x8, #0xd58                              ; __7VA7EOJRUDOSFIS

00000001000066ac         bl         __B97DE2E4_175_F0C445_2D3_29549CFFE480

00000001000066b0         mov        x29, x29

00000001000066b4         bl         imp___stubs__objc_retainAutoreleasedReturnValue

00000001000066b8         mov        x1, x0

00000001000066bc         str        x0, [sp, #0x8]

00000001000066c0         mov        x0, x1

00000001000066c4         bl         imp___stubs__NSLog

00000001000066c8         ldr        x0, [sp, #0x8]

00000001000066cc         bl         imp___stubs__objc_release

00000001000066d0         ldp        x29, x30, [sp, #0x30]

00000001000066d4         add        sp, sp, #0x40

00000001000066d8         ret

这个时候你就看不到明文字符串了。一个项目中的字符串不计其数,如果是都要进行加密,需要遍历源文件然后进行加密。这里还有另外一种选择,就是用clang生成语法树,然后拿到节点,然后再进行加密。

Clang生成语法树

如下源码:

- (void)viewDidLoad {
    [super viewDidLoad];
    // Do any additional setup after loading the view, typically from a nib.
    static char* str1 = nil;
    
    static char * str2 = "cr25HelloWorld";
    
    static NSString *str3 = nil;
    
    static NSString *str4 = @"cr23HelloWorld";
    
    char* str5 = "cr24HelloWorld";
    
    NSString *str6 = @"cr21HelloWorld\n";
    
    NSString *str7 = [NSString stringWithFormat:@"I'm%@",@"cr25"];
}

终端输入命令:

xcrun -sdk iphoneos clang -arch arm64 -Xclang -ast-dump -fsyntax-only -F UIKit ViewController.m

然后输出语法树:(由于输出内容太多,这里只截取部分)

 `-StringLiteral 0x7fb3e744b3c8 <col:26> 'char [15]' lvalue "cr25HelloWorld"

  |   |-DeclStmt 0x7fb3e744b538 <line:24:5, col:32>

  |   | `-VarDecl 0x7fb3e744b448 <col:5, /Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS10.3.sdk/usr/include/sys/_types.h:52:33> ViewController.m:24:22 str3 'NSString *' static cinit

  |   |   `-ImplicitCastExpr 0x7fb3e744b520 </Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS10.3.sdk/usr/include/sys/_types.h:52:23, col:33> 'NSString *' <NullToPointer>

  |   |     `-ParenExpr 0x7fb3e744b500 <col:23, col:33> 'void *'

  |   |       `-CStyleCastExpr 0x7fb3e744b4d8 <col:24, col:32> 'void *' <NullToPointer>

  |   |         `-IntegerLiteral 0x7fb3e744b4a8 <col:32> 'int' 0

  |   |-DeclStmt 0x7fb3e744b620 <ViewController.m:26:5, col:46>

  |   | `-VarDecl 0x7fb3e744b568 <col:5, col:30> col:22 str4 'NSString *' static cinit

  |   |   `-ObjCStringLiteral 0x7fb3e744b600 <col:29, col:30> 'NSString *'

  |   |     `-StringLiteral 0x7fb3e744b5c8 <col:30> 'char [15]' lvalue "cr23HelloWorld"

  |   |-DeclStmt 0x7fb3e744b6f8 <line:28:5, col:34>

  |   | `-VarDecl 0x7fb3e744b648 <col:5, col:18> col:11 str5 'char *' cinit

  |   |   `-ImplicitCastExpr 0x7fb3e744b6e0 <col:18> 'char *' <ArrayToPointerDecay>

  |   |     `-StringLiteral 0x7fb3e744b6a8 <col:18> 'char [15]' lvalue "cr24HelloWorld"

  |   |-DeclStmt 0x7fb3e744b7e0 <line:30:5, col:41>

  |   | `-VarDecl 0x7fb3e744b728 <col:5, col:23> col:15 str6 'NSString *' cinit

  |   |   `-ObjCStringLiteral 0x7fb3e744b7c0 <col:22, col:23> 'NSString *'

  |   |     `-StringLiteral 0x7fb3e744b788 <col:23> 'char [16]' lvalue "cr21HelloWorld\n"

  |   `-DeclStmt 0x7fb3e744b998 <line:32:5, col:66>

  |     `-VarDecl 0x7fb3e744b810 <col:5, col:65> col:15 str7 'NSString *' cinit

  |       `-ObjCMessageExpr 0x7fb3e744b958 <col:22, col:65> 'NSString * _Nonnull':'NSString *' selector=stringWithFormat: class='NSString'

  |         |-ObjCStringLiteral 0x7fb3e744b8b0 <col:49, col:50> 'NSString *'

  |         | `-StringLiteral 0x7fb3e744b880 <col:50> 'char [6]' lvalue "I'm%@"

  |         `-ObjCStringLiteral 0x7fb3e744b938 <col:58, col:59> 'NSString *'

  |           `-StringLiteral 0x7fb3e744b908 <col:59> 'char [5]' lvalue "cr25"

这样子就生成了语法树,每个节点信息都表示得很清晰。

比如:

`-VarDecl 0x7fb3e744b568 <col:5col:30col:22 str4(变量名) 'NSString *'(类型) static cinit(静态)

  |   |   `-ObjCStringLiteral(OC字符串) 0x7fb3e744b600 <col:29col:30'NSString *'

  |   |     `-StringLiteral(C类型的字符串) 0x7fb3e744b5c8 <col:30'char [15]' lvalue "cr23HelloWorld"


我们可以利用Clang的一些API进行分析与加密(例子源码见附件,感谢Monkey的开源源码):

1.首先需要dlopen一个动态库:libclang.dylib

2.初始化函数指针:initlibfunclist(void* handle);

3.在这个函数enum CXChildVisitResult printVisitor(CXCursor cursor, CXCursor parent, CXClientData client_data) 里遍历出文件名,变量名,类型,以及字符是OC字符串还是C字符串,最重要的是我们可以在这个函数里拿到字符串的开始和结束的位置,然后再进行字符串加密操作。这样子就可以把整个项目的字符串进行加密。

(今天先记录下字符串加密,其他加固方式下次再记录)


[培训]内核驱动高级班,冲击BAT一流互联网大厂工作,每周日13:00-18:00直播授课

上传的附件:
收藏
免费 1
支持
分享
最新回复 (18)
雪    币: 73
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
2
学习了.帮助很大.确实是加密字符串非常好的思路
2017-5-31 21:40
0
雪    币: 3907
活跃值: (5817)
能力值: ( LV12,RANK:200 )
在线值:
发帖
回帖
粉丝
3
确实是非常好的思路。
2017-6-28 12:27
0
雪    币: 1
活跃值: (30)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
4
思路不错
2017-7-5 23:04
0
雪    币: 2
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
5
人工混淆,利用Clang  语法树  自动提取、再混淆字符串、方法名、属性等;

谢分享,好思路
2017-8-14 17:11
0
雪    币: 628
活跃值: (358)
能力值: ( LV8,RANK:130 )
在线值:
发帖
回帖
粉丝
6

Monkey前来点赞!


课程里面有讲到(逃

2017-8-15 12:38
0
雪    币: 32
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
7
各位有没有clang  生成语法树好的参考资料推荐?
2017-8-18 10:20
0
雪    币: 591
活跃值: (743)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
8
我来偷了资料就跑,真刺激。,学到新姿势
2017-9-15 10:30
0
雪    币: 19
活跃值: (125)
能力值: ( LV5,RANK:60 )
在线值:
发帖
回帖
粉丝
9
怎么把加密的内容编译到app中呢?
2017-10-16 16:50
0
雪    币: 140
活跃值: (125)
能力值: ( LV5,RANK:60 )
在线值:
发帖
回帖
粉丝
10
66666666666
2017-10-17 16:47
0
雪    币: 287
活跃值: (578)
能力值: ( LV5,RANK:60 )
在线值:
发帖
回帖
粉丝
11
名字很666
2017-10-17 21:35
0
雪    币: 3
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
12
学习了
2017-11-28 17:32
0
雪    币: 184
活跃值: (96)
能力值: ( LV4,RANK:50 )
在线值:
发帖
回帖
粉丝
13
25期的兄弟,可以的
2018-1-24 09:32
0
雪    币: 9
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
14
点个赞   
2018-3-5 15:51
0
雪    币: 97
活跃值: (86)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
15
膜拜聂大神
2018-5-7 09:41
0
雪    币: 0
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
16
老哥  跪求你QQ  有事需要你帮助  我QQ210316026
2018-5-10 21:04
0
雪    币: 2
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
17
哈哈哈哈,小白一个,来看热闹,还有mokey
2018-6-13 14:56
0
雪    币: 37
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
18
好东西,多谢!
2018-10-19 12:53
0
雪    币:
能力值: ( LV1,RANK:0 )
在线值:
发帖
回帖
粉丝
19
里面那个方法是加密字符串的呢,没有看到加密方法呀,这个库ParseClangLib.zip 
2020-3-27 15:12
0
游客
登录 | 注册 方可回帖
返回
//