阅读本文之前 请先阅读 我之前写的文章 《Android安全之使用root权限绕过检测机制,强行自动允许应用的悬浮窗/应用后台弹出界面等权限》
了解前篇文章里面的如下几点知识点,作为本篇的基础:
1.在linux下如何直接运行dex (java代码) 让java代码全程拥有root权限去运行一些系统api
2.导入framework.jar, 以方便进行快速的免反射开发 (可选, 但是这样的话你得自己写反射和接口代理)
通过在linux下执行这段dex代码可以越权获取到topActivity
//获取顶部activity
public ComponentName getTopActivity(){
ComponentName topActivity = null;
for (ActivityManager.StackInfo allStackInfo : ActivityTaskManager.getService().getAllStackInfos()) {
if (allStackInfo.visible && allStackInfo.displayId == Display.DEFAULT_DISPLAY) {
topActivity =allStackInfo.topActivity;
}
}
return topActivity;
}
while(true){
String act = getTopActivity();
System.out.println("topActivity=" + act );
}
哈哈哈哈哈…
骗你的, 要是这么死循环获取就不会有这篇文章了…
把以下代码 打包成jar 用dx命令打包成一个dex 运行即可 (教程在前面说的文章里)
public static void main(String[] args) throws Exception {
Looper.prepareMainLooper();
registerTaskStackChangedListener(new TaskStackListener() {
@Override
public void onTaskStackChanged() throws RemoteException {
super.onTaskStackChanged();
//获取顶部activity
ComponentName topActivity = null;
for (ActivityManager.StackInfo allStackInfo : ActivityTaskManager.getService().getAllStackInfos()) {
if (allStackInfo.visible && allStackInfo.displayId == Display.DEFAULT_DISPLAY) {
topActivity =allStackInfo.topActivity;
}
}
sendText(""+topActivity);
}
});
Looper.loop();
}
//注册栈改变监听
private static void registerTaskStackChangedListener(TaskStackListener listener) throws Exception {
if (mTaskStackListener != null) {
ActivityTaskManager.getService().unregisterTaskStackListener(mTaskStackListener);
}
mTaskStackListener = (ITaskStackListener) listener;
ActivityTaskManager.getService().registerTaskStackListener(mTaskStackListener);
}
//利用发广播的方式 实现 通讯"回调"
private static void sendText(String text) {
String action = "com.dddd.zzzz.TEST";
try {
Intent intent = new Intent(action);
intent.putExtra("text", text);
getContext().sendBroadcast(intent);
} catch (Exception e) {
e.printStackTrace();
}
}
原理:
利用root权限执行 ActivityTaskManager.getService()注册一个activity栈变化监听,避免了死循环获取, 减少耗电量, 取出当前的topActivity后 通过自己创建的上下文 通过广播发送出去, 如然后你只需用广播接收器去接收数据即可
这没啥好说的 就是接收linux里的dex app进程发过来的广播
registerReceiver(object : BroadcastReceiver() {
override fun onReceive(context: Context?, intent: Intent?) {
LaihuaLogger.i("onReceive MX: ${intent?.action} ${intent?.getStringExtra("text")}")
}
}, IntentFilter("com.dddd.zzzz.TEST"))
1.linux下自己创建自己的上下文 解决了之前文章《Android安全之使用root权限绕过检测机制,强行自动允许应用的悬浮窗/应用后台弹出界面等权限》中 到最后无法拿到context去调用一些需要context 的api 时的抓狂…
//TODO 此处为了演示 没做上下文缓存, 会导致每次都会生成新的上下文
private static Context getContext() throws Exception {
Class<?> ActivityThread = Class.forName("android.app.ActivityThread");
Method systemMain = ActivityThread.getDeclaredMethod("systemMain");
Object object = systemMain.invoke(null);
Class<?> ContextImpl = Class.forName("android.app.ContextImpl");
Method createSystemContext = ContextImpl.getDeclaredMethod("createSystemContext", ActivityThread);
createSystemContext.setAccessible(true);
return (Context) createSystemContext.invoke(null, object);
}
2.创建Handler运行环境, 某些系统api需要基于Handler环境进行运作
Looper.prepareMainLooper();
//你的代码
xxxxxxx
Looper.loop();
联系客服