Android Framework 使用AMS实时监控应用进程死亡

修改文件:

ActivityManagerService.java

APK

原理:

         原生代码中会在每个应用进程启动时,创建一个AppDeathRecipient对象来监控其是否death,进程挂掉(包括走onDestroy的、或者crash)后,执行回调方法处理此应用的各组件资源的后续。利用此点,我们定义一个自己的XXXXCallerDeathRecipient类,并在其回调中写我们要在进程挂掉时需要同时做的事。
         功能代码需要写在AMS所在的包中,要从AMS的包内变量mPidsSelfLocked获取相关应用进程。
         应用端通过获取ams服务(详见我另一篇 访问系统隐藏类 的随笔),调用 watchXXXXDeathforProcess 并传入应用pid即可。

代码例如:

apk侧:

int pid = android.os.Process.myPid();
Log.v("XXXX",  "myPID: " + pid);
Method method = null;
try {
    method = Class.forName("android.os.ServiceManager").getMethod("getService", String.class);
    IBinder binder = (IBinder) method.invoke(null, Context.ACTIVITY_SERVICE);
    IActivityManager mIPm = IActivityManager.Stub.asInterface(binder);
    mIPm.watchXXXXDeathforProcess(pid);
} catch (NoSuchMethodException | ClassNotFoundException | InvocationTargetException | IllegalAccessException | RemoteException e) {
    Log.e("XXXX", "XXXX catch Exception: " + e);
    e.printStackTrace();
}

Framework侧:

ActivityManagerService.XXXXCallerDeathRecipient adr;

private final class XXXXCallerDeathRecipient implements IBinder.DeathRecipient {
    final ProcessRecord mApp;
    final int mPid;
    final IApplicationThread mAppThread;

    XXXXCallerDeathRecipient(ProcessRecord app, int pid,
                      IApplicationThread thread) {
        if (DEBUG_ALL) Slog.v(
                TAG, "XXXX death recipient " + this
                        + " for thread " + thread.asBinder());
        mApp = app;
        mPid = pid;
        mAppThread = thread;
    }

    @Override
    public void binderDied() {
        Slog.v(TAG, "XXXX Death received in " + this + " for thread " + mAppThread.asBinder() + "  mPid is " + mPid);
        try {
            // your code
        } catch (RemoteException e) {
            Slog.e(TAG, "XXXX restoreAllDirOwner has RemoteException when binderDied: " + e);
        }
        mApp.getThread().asBinder().unlinkToDeath(adr, 0);
    }
}

public boolean watchXXXXDeathforProcess(int pid) {
    ProcessRecord app;
    if (pid != MY_PID && pid >= 0) {
        synchronized (mPidsSelfLocked) {
            app = mPidsSelfLocked.get(pid);
        }
        Slog.d(TAG, "XXXX watchDeathforProcess for: " + app.processName + "    pid: " + app.mPid);
        try {
            adr = new ActivityManagerService.XXXXCallerDeathRecipient(
                    app, pid, app.getThread());
            app.getThread().asBinder().linkToDeath(adr, 0);
            app.setDeathRecipient(adr);
            return true;
        } catch (RemoteException e) {
            Slog.e(TAG, "XXXX watchDeathforProcess has RemoteException: " + e);
        }
    }
    return false;
}

 

posted @ 2023-03-02 15:47  小汀  阅读(345)  评论(0编辑  收藏  举报