我正在编写一个应用程序,出于安全考虑,我想混淆静态方法返回的值。调用ClassA
中的静态方法的结果应该是BOOL
,但我想尽可能让攻击者尽可能地获得返回的真实值(即我不想要要返回一个BOOL
,我想返回一些看似随机但有些意义的垃圾。
// in ClassA
returnValue = [ClassB staticMethod];
BOOL actaulReturnValue = // some magic to de-obfuscate returnValue
例如:返回1024位大多数随机垃圾,但某处是一个有意义的数字(每次可能是一个不同的位)。
另一个例子:返回10个左右看似随机的数字,但如果这些10个数字出现在pi的前1000个数字中,则实际值为TRUE
(接受10,000,000,000假数中将有1个数字的事实积极率)。
这是我能想到的两个例子,但我将它留给stackoverflow社区来帮助思考其他(可能更好)的方法。如果您还可以提供代码,则可获得奖励积分。
编辑:更难以进行逆向工程。如果我可以运行cycript并确定游戏结束的秘密 编辑2:即使攻击者知道我如何模糊返回值,仍然很难(如果不是不可能)找出真实值(这也是我的第二个例子的问题)< / p>
编辑3:我预先制作iOS应用的笔测试。我理解记忆中的任何东西都可以被阅读,因为我每天都会为客户做这件事。我也不是要暗示混淆和安全是一回事。话虽如此,我试图找出一种方法来阻止攻击者修补单个API调用以始终返回FALSE。
谢谢!
答案 0 :(得分:5)
我会诚实地对你说:不要打扰。原因如下:
在某些时候,您需要将未加密的值加载到内存中
假设您制作方法来模糊其返回值 - 当您实际需要使用该值时会发生什么?你将它取消混淆并将其加载到存储在内存中的变量中。然后你的攻击者只需要检查那个内存位置,这个位置在越狱设备和一些额外的工具上是微不足道的。
你永远不会克服这个问题。做你想做的事绝对没有意义。你基本上注定要失败。如果您有兴趣让我的应用更加安全there's a great book published by O'Reilly,我发现它非常有用。
答案 1 :(得分:0)
您可以对结果执行一些棘手的按位操作以获取一些位索引,并检查该索引处的位以查看它是否已设置,例如。
在以下示例中:
index
。index
- 位该单词是否已设置。这是我测试的解码功能:
-(BOOL)decodeCrypticResult:(long)crypticResult
{
u_int8_t* bytes = (u_int8_t*)&crypticResult;
u_int8_t xor = bytes[1] ^ bytes[3];
u_int8_t idx = ((xor>>4)&0xF) ^ (xor&0xF); // value in range [0..15]
u_int16_t word = ((bytes[2]<<8) & 0xFF00) | bytes[0]; // bytes 2 and 0 concatenated into a 16-bit word
BOOL res = (word >> idx) & 1; // check the idx-th bit of this word
return res;
}
要生成您神秘的结果,要从图书馆的YES
返回一个神秘的NO
或staticMethod
,这很容易:
BOOL
)随机数的第1个或第3个字节中的相应位所以这给出了以下代码:
-(long)returnCrypticBoolValue:(BOOL)boolValue
{
u_int32_t crypticResult = arc4random();
u_int8_t* bytes = (u_int8_t*)&crypticResult;
u_int8_t xor = bytes[1] ^ bytes[3];
u_int8_t idx = ((xor>>4)&0xF) ^ (xor&0xF); // value in range [0..15]
if (boolValue) {
// set the idx-th bit of byte 2 or 0
bytes[ (idx&8)?2:0 ] |= (1 << (idx&7));
} else {
// unset the idx-th bit of byte 2 or 0
bytes[ (idx&8)?2:0 ] &= ~(1 << (idx&7));
}
return crypticResult;
}