开启掘金成长之旅!这是我参与「掘金日新计划 · 12 月更文挑战」的第16天,点击查看活动详情
前言
- 应用场景:签名函数,把函数名隐藏在结构体里,以函数指针成员的形式存储来进行敏感逻辑的保护。
为了提高代码的安全性,可以采用把把函数名隐藏在结构体里,以函数指针成员的形式存储。 编译后,只留了下地址,去掉了名字和参数表,提高了逆向成本和攻击门槛.
在OC 开发中使用C 语言实现算法相关的功能,来保障代码的安全性。 iOS 的底层是用 C C++ 实现的,编译之后生成的大都是 subroutine, class-dump 拿它没办法,只能使用IDA工具。
I 防止静态分析
1.1 使用static inline方式编译函数,防止静态分析。
使用inline方式将函数在调用处强制展开,防止被hook和追踪符号。
static __attribute__((always_inline)) void anti_debug()
//一般的函数调用都会通过call的方式来调用,hacker很容易对一个函数做手脚,如果是以inline的方式编译的,会把该函数的code拷贝到每次调用该函数的地方;而static会让生成的二进制文件中没有清晰的符号表,让逆向的人很难弄清楚代码逻辑
查看汇编文件: 选中xx.m文件-->Xcode 菜单 --> Product --> Perform Action --> Assemble "xx.m"
与#define的区别:
- 使用
#define宏定义的代码,编译器不会对其进行参数有效性检查,仅仅只是对符号表进行替换。 #define宏定义的代码,其返回值不能被强制转换成可转换的适合的类型。
static inline BOOL isIPhoneXSeries() {
if (@available(iOS 11.0, *)) {
UIWindow *mainWindow = [[[UIApplication sharedApplication] delegate] window];
if (mainWindow.safeAreaInsets.bottom > 0.0) {
return YES;
}
}
return NO;
}
1.2 把函数名隐藏在结构体里,以函数指针成员的形式存储
从CSDN下载Demo:https://download.csdn.net/download/u011018979/16751837
1、应用场景:签名函数 2、原理:为了提高代码的安全性,可以采用把把函数名隐藏在结构体里,以函数指针成员的形式存储。 编译后,只留了下地址,去掉了名字和参数表,提高了逆向成本和攻击门槛. 3、文章:kunnan.blog.csdn.net/article/det…
1.3 使用宏进行替换字符串,来保护关键类名、方法名
- 根据前缀搜索出需要混淆的类名、方法名, 生成对应的宏文件
#define run OmWJoTZfCqoPshvr
#define iosre egnjoOFDrFiQVRgr
这样使用hopper等反汇编工具无法根据string搜索到关键字符
1.4 签名key 的存储
//https://kunnan.blog.csdn.net
//HexStrToString https://tool.lu/hexstr/
#define KNfir @"68747470733a2f2f"
#define KNfir1 @"6b756e6e616e2e626c6f672e6373646e"
#define KNfir2 @"2e6e6574"
#define key4pay [NSString stringWithFormat:@"%@%@%@",KNfir,KNfir1,KNfir2]
#define key4paystr [GeneralUtil convertHexStrToString:key4Unionpay]
+(NSString *)translate:(NSString *)content{
return [GeneralUtil convertHexStrToString:content];
}
- 二进制转字符串
// 二进制转字符串
//
#import "GeneralUtil.h"
@implementation GeneralUtil
+ (BOOL)isBlankString:(NSString *)string {
if (string == nil || string == NULL) {
return YES;
}
if ([string isKindOfClass:[NSNull class]]) {
return YES;
}
if ([[string stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceCharacterSet]] length]==0) {
return YES;
}
return NO;
}
+ (NSString *)convertHexStrToString:(NSString *)str {
if (!str || [str length] == 0) {
return nil;
}
NSMutableData *hexData = [[NSMutableData alloc] initWithCapacity:8];
NSRange range;
if ([str length] % 2 == 0) {
range = NSMakeRange(0, 2);
} else {
range = NSMakeRange(0, 1);
}
for (NSInteger i = range.location; i < [str length]; i += 2) {
unsigned int anInt;
NSString *hexCharStr = [str substringWithRange:range];
NSScanner *scanner = [[NSScanner alloc] initWithString:hexCharStr] ;
[scanner scanHexInt:&anInt];
NSData *entity = [[NSData alloc] initWithBytes:&anInt length:1];
[hexData appendData:entity];
range.location += range.length;
range.length = 2;
}
NSString *string = [[NSString alloc]initWithData:hexData encoding:NSUTF8StringEncoding];
return string;
}
@end
II 敏感信息的安全设计Checklist
-
临时产生的敏感数据(写入内存或文件),应具有及时清除和释放机制
-
不要在 HTTP GET 请求参数中包含敏感信息,如用户名、密码、卡号、ID等
-
禁止表单中的自动填充功能,因为表单中可能包含敏感信息,包括身份验证信息
-
不要在客户端上以明文形式保存密码或其他敏感信息
-
为所有敏感信息采用SSL加密传输
-
禁止将敏感信息(包含加密秘钥等)硬编码在程序中
-
不要在日志中保存敏感信息,包含但不限于系统详细信息、会话标识符、密码等
-
禁止在异常中泄露应用服务器的指纹信息,如版本,路径,组件版本等 -
禁止将源码或sql上传到开源平台或社区,如github、CSDN -
请求中含有敏感参数(如订单号、ID等),应进行混淆方式处理,防止产生参数遍历获取信息风险
敏感信息需要展示在web页面上时,应在后台进行敏感字段脱敏处理
身份证、银行卡号 姓名 预留手机号
- 请求返回数据不应包含请求之外的业务数据,特别是敏感信息数据
see also
公众号:iOS逆向