保护App重要数据,防止Cycript/Runtime修改
2016-08-13 18:01
330 查看
这一篇文章着重于保护重要数据不被攻击者使用Cycript或者Runtime修改,概要内容如下:
防止choose(类名)
禁忌,二重存在
自己的内存块
虚伪的setter/getter
加密内存数据
English version is here
以下内容均以此假想情况为基础: 我们有一个Person类,它的定义如下:
现在我们需要保护这个类的数据,虽然我们在@property里声明了这两个都是readonly,但是因为Objective-C的runtime特性,这个属性说了基本等于没说(对于破解者而言)。 那么我们要怎么做才能保护呢?
防止choose(类名)
我们知道,在Cycript中可以很方便的使用choose(类名)来获取到App中该类所有的实例变量(图1),那么我们就先从这里下手吧!
解决方案: 重载- (NSString *)description方法。效果如图2所示。
禁忌,二重存在
上面虽然在cycript中用choose函数拿不到了,但是如果一开始就被Hook了init方法怎么办呢?
解决方案:memcpy一份。
首先确定Person类实例的大小:(类指针大小+所有成员变量大小)
然后就可以愉快的memcpy了:
在用的时候,通过__bridge转换:
代码片段:
那么为了模拟实际情况(即init方法被Hook,拿到了normal_man的地址),我们直接在NSLog里输出。
使用Cycript攻击的实际效果如图3、图4:
通过Hook init方法,拿到了normal_man的地址0x7fbffbe06b00。
在Cycript中使用choose,只能看见两个字符串。现在直接调用[#0x7fbffbe06b00 setName:@"Cracker"];更改name属性。
可以看到normal_man的name的确被更改了。而我们memcpy的superman表示无压力。
那么superman的地址也被找到了的话,怎么办呢?如图5
P.S 事实上,它也的确被找到了,cycript会检索所有malloc的内存,图4、图5里,choose执行后的两句NSString就是证明,只不过因为我们重载了description方法,才没有直接看到地址。
自己的内存块
那么我们把这个normal_man复制到自己的一个内存区块如何呢?正好借用之前写的MemoryRegion。试试看吧!
代码片段:(其余部分与上面的相同)
实际效果(图6):
可以看到,现在choose找不到处于MemoryRegion中的superman。
不过就算找不到,Cracker还可以Hook这个类的setter和getter呀!我们又要如何应对呢?
虚伪的setter/getter
让我们把setter和getter改成这个样子:
这样Cracker们通过setter方法就改不了了,也不能通过getter来获取,只能HookIvar了。当然我们也是,那么我们自己要怎么修改呢?添加两个C函数吧!
在修改的时候使用:
在获取的时候:
加密内存区块
在我们把Person类改成上面那个样子之后,已经能阻止大部分只用cycript就想调戏我们的App的人了。
然而,如果Cracker们搜索内存的话,还是有可能找到一些数据的,比如这里superman的年龄,
superman的内存地址是0x102800f00,_age在(0x102800f00 + sizeof(Person *) + sizeof(NSString *)),也就是0x102800f10,如图7。
那么我们不用的时候加密这块内存,用的时候再解密,演示用的加密、解密函数如下,
使用代码:
现在再来看看内存里的数据(图8):
嗯,似乎是没问题了呢~
完整示例代码,https://github.com/BlueCocoa/HookMeIfYouCan
http://www.cocoachina.com/ios/20150511/11801.html
防止choose(类名)
禁忌,二重存在
自己的内存块
虚伪的setter/getter
加密内存数据
English version is here
以下内容均以此假想情况为基础: 我们有一个Person类,它的定义如下:
防止choose(类名)
我们知道,在Cycript中可以很方便的使用choose(类名)来获取到App中该类所有的实例变量(图1),那么我们就先从这里下手吧!
解决方案: 重载- (NSString *)description方法。效果如图2所示。
禁忌,二重存在
上面虽然在cycript中用choose函数拿不到了,但是如果一开始就被Hook了init方法怎么办呢?
解决方案:memcpy一份。
首先确定Person类实例的大小:(类指针大小+所有成员变量大小)
使用Cycript攻击的实际效果如图3、图4:
通过Hook init方法,拿到了normal_man的地址0x7fbffbe06b00。
在Cycript中使用choose,只能看见两个字符串。现在直接调用[#0x7fbffbe06b00 setName:@"Cracker"];更改name属性。
可以看到normal_man的name的确被更改了。而我们memcpy的superman表示无压力。
那么superman的地址也被找到了的话,怎么办呢?如图5
P.S 事实上,它也的确被找到了,cycript会检索所有malloc的内存,图4、图5里,choose执行后的两句NSString就是证明,只不过因为我们重载了description方法,才没有直接看到地址。
自己的内存块
那么我们把这个normal_man复制到自己的一个内存区块如何呢?正好借用之前写的MemoryRegion。试试看吧!
代码片段:(其余部分与上面的相同)
可以看到,现在choose找不到处于MemoryRegion中的superman。
不过就算找不到,Cracker还可以Hook这个类的setter和getter呀!我们又要如何应对呢?
虚伪的setter/getter
让我们把setter和getter改成这个样子:
在我们把Person类改成上面那个样子之后,已经能阻止大部分只用cycript就想调戏我们的App的人了。
然而,如果Cracker们搜索内存的话,还是有可能找到一些数据的,比如这里superman的年龄,
superman的内存地址是0x102800f00,_age在(0x102800f00 + sizeof(Person *) + sizeof(NSString *)),也就是0x102800f10,如图7。
那么我们不用的时候加密这块内存,用的时候再解密,演示用的加密、解密函数如下,
嗯,似乎是没问题了呢~
完整示例代码,https://github.com/BlueCocoa/HookMeIfYouCan
http://www.cocoachina.com/ios/20150511/11801.html
相关文章推荐
- 保护App重要数据,防止Cycript/Runtime修改
- 保护App重要数据,防止Cycript/Runtime修改
- Excel之【保护工作表】功能(工具---->保护) ------可以防止修改格式,删除行。只能在里面填写数据。
- 无刷新显示数据(摘抄)修改。ajax。献给和我一样的人。防止大家看到一堆堆的代码,拿来不能用,改还不知道从那里入手,给人家发消息还不回的人
- mysql数据库的重要数据应当如何保护
- 如何保护MySQL中重要数据的方法
- 如何保护MySQL 中的重要数据
- 保护excel指定单元格数据不被修改的方法
- 构建更加安全的 Web 应用程序-一个新的保护框架可帮助您防止操作和数据篡改
- [cocos2dx]防止八门神器修改内存数据
- 保护MySQL中重要的数据
- 如何保护MySQL 中的重要数据
- mysql数据库中的重要数据应当如何保护
- Google App Engine:如何修改你的数据模型
- 六大步保护MySQL数据库中重要数据
- 生产库数据修改,单条记录;防止forupdate锁表情况。
- 六大步保护MySQL数据库中重要数据
- (GAE文档翻译)Google App Engine中如何修改你的数据模型
- NTFS权限保护重要文件夹防止被删除
- 【C Prime Plus】学习笔记,Chapter 10,用const 修饰形参 保护数据,以防修改