一个IOS的ipa包被反编译后,其中已初始化的字符串都是完整可见的。 针对于iOS的Mach-O二进制通常可获得以下几种字符串信息:
1、资源文件名 2、可见的函数符号名 3、SQL语句 4、对称加密算法的key。尤其是4,很多app会用对称加密算法,但是客户端保存私钥却是不安全的!对于攻击者来说,如果能从反编译出来的二进制中获取到私钥,却是一件幸福的事!因为你的加密基本瓦解,而且攻击者会从中获得继续破解你的app的乐趣(毕竟反编译出来的二进制真的是需要有很大的毅力才能坚持得下去,不然会让人分分钟摔桌子)。
对于字符串加解密,常规的方法就是进行异或加解密。
来写个sample code:
static unsigned char XOR_KEY = 0xBB;
void xorString(unsigned char *str, unsigned char key)
{
unsigned char *p = str;
while( ((*p) ^= key) != '\0') p++;
}
- (NSString *)toeknNew_key
{
unsigned char str[] = {(XOR_KEY ^ 'w'),//welcome
(XOR_KEY ^ 'e'),
(XOR_KEY ^ 'l'),
(XOR_KEY ^ 'c'),
(XOR_KEY ^ 'o'),
(XOR_KEY ^ 'm'),
(XOR_KEY ^ 'e'),
(XOR_KEY ^ '\0')};
xorString(str, XOR_KEY);
static unsigned char result[7];
memcpy(result, str, 7);
return [NSString stringWithFormat:@"%s",result]; //输出: welcome
}
这样就无法从二进制中直接分析得到字符串“welcome”了 ,稍微好了很多。但是扔进IDA里分析一下,发现效果不好,连续存储的’w’、’e’等字符还是暴露了可读的”welcome”,
改进一下,取消
XOR_KEY
独立变量的身份,改为宏,作为数据直接插入,这样:
#define XOR_KEY 0xBB
void xorString(unsigned char *str, unsigned char key)
{
unsigned char *p = str;
while( ((*p) ^= key) != '\0') p++;
}
- (NSString *)toeknNew_key
{
unsigned char str[] = {(XOR_KEY ^ 'w'),//welcome
(XOR_KEY ^ 'e'),
(XOR_KEY ^ 'l'),
(XOR_KEY ^ 'c'),
(XOR_KEY ^ 'o'),
(XOR_KEY ^ 'm'),
(XOR_KEY ^ 'e'),
(XOR_KEY ^ '\0')};
xorString(str, XOR_KEY);
static unsigned char result[7];
memcpy(result, str, 7);
return [NSString stringWithFormat:@"%s",result]; //输出: welcome
}
出来的效果好多了。
什么也没看出key是多少,我们的目的达到了。
ps:当然,XOR_KEY并不是只能是0XBB,0XAA、0X22、0X11等十六进制数都可以的。