Detection principle

In Android native, the anti-debug solution is to detect the tracepID by reading the status or stat of the process. The main principle of this solution is that the tracepID of the process in debug state is not 0.

Since Android is open source, the most thorough way around this debugging detection is to modify the source code and recompile it so that tracepID is always 0.

To counter this bypass approach, we can create a child process and have the child process actively set ptrace itself to debug.

Normally, the tracepID of the child process should not be 0. At this point we check whether the child process tracepID is 0,

0 indicates that the source code has been modified.

Code implementation

// Check the system implementation
bool checkSystemData(a)
{

// Build the pipeline
int pipefd[2];
if (- 1= =pipe(pipefd))
{

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

return false;

}

// Create a child process
pid_t pid = fork();

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

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

/ / for failure

if(0 > pid) {

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

return false;

}

// Subprocess

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");

/ / get 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;

}

// Write data to the pipe

close(pipefd[0]); // Close the pipe read side

write(pipefd[1], (void*)&childTracePid,4); // Write data to the write side of the pipe

close(pipefd[1]); // Close the pipe write end after writing

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

}

else

{

// Parent program
LOGA("Start waiting for child process. \n");

waitpid(pid,NULL.NULL); // Wait for the child processThe end of theint buf2 = 0;

close(pipefd[1]); // Close the write end

read(pipefd[0], (void*)&buf2, 4); // Read from the readerData to thebuf

close(pipefd[0]); // Close the read end

LOGB("Child process passed content :%d\n", buf2); // Output content

// Determine the tracepID after the child process ptarce

if(0 == buf2) {

LOGA("Source code has been modified.\n");

}else{

LOGA("The source code has not been modified.\n");

}

return true; }}Copy the code

// Check for code calls
void main(a)

{

bool bRet=checkSystemData(a);if(true==bRet)

LOGA("check succeed.\n");

elseLOGA("check failed.\n");

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

return;

}

Copy the code