我正在构建一个将敏感数据传输到我的服务器的iOS应用程序,并且我作为一项额外措施签署了我的API请求。我想尽可能地进行逆向工程,并且使用Cycript查找某些真实应用程序的签名密钥,我知道通过附加到进程来找到这些密钥并不困难。我完全清楚,如果有人真的很熟练,并且足够努力,他们最终将利用,但我试图尽可能地努力,而我仍然方便自己和用户。
我可以检查越狱状态并采取其他措施,或者我可以执行SSL固定,但通过附加到进程并修改内存,两者仍然很容易绕过。
有没有办法检测某些(无论是Cycript,gdb还是可用于破解流程的任何类似工具)是否附加到流程中,而不是被拒绝App Store?
编辑:这不是Detecting if iOS app is run in debugger的重复。该问题与输出更相关,它检查输出流以确定是否有一个输出流附加到记录器,而我的问题与此无关(并且该检查不包括我的条件)
答案 0 :(得分:6)
gdb检测是可行的via the linked stackoverflow question - 它使用kstat来确定进程是否正在被调试。这将检测调试器当前是否附加到进程。
还有一段代码 - Using the Macro SEC_IS_BEING_DEBUGGED_RETURN_NIL in iOS app - 允许您在代码中的各个位置输入一个执行调试器附加检查的宏(它的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或其他反汇编程序,那么您就不会受到保护。
调试器的检查是作为宏实现的原因是你将代码放在代码中的各个位置,因此有人试图修复它将需要修补各种应用程序的地方。
答案 1 :(得分:3)
根据@ petesh的回答,我发现下面的代码在带有Cycript的越狱手机上达到了我想要的效果。 printf字符串的存在对于逆向工程师来说是个黄金,所以这段代码只适用于demo / crack-me应用程序。
#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;
}
答案 2 :(得分:2)
据我所知,Cycript过程注入可以通过调试符号实现。因此,如果您删除App Store版本的调试符号(Release配置的默认构建设置),那将有所帮助。
您可以采取的另一个操作,即对App的可用性没有影响,将使用混淆器。但是,这会导致任何崩溃报告无效,因为即使崩溃报告已被符号化,您也无法理解符号。