共计 2159 个字符,预计需要花费 6 分钟才能阅读完成。
持续上篇文章:如何给 iOS APP 加固 第一章【附代码】
3. 避免动静调试
黑客能够通过动静调试应用程序,获取应用程序的外部信息和逻辑,从而攻打应用程序。能够在应用程序中集成避免动静调试的代码,如 AntiDebugging。
1)检测调试器是否存在
能够通过检测以后过程是否存在调试器来判断是否处于调试状态。以下是示例代码:
#include <assert.h> | |
#include <stdbool.h> | |
#include <sys/types.h> | |
#include <unistd.h> | |
#include <sys/sysctl.h> | |
bool am_i_being_debugged() {int name[4]; | |
struct kinfo_proc info; | |
size_t info_size = sizeof(info); | |
info.kp_proc.p_flag = 0; | |
name[0] = CTL_KERN; | |
name[1] = KERN_PROC; | |
name[2] = KERN_PROC_PID; | |
name[3] = getpid(); | |
if (sysctl(name, 4, &info, &info_size, NULL, 0) == -1) {perror("sysctl"); | |
exit(EXIT_FAILURE); | |
} | |
return ((info.kp_proc.p_flag & P_TRACED) != 0); | |
} |
在上述代码中,通过检测以后过程的标记来判断是否存在调试器。
2) 检测调试器是否开启
能够通过检测以后过程的环境变量来判断是否处于调试状态。以下是示例代码:
#include <assert.h> | |
#include <stdbool.h> | |
#include <stdlib.h> | |
bool am_i_being_debugged() {return (getenv("DYLD_INSERT_LIBRARIES") != NULL); | |
} |
在上述代码中,通过检测环境变量来判断是否存在调试器。
3) 破解断点
能够在应用程序中退出代码来破解调试器中的断点。以下是示例代码:
#include <signal.h> | |
#include <stdio.h> | |
void disable_debugger_breakpoint() {ptrace(PT_DENY_ATTACH, 0, 0, 0); | |
signal(SIGTRAP, signal_handler); | |
} | |
void signal_handler(int signal) {printf("Debugging signal received!\n"); | |
} |
在上述代码中,应用 ptrace 函数来禁用附加调试器的性能,并应用 signal 函数来解决调试信号。
4. 避免反向工程
黑客能够通过反向工程获取应用程序的源代码和算法,因而须要避免反向工程。能够应用代码混同、加密、应用动态链接库等办法来避免反向工程。
1) 字符串加密
能够在应用程序中对字符串进行加密,以避免歹意用户对应用程序进行反向工程。以下是示例代码:
NSString* encryptString(NSString* str) {NSMutableString* result = [NSMutableString new]; | |
for (int i = 0; i < [str length]; i++) {[result appendFormat:@"%c", [str characterAtIndex:i] ^ 0x7F]; | |
} | |
return [result copy]; | |
} |
在上述代码中,将每个字符与 0x7F 异或,以加密字符串。
2) 函数指针混同
能够在应用程序中应用函数指针混同技术,以避免反向工程者通过符号表来查找函数。以下是示例代码:
void (*functionPointer)(int) = NULL; | |
void func1(int arg1) {//...} | |
void func2(int arg1) {//...} | |
void init() {if (rand() % 2 == 0) {functionPointer = func1;} else {functionPointer = func2;} | |
} | |
int main() {init(); | |
functionPointer(0); | |
} |
在上述代码中,将函数指针随机赋值为两个函数之一,以减少反向工程的难度。
3) 代码混同
能够在应用程序中应用代码混同技术,以使反向工程者无奈了解应用程序的代码构造。以下是示例代码:
#define encode(str) encryptString(@#str) | |
#define func1Name encode(aaa) | |
#define func2Name encode(bbb) | |
void func1(int arg1) {//...} | |
void func2(int arg1) {//...} | |
int main() {[func1Name UTF8String]; // 此处不会执行理论代码 | |
[func2Name UTF8String]; // 此处不会执行理论代码 | |
func1(0); | |
func2(0); | |
} |
在上述代码中,应用宏定义来加密函数名,使反向工程者无奈轻易了解应用程序的代码构造。
避免反向工程是 iOS 利用程序开发中十分重要的一部分,上述示例代码能够帮忙您理解如何在应用程序中退出代码来爱护应用程序的平安。但须要留神的是,这些技术并不能齐全保障应用程序的平安,反向工程者依然有可能破解应用程序。
明天就讲到这里啦,下篇文章有空持续!