android中native层的检测反调试

举报
小道安全 发表于 2022/04/25 22:06:13 2022/04/25
【摘要】 反调试检测

检测原理

安卓的native下,是运用醉倒的反调试方案是通过读取进程的status或stat来检测tracepid,它主要原理是调试状态下的进程tracepid不为0。

对于这种调试检测手段,因为android系统是开源的,所以最彻底的绕过方式就是修改系统源码后重新编译,让tracepid永远为0。

对抗这种bypass手段,我们可以创建一个子进程,让子进程主动ptrace自身设为调试状态,

此时正常情况下,子进程的tracepid应该不为0。此时我们检测子进程的tracepid是否为0,

如果为0说明源码被修改了。

代码实现

//检测系统实现
bool checkSystemData()
{

// 建立管道
int pipefd[2];
if (-1 == pipe(pipefd))
{

LOGA("pipe() error.\n");

return false;

}

// 创建一个子进程
pid_t pid = fork();

LOGB("father pid is: %d\n",getpid());

LOGB("child pid is: %d\n",pid);

// for失败

if(0 > pid) {

LOGA("fork() error.\n");

return false;

}

// 子进程程序

int childTracePid=0;

if ( 0 == pid )

{

int iRet = ptrace(PTRACE_TRACEME, 0, 0, 0);

if (-1 == iRet)

{

LOGA("child ptrace failed.\n");

exit(0);

}

LOGA("%s ptrace succeed.\n");

// 获取tracepid

char pathbuf[0x100] = {0};

char readbuf[100] = {0};

sprintf(pathbuf, "/proc/%d/status", getpid());

int fd = openat(NULL, pathbuf, O_RDONLY);

if (-1 == fd) {

LOGA("openat failed.\n");

}

read(fd, readbuf, 100);

close(fd);

uint8_t *start = (uint8_t *) readbuf;

uint8_t des[100] = {0x54, 0x72, 0x61, 0x63, 0x65, 0x72, 0x5

0, 0x69, 0x64, 0x3A,0x09};

int i = 100;

bool flag= false;

while (--i)
{

if( 0==memcmp(start,des,10) )
{

start=start+11;childTracePid=atoi((char*)start);

flag= true;

break;

}else

{

start=start+1;

flag= false;

}

}//while

if(false==flag) {

LOGA("get tracepid failed.\n");

return false;

}

// 向管道写入数据

close(pipefd[0]); // 关闭管道读端

write(pipefd[1], (void*)&childTracePid,4); // 向管道写端写入数据

close(pipefd[1]); // 写完关闭管道写端

LOGA("child succeed, Finish.\n");
exit(0);

}

else

{

// 父进程程序
LOGA("开始等待子进程.\n");

waitpid(pid,NULL,NULL); // 等待子进程

结束

int buf2 = 0;

close(pipefd[1]); // 关闭写端

read(pipefd[0], (void*)&buf2, 4); // 从读端读取

数据到buf

close(pipefd[0]); // 关闭读端

LOGB("子进程传递的内容为:%d\n", buf2); // 输出内容

// 判断子进程ptarce后的tracepid

if(0 == buf2) {

LOGA("源码被修改了.\n");

}else{

LOGA("源码没有被修改.\n");

}

return true;

}

}
复制代码

//检测代码的调用
void main()

{

bool bRet=checkSystemData();

if(true==bRet)

LOGA("check succeed.\n");

elseLOGA("check failed.\n");

LOGB("main Finish pid:%d\n",getpid());

return;

}



【版权声明】本文为华为云社区用户原创内容,未经允许不得转载,如需转载请自行联系原作者进行授权。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。