android 反调试(TracePid 不断轮询检查 JAVA )

android 反调试(TracePid 不断轮询检查 JAVA )

在android 中,在调试状态下,linux会向/proc/"进程PID"/status 中写入状态信息。其中TracePid 就是调试该进程的进程的的Pid,所以反调试的方法之一就是通过不断轮询检查TracePid的值,假如为0的话,说明该进程没有被调试,假如不为0的话,就说明当前该进程正在被调试,程序执行exit(0)操作。

892910cbdbe87fdea4953c364d0d201d.png

我直接用一个类来包装我的adb shell:

先通过getpid()函数来查找当前我们程序的pid.然后利用Runtime.getRuntime.exec()函数来执行adb 命令,然后通过BufferReader来读取status 并放入String中。

public final class RootCmd {

public static String GetTracePid(){

int pid =getpid();

String ss=String.valueOf(pid);

Process p = null;

try {

p = Runtime.getRuntime().exec("cat /proc/"+ss+"/status");

} catch (IOException e) {

e.printStackTrace();

}

String data = null;

BufferedReader ie = new BufferedReader(new InputStreamReader(p.getErrorStream()));

BufferedReader in = new BufferedReader(new InputStreamReader(p.getInputStream()));

String error = null;

try {

while ((error = ie.readLine()) != null

&& !error.equals("null")) {

data += error + "\n";

}

} catch (IOException e) {

e.printStackTrace();

}

String line = null;

try {

while ((line = in.readLine()) != null

&& !line.equals("null")) {

data += line + "\n";

}

} catch (IOException e) {

e.printStackTrace();

}

Log.v("ls", data);

String tmp=data.split("\n")[7];

tmp=tmp.replace("TracerPid:","");

// Log.i("TracePid",tmp);

return tmp;

}

在MainActivity中利用线程不断轮询执行该函数,因为toast只能在主线程中执行,所以利用handleMessage向主线程发送消息。我这里没有用Timer来实现不断轮询执行,我用的是线程的sleep函数

public class MainActivity extends AppCompatActivity {

private Handler handler ;

@Override

protected void onCreate(Bundle savedInstanceState) {

super.onCreate(savedInstanceState);

setContentView(R.layout.activity_main);

handler=new Handler() {

@Override

public void handleMessage(Message msg) {

super.handleMessage(msg);

if (msg.what == 0) {

Toast toast = Toast.makeText(getApplicationContext(), "程序没有正在被调试", Toast.LENGTH_LONG);

//显示toast信息

//toast 只能在主线程中执行,所以利用handeler message 向主线程发送消息

toast.show();

}

if (msg.what == 1) {

Toast toast = Toast.makeText(getApplicationContext(), "程序正在被调试", Toast.LENGTH_LONG);

//显示toast信息

toast.show();

exit(0);

}

}

};

/* Log.i("SSSSS", "调试开始了");

int pid =getpid();

String ss=String.valueOf(pid);

Log.i("SSSSS",ss);

Toast toast=Toast.makeText(getApplicationContext(),ss, Toast.LENGTH_LONG);

//显示toast信息

toast.show();*/

//利用线程的sleep 定时轮询检查TracePid

new Thread() {

@Override

public void run() {

//这里写入子线程需要做的工作

int flag=1;

while(flag!=0) {

String Tracepid = RootCmd.GetTracePid().trim(); //执行adb命令,查找当前程序是否正在被调试

int Trace = Integer.valueOf(Tracepid).intValue();

if (Trace != 0) {

Log.i("TracePid", "程序正在被调试");

Message message=new Message();

message.what=1;

handler.sendMessage(message);

} else {

Log.i("TracePid", "程序没有正在被调试");

Log.i("TracePid", Tracepid);

Message message=new Message();

message.what=0;

handler.sendMessage(message);

}

try {

Thread.sleep(10000);

} catch (InterruptedException e) {

e.printStackTrace();

}

}

}

}.start();

}

}

android 反调试(TracePid 不断轮询检查 JAVA )相关教程

Logo

华为开发者空间,是为全球开发者打造的专属开发空间,汇聚了华为优质开发资源及工具,致力于让每一位开发者拥有一台云主机,基于华为根生态开发、创新。

更多推荐