0

我正在编写一个应用程序,出于安全原因,我想混淆从静态方法返回的值。调用静态方法的结果ClassA应该是 aBOOL但我想让攻击者尽可能难以获得返回的真实值(即我不想返回 a 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:即使攻击者知道我是如何混淆返回值的,它仍然应该很难(如果不是不可能的话)找出真正的值(这也是我的第二个示例的问题)

编辑 3:我以对 iOS 应用程序进行渗透测试为生。我知道内存中的任何内容都可以读取,因为我每天都在为客户做这件事。我也不是要暗示混淆和安全是一回事。话虽如此,我正试图找出一种方法来防止攻击者修补单个 API 调用以始终返回 FALSE。

谢谢!

4

2 回答 2

5

我对你说实话:不要打扰。原因如下:

在某些时候,您需要将未加密的值加载到内存中

假设你设计了你的方法来混淆它的返回值——当你真正需要使用那个值时会发生什么?您对其进行混淆处理并将其加载到内存中存在的变量中。然后你的攻击者只需要检查那个内存位置,在越狱设备和一些额外的工具上是微不足道的。

你永远无法克服这个问题。做你想做的事绝对没有意义。你基本上注定要失败。如果您有兴趣让您的应用程序更安全,那么我发现O'Reilly 出版的一本很棒的书非常有用。

于 2012-10-12T20:59:42.227 回答
0

例如,您可以对结果进行一些棘手的按位运算以获得一些位索引,并检查该索引处的位以查看它是否已设置。

在以下示例中:

  • 然后给定 32 位的神秘结果,我计算神秘结果的第 2 和第 4 个字节的 XOR,然后再次将高 4 位与低 4 位进行异或。这给了我一个 4 位的结果,可以解释为index0 到 15 之间的值。
  • 然后我使用这个索引来知道我需要在剩余的 2 个字节中检查哪个位:我连接第 3 个字节和第一个字节以获得一个 16 位字,并检查该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;
}

要生成您的神秘结果以返回一个神秘的YESNOstaticMethod您的库中返回,这很容易:

  • 生成一个随机的 32 位数字
  • 从这个随机数的表示中计算上面的位索引
  • 在返回之前设置或取消设置(取决于BOOL您需要返回)随机数的第一个或第三个字节中的相应位

所以这给出了以下代码:

-(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;
}
于 2012-10-12T20:53:20.110 回答