0%

Android反调试--SIGTRAP

记录一个通过在原代码插入断点指令的方式来达到反调试的方法.
参考 YK 大佬的文章
[原创] 2022 腾讯游戏安全竞赛安卓客户端决赛 writeup

注册异常处理函数,保存原函数指令后替换为 brk #0

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
unsigned char bp[]={0x00,0x00,0x20,0xD4}; //brk #0
unsigned char backup[4]={0x00,0x00,0x00,0x00};//用来保存原指令
void *anti_debug(void *arg){
//注册异常函数
struct sigaction act ;
memset(&act ,0 ,sizeof(act));
act.sa_sigaction = &handler ;
act.sa_flags =SA_NODEFER|SA_RESETHAND;
sigaction(SIGTRAP,&act ,NULL);

//修改内存权限
int pageSize = getpagesize();
unsigned long addr= (unsigned long )(test);
unsigned long mem = addr & (~(pageSize - 1));
LOGD("mprotect:%d",mprotect((void *)(mem), pageSize, PROT_READ|PROT_WRITE|PROT_EXEC));

//保存并替换test函数的指令
memmove((void*)backup,(void*)test, sizeof(backup));
memmove((void*)test,(void*)bp, sizeof(bp));

//等待调试器附加,时间需看实际情况
//sleep(1);

//触发断点函数
test();
}
1
2
3
4
5
6
7
void handler (int sig ,siginfo_t *siginfo , void * context){
LOGD("handler");
memmove((void*)test,(void*)backup, sizeof(backup));//把断点指令恢复
__builtin___clear_cache((char*)test, (char*)test + 8); //刷新缓存
LOGD("handler finish");
return;
}
1
2
3
4
void test(){
LOGD("test_fun");
return;
}

在我测试的时候,发现并不是 100% 能成功卡住调试器,猜测是附加的过程中已经处理完断点流程
建议在 test 前调用 sleep 函数等待调试器附加完成