杂谈Android:不可实现的Android静默安装

杂谈Android:不可实现的Android静默安装_第1张图片
乔欣

静默安装,就是apk在后台悄悄地安装。很多流氓软件喜欢干。但从现在的情况看,只有root了的手机,或者你能搞到手机厂商的签名,才能静默安装。
关于静默安装,基本上有两种情况。
1.root情况下静默安装
2.非root下面静默安装

root情况静默安装##

1.调用pm指令,下面就是调用pm指令(pm install -r)把/sdcard/haha.apk安装掉。

    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
       runShellCommand("pm install -r  /sdcard/haha.apk"); //执行命令
    }


    private void runShellCommand(String command) {
        Process process = null;
        BufferedReader bufferedReader = null;
        StringBuilder mShellCommandSB =new StringBuilder();
        Log.d("wenfeng", "runShellCommand :" + command);
        mShellCommandSB.delete(0, mShellCommandSB.length());
        String[] cmd = new String[] { "/system/bin/sh", "-c", command }; //调用bin文件
        try {
            byte b[] = new byte[1024];
            process = Runtime.getRuntime().exec(cmd);
            bufferedReader = new BufferedReader(new InputStreamReader(
                    process.getInputStream()));
            String line;

            while ((line = bufferedReader.readLine()) != null) {
                mShellCommandSB.append(line);
            }
            Log.d("wenfeng", "runShellCommand result : " + mShellCommandSB.toString());
            process.waitFor();
        } catch (IOException e) {
            e.printStackTrace();
        } catch (InterruptedException e) {
            e.printStackTrace();
        } finally {
            if (bufferedReader != null) {
                try {
                    bufferedReader.close();
                } catch (IOException e) {
                    // TODO: handle exception
                }
            }

            if (process != null) {
                process.destroy();
            }
        }
    }

2.调用cp指令,把apk拷贝到data/app目录下,把上面的runShellCommand("pm install -r /sdcard/haha.apk")替换成下面这句。然后用户下次重启时,apk就会自动安装。

runShellCommand("cp /sdcard/haha.apk /data/app")

非root下面静默安装##

1.调用辅助功能,跟抢红包原理差不多。其实这种方式并不算严格的静默安装,因为用户可以看到安装的界面。很多应用商店都用到这种方式批量安装apk,下载后自动弹出安装界面,然后自动帮你点击安装。就能抢红包一样,自动打开红包页面,自动点击红包的道理一样一样的。
这个辅助功能最开始google设计是用于残疾人的,让他们更加方便的使用手机。一个应用要获取辅助功能,要在设置里面授权。

杂谈Android:不可实现的Android静默安装_第2张图片
Paste_Image.png

2.反射调用PackageManager
这个在百度搜索,大多数是出现这篇文章
Android 无需root实现apk的静默安装
关于这种方式,想法很好。
但是其实是不可行的。
而且文章的实现过于复杂了,其实不需要这么复杂,拉出一大坨类。如果你有Android系统源码的话,在源码环境编译只需要在Android.mk增加一句就可以了,把framework.jar包含进去编译,自然就可以找到那一大坨类。

LOCAL_JAVA_LIBRARIES := \
    framework \

然后就可以直接在代码里面引用IPackageManager那些类了。

         public static void install()  
    {  
        String path = "sdcard";  
        String fileName = path + "/haha.apk";  
        File file = new File(fileName);  
          
        try {  
   
            Class clazz = Class.forName("android.os.ServiceManager");  
            Method method = clazz.getMethod("getService", String.class);  
            IBinder iBinder = (IBinder) method.invoke(null, "package");  
            IPackageManager ipm = IPackageManager.Stub.asInterface(iBinder);  
            @SuppressWarnings("deprecation")  
            VerificationParams verificationParams = new VerificationParams(null, null, null, VerificationParams.NO_UID, null);  
            ipm.installPackageAsUser(fileName, null, 2, null, verificationParams, "armeabi-v7a",0);  
        } catch (Exception e) {  
            // TODO Auto-generated catch block  
            e.printStackTrace();  
        }  
  
    }  

上面我说这种方式是不可行的,原因是:
1.installPackageAsUser会远程调用PackageManagerService进行安装,但安装前需要校验权限,只有System权限以上才能通过校验。所以为了编译System权限的app,需要在AndroidManifest增加一句 android:sharedUserId="android.uid.system"


2.但你以为你这个System权限的app可以安装到现实手机中吗?不可能的,系统在安装AndroidManifest包含android:sharedUserId="android.uid.system"的app时,都会首先看下app的签名。app签名不对直接就安装失败的。

杂谈Android:不可实现的Android静默安装_第3张图片
安装失败.png

所以,那篇文章的app根本不可能安装到手机中去。除非,你能搞到手机厂家的签名!!!!签名这个可是重大机密,泄露可是要出人命的。

你可能感兴趣的:(杂谈Android:不可实现的Android静默安装)