修补应用内购买黑客攻击;卡在第四步。

5
作为我们中的许多人所知,最近有一个与苹果有关的情况,黑客能够免费获得任何应用内购买。苹果最近发布了描述如何修补它的this document,但我对第4步有点困惑,希望得到任何帮助。
首先要做的是下载他们的.patch和.m补丁,将其包含在您的项目中,并针对Security框架进行链接。好的,明白了。然后苹果说:
提供一个base64编码器、一个base64解码器和当验证成功时执行的操作。
请问关于编码器部分的内容,我应该怎么做?(当验证成功时执行的操作对我来说很清楚。)我看到类中有名为base64_encodebase64_decode的函数。但是它要求什么呢?这像是我知道的特殊PIN码,以防止黑客攻击吗?我不确定在这里该怎么做。当然,我理解编码和解码的总体概念,但在这种情况下如何正确生成一个编码器的编程细节我不太清楚。

如果需要,以下是苹果编写的代码:

- (NSString *)encodeBase64:(const uint8_t *)input length:(NSInteger)length
{ 
#warning Replace this method.
    return nil;
}

- (NSString *)decodeBase64:(NSString *)input length:(NSInteger *)length
{
#warning Replace this method.
    return nil;
}

#warning Implement this function.
char* base64_encode(const void* buf, size_t size)
{ return NULL; }

#warning Implement this function.
void * base64_decode(const char* s, size_t * data_len)
{ return NULL; }

我也感到困惑,为什么有两个编码和两个解码函数。我知道有一对返回 NSString* 的函数,但第二对为什么返回一个 char* 和一个 void*?这些函数预期返回什么?我真的不理解。

如果您是注册开发人员(每年可获得两次机会 - 使用或失去),我建议您使用其中一次苹果支持电话。这太重要了,不能犯错误或使用可能不正确的建议。 - Robotic Cat
@RoboticCat 嗯,这是个好主意。我觉得苹果没有在他们给我们的网页上添加一些解释很奇怪。他们逐步解释了简单的事情(下载代码,将其添加到您的项目中),然后在需要实际代码的部分让我们束手无策。感谢您的建议。 - WendiKidd
你有查看过他的网站吗?他说已经找到了VerificationController的解决方法。我们是否应该花时间来实现这个快速修复呢? - PreetKamal Minhas
@PreetKamalMinhas,我在他的网站上没有找到这个信息。你能给我提供链接吗?谢谢! - WendiKidd
2个回答

0
请查看一个由未知作者发布的解决方案:这里
其中包含以下代码,我已经测试并且对我有效:
//  single base64 character conversion
static int POS(char c)
{
    if (c>='A' && c<='Z') return c - 'A';
    if (c>='a' && c<='z') return c - 'a' + 26;
    if (c>='0' && c<='9') return c - '0' + 52;
    if (c == '+') return 62;
    if (c == '/') return 63;
    if (c == '=') return -1;

    [NSException raise:@"invalid BASE64 encoding" format:@"Invalid BASE64 encoding"];
    return 0;
}

- (NSString *)encodeBase64:(const uint8_t *)input length:(NSInteger)length
{
    return [NSString stringWithUTF8String:base64_encode(input, (size_t)length)];
}

- (NSString *)decodeBase64:(NSString *)input length:(NSInteger *)length
{
    size_t retLen;
    uint8_t *retStr = base64_decode([input UTF8String], &retLen);
    if (length)
        *length = (NSInteger)retLen;
    NSString *st = [[[NSString alloc] initWithBytes:retStr
                                             length:retLen
                                           encoding:NSUTF8StringEncoding] autorelease];
    free(retStr);    // If base64_decode returns dynamically allocated memory
    return st;
}

char* base64_encode(const void* buf, size_t size)
{
    static const char base64[] =  "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";

    char* str = (char*) malloc((size+3)*4/3 + 1);

    char* p = str;
    unsigned char* q = (unsigned char*) buf;
    size_t i = 0;

    while(i < size) {
        int c = q[i++];
        c *= 256;
        if (i < size) c += q[i];
        i++;

        c *= 256;
        if (i < size) c += q[i];
        i++;

        *p++ = base64[(c & 0x00fc0000) >> 18];
        *p++ = base64[(c & 0x0003f000) >> 12];

        if (i > size + 1)
            *p++ = '=';
        else
            *p++ = base64[(c & 0x00000fc0) >> 6];

        if (i > size)
            *p++ = '=';
        else
            *p++ = base64[c & 0x0000003f];
    }

    *p = 0;

    return str;
}

void* base64_decode(const char* s, size_t* data_len_ptr)
{
    size_t len = strlen(s);

    if (len % 4)
        [NSException raise:@"Invalid input in base64_decode" format:@"%d is an invalid length for an input string for BASE64 decoding", len];

    unsigned char* data = (unsigned char*) malloc(len/4*3);

    int n[4];
    unsigned char* q = (unsigned char*) data;

    for(const char*p=s; *p; )
    {
        n[0] = POS(*p++);
        n[1] = POS(*p++);
        n[2] = POS(*p++);
        n[3] = POS(*p++);

        if (n[0]==-1 || n[1]==-1)
            [NSException raise:@"Invalid input in base64_decode" format:@"Invalid BASE64 encoding"];

        if (n[2]==-1 && n[3]!=-1)
            [NSException raise:@"Invalid input in base64_decode" format:@"Invalid BASE64 encoding"];

        q[0] = (n[0] << 2) + (n[1] >> 4);
        if (n[2] != -1) q[1] = ((n[1] & 15) << 4) + (n[2] >> 2);
        if (n[3] != -1) q[2] = ((n[2] & 3) << 6) + n[3];
        q += 3;
    }

    // make sure that data_len_ptr is not null
    if (!data_len_ptr)
        [NSException raise:@"Invalid input in base64_decode" format:@"Invalid destination for output string length"];

    *data_len_ptr = q-data - (n[2]==-1) - (n[3]==-1);

    return data;
}

那个链接直接复制了这个 SO 问题(https://dev59.com/uGbWa4cB1Zd3GeqPXHpK?lq=1),实际上是个重复的……不过我还没有来得及看代码,稍后会查看并回复你,谢谢 :) - WendiKidd

0

那个页面上的代码格式非常糟糕,所以我很难阅读它。(即应该是代码的行没有像代码一样格式化,不是代码的行却像代码一样格式化,很难看出示例从哪里开始和结束...)我真的很感谢你试图指引我正确的方向,但我不认为我找到了答案。我也很困惑,链接中的示例有1个编码和1个解码函数,但Apple需要2个——每个都返回一个字符串,然后一个编码返回char,一个解码返回void。为什么是void*?他们想要返回什么?/迷失了 - WendiKidd
嗯,还有,试图进一步查看链接...似乎大多数示例都使用相同的编码表,尽管有些使用巨大的解码表,而其他一些则似乎根本没有填充解码表。所以我在想:如果编码表总是相同的,那它的作用是什么?这不容易被黑客攻击吗?就此而言,如果它总是相同的,为什么苹果不只是编写代码呢?整个问题让我非常困惑... - WendiKidd
这很奇怪,也许与加密功能的出口限制有关?无论如何,我已经添加了第二个链接到答案中,值得一看。排版更好。 - Ben Clayton
@WendiKidd 苹果以出色的产品和糟糕的文档而闻名。他们所有的文档,没有例外,都是含糊不清、不完整、可疑或这些选项的组合。如果他们可以创建一个更加模糊的文档,为什么要提供一个完整的解决方案呢?顺便说一句,我讨厌他们的文档。如果没有像这样的网络论坛,我们将会被毁灭。我们的幸运是,我们有杰出的程序员能够理解苹果使用的克林贡语言。感谢每个在SO上帮助的人。 - Duck

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接