某些应用如何在 Android 上跟踪自己的卸载

我发现360安全应用程序卸载后在浏览器中打开他们的页面。

他们可以在所有Android版本(4.,5.和6.*)上做到这一点,我不明白如何。

也许有人有什么想法?我知道这里这里以及其他问题的相同问题,但他们仍然没有答案。

这不是一个错误,因为它仅适用于<4.4.2 android,没有其他进程以新的方式监听相同的错误,我检查了一下。inotify

他们的图书馆里有一些魔力eternity.so


答案 1

让我试着澄清一下。

在 Android 4.4 之前,我们可以使用 ,它提供了一种监视文件系统事件的机制,我们创建了一个守护程序来监视我们在应用程序目录中创建的文件是否被删除或我们的主应用程序目录被删除,这应该发生在用户卸载应用程序时,JNI 代码将如下所示:inotify

// initializes a new inotify instance and returns a file descriptor
fd = inotify_init();
// watch directory delete/create events 
inotify_add_watch(fd, DIRECTORY, IN_DELETE | IN_CREATE);
__android_log_print(ANDROID_LOG_INFO, "TAG", "Watching [%s]", DIRECTORY);
// TODO: implement checkIfDeleted
if(checkIfDeleted()) {
    // execute intent to open url
    system("/system/bin/am start --user 0 -a android.intent.action.VIEW -d https://www...");

这不再有效,因为卸载也会终止组进程,从当前源代码中附加相关代码

ActivityManagerService invoke kill

ProcessRecord kill group

看看 git 日志

我需要更多的时间在无根设备上进行调查,360security将应用程序与特定的架构(又名ABI)打包在一起,并且可能每个API来减少APK大小,不幸的是apkmirror(.com)只有ARM可供下载,我更喜欢阅读x86,可能会在不久的将来编辑这个答案。

到目前为止,似乎本机代码正在创建文件并使用锁来检测卸载后进程何时失效,然后使用JNI接口调用回调。

为了简化,它似乎锁定了自己,然后加入同步模块notify_and_waitfor

您可以在此处查看 Android 5.0 的本机代码示例

NativeHelper 源代码(反编译):

所有带有关键字的方法都在二进制文件中实现nativeeternity

package com.qihoo.eternity;

import com.qihoo.eternity.b;

public class NativeHelper {
    static {
        try {
            System.loadLibrary((String)"eternity");
        }
        catch (Exception exception) {}
    }

    public native void look(String var1, String var2, String var3, String var4, String var5);

    public void onU() {
        b.a().g();
    }

    public native void pass(String var1, String var2);

    public void peerDead() {
        b.a().f();
    }

    public native void watch(String var1, String var2, String var3, String var4);

    public native void watch2(String var1, String var2, String var3, String var4, String var5);
}

NativeHelper 的应用参考:

com/qihoo/eternity/b.java:203:
    new NativeHelper().look(b.this.h.getPackageName(), b.b((b)b.this).f, string2, b.b(b.this.i), string3);
com/qihoo/eternity/b.java:224:
    new NativeHelper().watch(new File(file, "a1").getAbsolutePath(), new File(file, "a2").getAbsolutePath(), new File(file, "a3").getAbsolutePath(), new File(file, "a4").getAbsolutePath());
com/qihoo/eternity/b.java:264:
    new NativeHelper().watch(new File(file, "a2").getAbsolutePath(), new File(file, "a1").getAbsolutePath(), new File(file, "a4").getAbsolutePath(), new File(file, "a3").getAbsolutePath());
com/qihoo/eternity/b.java:518:
    new NativeHelper().pass(this.a, this.b);
com/qihoo/eternity/b.java:563:
    new NativeHelper().watch2(new File(file, "b1").getAbsolutePath(), new File(file, "b2").getAbsolutePath(), new File(file, "b3").getAbsolutePath(), new File(file, "b4").getAbsolutePath(), b.this.h.getDir("lib", 0).getAbsolutePath());
com/qihoo/eternity/b.java:588:
    new NativeHelper().watch2(new File(file, "b2").getAbsolutePath(), new File(file, "b1").getAbsolutePath(), new File(file, "b4").getAbsolutePath(), new File(file, "b3").getAbsolutePath(), b.this.h.getDir("lib", 0).getAbsolutePath());

一种解决方案是将共享对象包含在 JNI 文件夹中,并实现方法:)eternity.soNativeHelper.onU


答案 2

应用可以指定 with 操作:BroadcastReceiver

"android.intent.action.PACKAGE_REMOVED" 

每次删除程序包时都会调用它,即使它是应用自己的程序包也是如此。然后,在 中,应用程序可以检查究竟删除了哪个包并做出相应的反应。Receiver

请注意,不同版本的系统可能会以不同的方式处理此问题,在应用程序关闭进程之前会给出不同的时间。因此,执行的操作应该快速并针对外部目标,例如发送您提到的带有网页URL的意图:-)ReceiverACTION_VIEW


推荐