App安全

1.干扰砸壳

1)在Load方法中检测是否越狱,如果是则直接退出。效果:
越狱机无法运行,无法直接使用frida一键砸壳,增加砸壳的困难性。
2)在load方法中使用ptrace或者svc汇编检测是否有调试器附加,一旦lldb调试,则直接闪退。 效果:
通过第一点,逆向开发人员无法直接砸壳,很可能会使用debugserver对App进行启动前附加调试。
这时候load方法检测到调试器,则直接闪退。进一步干扰砸壳。

解决方法:
创建一个tweak,随便写个类,在该类的load方法执行一个耗时操作,足够frida砸壳即可。

2.指定函数的section

关键防护函数或者关键逻辑使用C语言实现,并指定section为非__text。干扰IDA解析,影响动态调试的堆栈打印。例如:

#include "Test.h"
__attribute__ ((section ("__TEXT,objd")))
void say() {
    int a = 10;
    int b = 100;
    if (a > b) {
        printf("hheheh");
    }
}
复制代码

另外像今年的抖音技术博客以及戴铭大佬博客中提到的App包瘦身优化,把所有的代码都挪到别的section了。

3.花指令混淆

核心原理:

通过插入一些垃圾指令(例如:”.long 0x0ffbcfa4\n” ), 干扰 IDA等反汇编工具,无法直接反汇编成伪代码,影响静态分析。

假设一个函数,指令1正在执行,那么指令2正在译码,指令3正在取址,而PC寄存器是保存当前正在取值的地址,也就是说PC保存的是指令3的地址,

重点:

1.只能真机调试,不支持模拟器调试;

2.由于arm64不能直接使用lr, pc等寄存器,因此 需要使用 #ifdef arm64 兼容 arm64和 arm v7,7s。

3.对于 arm64,首先定义一个裸函数 getpc(), 该函数全部有汇编代码实现, 该函数的作用就是 将x30寄存器的值 赋值给 x16寄存器。

即该函数调用的下一条指令地址 赋值给 x16. 然后 x16 + 8 + n * 4 , 其中:

8 是 ( “mov x30,x16\n” “ret\n”)两条指令的长度, n * 4 是 花指令的长度,即 每条花指令长度为 4字节,一共 n条, 再调用 ret指令 跳过这些花指令。

#ifdef __arm64__
  getpc();
 // x16 = x16 + 8 + 4*n,  8是下面两条指令的长度和,4*n 是 n条花指令的长度和。  
  asm volatile("add x16,x16,0x3c\n”    
 	"mov x30,x16\n"
	"ret\n");
复制代码

4.对于armv7, v7s系列:

直接将 pc指令的值赋值给 lr, 然后lr 加上 4 + n * 4 , 其中 4 是

#else
  asm volatile(
  	"mov lr,pc\n"
  	"add lr,0x34\n"
  	"mov pc,lr\n"
  	);
#endif
复制代码

完整示例:

CHDeclareClass(NSURL);
CHMethod1(NSURL *, NSURL, initFileURLWithPath, NSString *, arg1){
 
#ifdef __arm64__
    getpc();
    asm volatile("add x16,x16,0x3c\n"
                 "mov x30,x16\n"
                 "ret\n");
#else
    asm volatile(
                 "mov lr,pc\n"
                 "add lr,0x34\n"
                 "mov pc,lr\n"
                 );
#endif
    asm volatile(
                 ".long 0x0ffbcfa4\n"
                 ".long 0xc89c684a\n"
                 ".long 0xc65a557c\n"
                 ".long 0xfe0772d9\n"
                 ".long 0x3e23ad4d\n”
                 ".long 0x3d8329ff\n"
                 ".long 0xd2193731\n"
                 ".long 0x4e7d2760\n"
                 ".long 0x0e79de99\n"
                 ".long 0xf4d1efaf\n”
                 ".long 0xa82158dd\n"
                 ".long 0x33198ce6\n"
                 );
    
    if (arg1 != nil) {
        return CHSuper1(NSURL, initFileURLWithPath, arg1);
    } else {
        return nil;
    }
}

__attribute__((naked)) void getpc(void) {
#ifdef __arm64__
    asm volatile ("sub sp,sp,0x10\n"
                 "stp x29,x30,[sp]\n"
                 "mov x0,%0\n"
                 "add x0,x0,40\n"
                 "br x0\n"
                 ".long 0x1234dfae\n"
                 ".long 0x1234dfae\n"
                 ".long 0x1234dfae\n"
                 "ldp x29,x30,[sp]\n"
                 "mov x16,x30\n"
                 "add sp,sp,0x10\n"
                 "ret\n"
                 :
                 :"r"(&getpc)
                 :"x0");
#endif
}

复制代码
© 版权声明
THE END
喜欢就支持一下吧
点赞0 分享