本文章由Jack_Jia编写,转载请注明出处。
文章链接: http://blog.csdn.net/jiazhijun/article/details/10157901

作者:Jack_Jia 邮箱:309zhijun@163.com


一般开发者都有这样的业务需求:统计自己应用的卸载量或在用户卸载应用后提供反馈信息以便更好的改进软件。

应用开发者可以通过注册“android.intent.action.PACKAGE_REMOVED”广播获取卸载其它应用的信息,但该广播不能用于应用本身被卸载。如何获取自己被卸载的信息呢?

目前有两种方式可以做到应用卸载提示:

第一种通过监控Android日志实现:

启动一个服务监控android系统的打印日志,当监控到"android.intent.action.DELETE"并且包含自己应用的包名时,提示给用户。代码摘至 (http://blog.csdn.net/xyz_lmn/article/details/8330710)

缺点:耗电问题,且程序必须在启动的情况下才可以监控。

public class AndroidLogcatScannerThread extends Thread {    private LogcatObserver observer;    public AndroidLogcatScannerThread(LogcatObserver observer) {            this.observer = observer;    }    public void run() {            String[] cmds = { "logcat", "-c" };            String shellCmd = "logcat";            Process process = null;            InputStream is = null;            DataInputStream dis = null;            String line = "";            Runtime runtime = Runtime.getRuntime();            try {                    observer.handleLog(line);                    int waitValue;                    waitValue = runtime.exec(cmds).waitFor();                    observer.handleLog("waitValue=" + waitValue + "\n Has do Clear logcat cache.");                    process = runtime.exec(shellCmd);                    is = process.getInputStream();                    dis = new DataInputStream(is);                    while ((line = dis.readLine()) != null) {                    //Log.d("Log","Log.Bestpay:"+line);                                        if(observer!=null)                            observer.handleLog(line);                                                  }            } catch (InterruptedException e) {                    e.printStackTrace();            } catch (IOException ie) {                    ie.printStackTrace();            } finally {                    try {                            if (dis != null) {                                    dis.close();                            }                            if (is != null) {                                    is.close();                            }                            if (process != null) {                                    process.destroy();                            }                    } catch (Exception e) {                            e.printStackTrace();                    }            }    }}

监控服务:

public class AndroidLogcatScannerService extends Service implements LogcatObserver{@Overridepublic void onCreate() {// TODO Auto-generated method stubsuper.onCreate();}@Overridepublic void onDestroy() {// TODO Auto-generated method stubsuper.onDestroy();}@Overridepublic void onStart(Intent intent, int startId) {// TODO Auto-generated method stubsuper.onStart(intent, startId);AndroidLogcatScannerThread scannerThread=new AndroidLogcatScannerThread(AndroidLogcatScannerService.this);scannerThread.start();}@Overridepublic IBinder onBind(Intent intent) {// TODO Auto-generated method stubreturn null;}@Overridepublic void handleLog(String info) {// TODO Auto-generated method stubif (info.contains("android.intent.action.DELETE") && info.contains(getPackageName())) {            Intent intent = new Intent();            intent.setClass(AndroidLogcatScannerService.this, UninstallActivity.class);            intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);            startActivity(intent);        }}}

第二种通过Fork子进程,然后在子进程中通过监控/data/data/{package_name}目录变化实现应用卸载提示,当私有目录被删除时,本应用即被卸载。”豌豆荚“即时使用该中方式。下面我们通过逆向分析“豌豆荚”来看看该功能具体实现。

豌豆荚被卸载后,总是调用浏览器打开如下页面:

在逆向过程中发现,即使在设置->应用程序中强制停止豌豆荚相关应用,当卸载豌豆荚是仍然可以调起浏览器访问反馈页面。豌豆荚是如何做到的呢?

豌豆荚启动后,主要涉及以下三个进程:

当在设置->应用程序中强制关闭豌豆荚相关应用后,我们观察进程变化:

发现在设置->应用程序中强制关闭并不能关闭uuid_sys进程,那么卸载反馈逻辑肯定就在uuid_sys进程中完成了!

在豌豆荚APK安装包存在lib\armeabi\libuuid.so文件,该文件并不是共享库文件而是一个可执行文件。

使用IDA逆向libuuid.so文件,实现关键代码如下:


1、使用linux inotify_init、inotify_add_watch监控文件系统目录/data/data/com.wandoujia.phoenix2的变化。


2、当监控目录被删除时说明程序被卸载,通过am命令启动浏览器打开指定网页。

更多相关文章

  1. 一款霸榜 GitHub 的开源 Linux 资源监视器!
  2. 一些资料,binder,content provider
  3. Android(安卓)studio 3.4.1NDK开发
  4. android之init进程-uevent
  5. Android之unable to execute dex java heap space解决方案
  6. 在Android4.0 SDK的tools目录中运行模拟器emulator的环境变量的
  7. android如何打印当前的线程及进程
  8. Android(安卓)framework系统默认设置修改
  9. android 2.2 apidemos 赏析笔记

随机推荐

  1. 查询表中某字段有重复记录个数的方法
  2. 分享:在存储过程中使用另一个存储过程返回
  3. asp.net连接查询SQL数据库并把结果显示在
  4. sql server多行数据拼接的实例方法
  5. SQL Server 游标语句 声明/打开/循环实例
  6. SQL Server 2012 安装图解教程(附sql2012
  7. SQL Server控制语句的基本应用
  8. SQL Server的基本功能性语句介绍
  9. 关于SQL Server查询语句的使用
  10. mssql server 2012(SQL2012)各版本功能对