5

我正在构建一个将敏感数据传输到我的服务器的 iOS 应用程序,并且我正在签署我的 API 请求作为附加措施。我想让逆向工程尽可能地困难,并且在使用 Cycript 找到一些真实世界应用程序的签名密钥后,我知道通过附加到进程来找到这些密钥并不难。我绝对知道,如果有人真的很熟练并且足够努力,他们最终被利用,但我会尽可能地努力,同时仍然为我自己和用户提供方便。

我可以检查越狱状态并采取其他措施,或者我可以进行 SSL pinning,但通过附加到进程和修改内存仍然很容易绕过。

有什么方法可以检测是否有某些东西(无论是 Cycript、gdb 还是任何可用于破解进程的类似工具)附加到进程,而不被 App Store 拒绝?

编辑:这不是Detecting if iOS app is run in debugger的副本。该问题与输出更相关,它检查输出流以识别是否有输出流附加到记录器,而我的问题与此无关(并且该检查不涵盖我的情况)。

4

3 回答 3

6

gdb 检测可通过链接的 stackoverflow 问题进行- 它使用 kstat 来确定是否正在调试进程。这将检测调试器当前是否附加到进程。

还有一段代码 -在 iOS 应用程序中使用宏 SEC_IS_BEING_DEBUGGED_RETURN_NIL - 它允许您在代码中的多个位置(它是 C/Objective-C)中添加一个执行调试器附加检查的宏。

至于检测 Cycript,当它针对一个进程运行时,它会在进程中注入一个 dylib 来处理 cycript 命令行和进程之间的通信 - 该库的部分名称看起来像cynject. 该名称看起来与典型 iOS 应用程序中存在的任何库都不相似。这应该可以通过类似 ( C) 的小循环检测到:

BOOL hasCynject() {
    int max = _dyld_image_count();
    for (int i = 0; i < max; i++) {
        const char *name = _dyld_get_image_name(i);
        if (name != NULL) {
            if (strstr(name, "cynject") == 0) return YES;
        }
    }
}

同样,建议给它一个比这更好的名称,并混淆您正在测试的字符串。

这些只是可以采取的方法——不幸的是,这些方法只会在运行时以某种方式保护您,如果有人选择将 IDA 或其他反汇编程序指向它,那么您将不会受到保护。

调试器检查被实现为宏的原因是您会将代码放置在代码中的多个位置,因此尝试修复它的人必须在多个位置修补应用程序。

于 2015-12-07T15:07:10.040 回答
4

根据@petesh 的回答,我发现下面的代码在带有 Cycript 的越狱手机上实现了我想要的。printf 字符串的存在对逆向工程师来说是金子,所以这段代码只适用于演示/破解我的应用程序。

#include <stdio.h>
#include <string.h>
#include <mach-o/dyld.h>

int main ()
{
        int max = _dyld_image_count();
        for (int i = 0; i < max; i++) {
            const char *name = _dyld_get_image_name(i);
            const char needle[11] = "libcycript";
            char *ret;

            if ((ret = strstr(name, needle)) != NULL){
                printf("%s\nThe substring is: %s\n", name, ret);
            }
        }

    return 0;
}
于 2017-07-10T15:56:35.403 回答
2

据我所知,Cycript 进程注入是通过调试符号实现的。因此,如果您去掉 App Store 版本的调试符号(Release 配置的默认构建设置),那将有所帮助。

您可以采取的另一个不会影响应用程序可用性的操作是使用混淆器。但是,这会使任何崩溃报告变得毫无用处,因为即使崩溃报告是符号化的,您也无法理解这些符号。

于 2016-04-09T20:46:49.610 回答