android黑科技系列——实现静态的默认安装和卸载应用

一、访问隐藏的API方式进行静态的默认安装和卸载

1.系统安装程序

android自带了一个安装程序—/system/app/PackageInstaller.apk.大多数情况下,我们手机上安装应用都是通过这个apk来安装

的。代码使用也非常简单:

/* 安装apk */
public static void installApk(Context context, String fileName) {
    Intent intent = new Intent();
    intent.setAction(Intent.ACTION_VIEW);
    intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
    intent.setDataAndType(Uri.parse("file://" + fileName),"application/vnd.android.package-archive");
    context.startActivity(intent);
}

/* 卸载apk */
public static void uninstallApk(Context context, String packageName) {
    Uri uri = Uri.parse("package:" + packageName);
    Intent intent = new Intent(Intent.ACTION_DELETE, uri);
    context.startActivity(intent);
}

通过发一个Intent,把应用所在的路径封装整uri.之后默认启动了PackageInstaller.apk来安装程序了。

但是此种情况下,仅仅是个demo而已,很难达到开发者的需求。如:

1).界面不好

2).被用户知晓

3).什么时候安装完了,卸载完了呢?

当然这里关于第三点的话,为了达到自己的需求,相信很多人都会接着来监听系统安装卸载的广播,继续接下来的代码逻辑。

监听系统发出的安装广播

在安装和卸载完后,android系统会发一个广播

android.intent.action.PACKAGE_ADDED(安装)

android.intent.action.PACKAGE_REMOVED(卸载)

咱们就监听这广播,来做响应的逻辑处理。实现代码:

public class MonitorSysReceiver extends BroadcastReceiver{

    @Override
    public void onReceive(Context context, Intent intent){
        //接收安装广播
        if (intent.getAction().equals("android.intent.action.PACKAGE_ADDED")) {
            //TODO
        }
        //接收卸载广播
        if (intent.getAction().equals("android.intent.action.PACKAGE_REMOVED")) {
            //TODO
        }
    }
}

AndroidManifest.xml文件中的配置:

 <receiver android:name=".MonitorSysReceiver">
            <intent-filter>
             <action android:name="android.intent.action.PACKAGE_ADDED" />
             <action android:name="android.intent.action.PACKAGE_REMOVED" />
            </intent-filter>
  </receiver>

到此,确实安装卸载的整体流程都知道了,但是这个效果肯定是无法达到项目的需求。

一般这种应用商店类(豌豆荚)的项目,肯定是会要自定义提示框效果的安装卸载功能,而不是调用系统的安装程序。

那咱就要想法子实现静默安装、卸载咯。

下面这种调用系统隐藏api接口来实现静默安装卸载,是比较大众靠谱的,实现自定义的提示界面

2.系统隐藏的api

隐藏api,顾名思义,普通情况下肯定是调用不到的。翻翻源码\frameworks\base\core\java\android\content\pm目录下

PackageManager.java,应该发现在注释行里有加上@hide声明。调用的安装下载接口如下:

安装接口:

public abstract void installPackage(Uri packageURI,IPackageInstallObserver observer, int flags,String installerPackageName);

卸载接口:

public abstract void deletePackage(String packageName,IPackageDeleteObserver observer, int flags);

并且都是抽象方法,需要咱们实现。

看参数里IPackageInstallObserver  observer一个aidl回调通知接口,当前目录中找到这接口:

package android.content.pm;

/**
 * API for installation callbacks from the Package Manager.
 * @hide
 */
oneway interface IPackageInstallObserver {
    void packageInstalled(in String packageName, int returnCode);
}

好吧,这里有现成的干货,咱拿过来直接用呗(当然如果没有源码的那就算了,那能实现的只是demo)。具体步骤:

从源码中拷贝要使用的aidl回调接口:IPackageInstallObserver.aidl、IPackageDeleteObserver.aidl当然完全可以拷贝整个pm目

录,这样就不会报错了。

作者项目里面用到了pm,所以把PackageManager.java以及涉及到的一些文件也拷贝过来了,不然eclipse报找不到PackageManager

对象。结构如下:

注:此处的包名android.content.pm一定要和源码目录结构一致,不然源码里编译会提示找不到aidl接口。一切朝源码编译看齐

此处有2种方式实现:

1.直接只取IPackageDeleteObserver.aidl和IPackagerInstallObserver.aidl、IPackageMoveObserver.aidl等要使用的接口,然后通过

bindService来和系统连接服务,然后直接调用接口即可(这种没有方式作者没试过,不过原理上来说应该是可行的,除非系统没有

这个Service实现这个接口。有需求的可以深究下)

2.作者此处的方法是直接拷贝了源码PackageManager.java等文件过来,不过靠过来之后eclipse会提示一些接口错误,但这里作者把

上面那几个.java文件都放空了,因为用不到,只是为了编译过才拷贝了那么多文件。最简单的就是直接拷贝4个文件即可:

PackageManager.java
IPackageDeleteObserver.aidl
IPackagerInstallObserver.aidl
IPackageMoveObserver.aidl

然后把PackageManager.java中报的异常的接口都注释掉即可

实现回调接口,代码如下:

安装的回调接口:

/*静默安装回调*/
class MyPakcageInstallObserver extends IPackageInstallObserver.Stub{

    @Override
    public void packageInstalled(String packageName, int returnCode) {
        if (returnCode == 1) {
            Log.e("DEMO","安装成功");
            new ToastThread(InstallActivity.this,"安装成功").start();
        }else{
            Log.e("DEMO","安装失败,返回码是:"+returnCode);
            new ToastThread(InstallActivity.this,"安装失败,返回码是:"+returnCode).start();
        }
    }
}

安装的方法:

String fileName = Environment.getExternalStorageDirectory() + File.separator + "baidu"+File.separator +"UC.apk";
Uri uri = Uri.fromFile(new File(fileName));
int installFlags = 0;
PackageManager pm = getPackageManager();
try {
PackageInfo pi = pm.getPackageInfo("com.UCMobile",PackageManager.GET_UNINSTALLED_PACKAGES);
if(pi != null) {
installFlags |= PackageManager.INSTALL_REPLACE_EXISTING;
}
} catch (NameNotFoundException e) {
}
MyPakcageInstallObserver observer = new MyPakcageInstallObserver();
pm.installPackage(uri, observer, installFlags, "com.UCMobile");

从代码中可以看到我们想安装的是从SD卡中的baidu文件夹中的UC.apk

(所以在测试程序的时候需要将UC.apk拷贝到SD卡中的baidu文件夹中,或者你可以自定义一个文件的存放目录)

卸载原理是一样的

卸载的回调接口:

/* 静默卸载回调 */
class MyPackageDeleteObserver extends IPackageDeleteObserver.Stub {

    @Override
    public void packageDeleted(String packageName, int returnCode) {
        if (returnCode == 1) {
            Log.e("DEMO","卸载成功...");
            new ToastThread(InstallActivity.this,"卸载成功...").start();
        }else{
            Log.e("DEMO","卸载失败...返回码:"+returnCode);
            new ToastThread(InstallActivity.this,"卸载失败...返回码:"+returnCode).start();
        }
    }
}

卸载的功能:

PackageManager pm = InstallActivity.this.getPackageManager();
IPackageDeleteObserver observer = new MyPackageDeleteObserver();
pm.deletePackage("com.UCMobile", observer, 0);

这里我们一定要传一个包名。

自此,静默安装卸载代码实现。最后在AndroidManifast.xml中要注册权限和添加为系统用户组

<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.autoinstallpackage.demo"
    android:versionCode="1"
    android:versionName="1.0.19"
    android:sharedUserId="android.uid.system">

    <uses-sdk android:minSdkVersion="4"/>

    <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
    <uses-permission android:name="android.permission.INTERNET" />
    <uses-permission android:name="android.permission.INSTALL_PACKAGES" />
    <uses-permission android:name="android.permission.DELETE_PACKAGES" />
    <uses-permission android:name="android.permission.MOUNT_UNMOUNT_FILESYSTEMS"/>
    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
    <uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED"/>
    ...

</manifest>

这里要注意的地方有两个:第一个必须要添加:

android:sharedUserId="android.uid.system"

这个是将其应用注册成系统用户组中,如果不加这行代码的话,会出现报错,但是加了这行代码之后,如果还报错的话,重新clean一下项目就好了,这个是Eclipse的一个bug吧

还要添加安装和卸载的权限:

<uses-permission android:name="android.permission.INSTALL_PACKAGES" />
<uses-permission android:name="android.permission.DELETE_PACKAGES" />

这时候上面的工作都做完之后,那么我们就来用Eclipse运行一下吧:

好吧,貌似不是那么的顺利,出现一个安装错误,其实这个信息去百度一下之后会找到很多的相关资料,因为这个问题有很多人遇

到过,所以解决的方法也是很多的,就是需要将我们的应用签名成系统级的即可,那么我们该怎么办呢?

网上普遍的两种方法:

第一种是:得到platform.pem,platform.x509.pem,signapk.jar这三个文件进行签名:签名的命令很简单:

java -jar signapk.jar platform.x509.pem platform.pem  需要签名的apk   签名之后的apk

下图是我签名的操作:

第二种方法:很麻烦的,为什么说麻烦呢?因为需要下载源代码,然后将我们的应用拷贝到指定的目录即可:
1.如果你有系统源码,最简单的就是将eclipse里面的应用拷贝到系统里面,然后编译系统,会生
成out/target/product/generic/system/app/abc.apk,这个应用就是经过系统签名了。具体方法如下:

将应用文件夹复制到源码目录:packages/experimental/project_name/里面,并且只保留src、res、libs、androidmanifest.xml这三个文件,里面新建一个Android.mk文件,内容如下:

LOCAL_PATH:= $(call my-dir)

include $(CLEAR_VARS)

LOCAL_MODULE_TAGS := optional

LOCAL_SRC_FILES := $(call all-subdir-java-files)

LOCAL_PACKAGE_NAME := abc

LOCAL_CERTIFICATE := platform

include $(BUILD_PACKAGE)

然后进行编译即可

其实我们在将第一种方法的时候有一个问题就是那三个签名的文件到哪里能搞到,这个吗?可以到网上去搜索的,但是本人在下载
下来然后进行签名,结果总是失败,于是,我就放弃了从网上去下载,那么还有什么方法可以得到呢?好吧,还得去下载Android源
码,编译之后可以在指定的目录中找到这三个文件

但是还没有完,不管是第一种方法还是第二种方法,我在试验的过程中还是失败,原因是什么呢?因为我们如果用这三个文件进行
签名或者把工程放到源码中进行编译的话,都必须要注意一点:就是签名的文件的系统版本必须和安装到设备的系统的版本一样,
说白一点:现在假如签名的那三个文件是从下载的编译之后的源码中得到的,那么这三个文件的版本就是这个Android源码的版本:
比如是4.4版本的,那么我们用这三个文件进行签名之后的apk包只能安装到系统版本为4.4的机子上,同理如果我们将工程直接放到
Android源码中进行编译的话,假如Android源码的系统版本是4.4,那么编译之后的apk也只能安装到系统版本为4.4的机子上。

所以我们从网上下载到的签名的三个文件进行签名之后总是失败,所以这种方式总是不靠谱的,因为我们从网上下载的签名文件肯
定不知道他的版本号,但是我们可以将签名之后的包安装到每个版本的系统中进行尝试,所以最靠谱的方式还是我们下载源码然后

得到这三个签名的文件即可,因为我们自己下载的源码肯定知道版本的。

这三个文件对应的目录是:

signapk.jar: 源码目录/out/host/linux-x86/framework/signapk.jar

platform.pk8和platform.x509.pem:  源码目录/build/target/product/security/platform.pk8&platform.x509.pem

当我们使用第一种方法的时候,我们需要用Eclipse中导出一个未签名的包,这个很简单了,这里就不介绍了~~

运行的结果:

因为手头上没有4.4系统的机子,又不想刷机,所以就用模拟器了。在这个过程中安装和卸载可能要一段时间,所以要等待一会,不要着急~~

那么我们就介绍了使用隐藏的api来进行默认的安装和卸载app,

Demo工程下载地址:

http://download.csdn.net/detail/jiangwei0910410003/7584423

导入工程之后,需要做的几步:

在SD卡中拷贝一个UC.apk到baidu文件夹(需要新建的)

导出未进行签名的包

下载签名的工具:

http://download.csdn.net/detail/jiangwei0910410003/7584441

按照上面的签名步骤进行操作

然后找到一个系统是4.4版本的测试机或者模拟器进行安装包(因为我的签名文件的版本是4.4)

二、通过命令进行静态的默认安装和卸载

1、需要签名文件,不需要root权限

下面我们再来看一下如何使用命令的方式来实现默认的安装和卸载app,我们知道可以使用命令:

adb install  apk文件

adb uninstall  包名

进行安装和卸载操作。

我们在代码中可以使用Runtime类进行操作:

Runtime.getRuntime().exec("adb uninstall com.UCMobile");

或者ProcessBuilder:

new ProcessBuilder().command("adb","uninstall","com.UCMobile").start();

看到这两个类的区别在于,第一种是将命令一起写完,第二种是将命令用空格分隔,然后将其当做参数进行传递的,其实command

方法的参数是一个String可变参数类型的

但是我们执行上面的代码发现总是执行失败,结果才发现,这些命令执行的目录不是在shell层的,但是手机中执行的命令必须

要在shell层中的,所以会有问题的,但是我们可以使用pm命令,比如我们使用PC端的命令行进行安装文件:

>adb shell

>pm install  apk文件

其实上面的两行命令和

>adb install  apk文件

的效果一样

但是如果想在手机上执行安装文件只能执行命令:pm install  apk文件

(可以把pm命令的作用想成是脱离shell层来执行命令的)

不多说了,下面就来看一下代码吧:

/*
* m命令可以通过adb在shell中执行,同样,我们可以通过代码来执行
*/
public static String execCommand(String ...command)  {
    Process process=null;
    InputStream errIs=null;
    InputStream inIs=null;
    String result="";  

    try {
        process=new ProcessBuilder().command(command).start();
        ByteArrayOutputStream baos = new ByteArrayOutputStream();
        int read = -1;
        errIs=process.getErrorStream();
        while((read=errIs.read())!=-1){
            baos.write(read);
        }
        inIs=process.getInputStream();
        while((read=inIs.read())!=-1){
            baos.write(read);
        }
        result=new String(baos.toByteArray());
        if(inIs!=null)
            inIs.close();
        if(errIs!=null)
            errIs.close();
        process.destroy();
    } catch (IOException e) {
        result = e.getMessage();
    }
    return result;
}

调用这个方法:

protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        final String path = Environment.getExternalStorageDirectory() + File.separator + "baidu"+File.separator + "360MobileSafe.apk";

        Button btn1 = (Button) findViewById(R.id.btn1);
        btn1.setOnClickListener(new OnClickListener(){
            @Override
            public void onClick(View v) {
                //安装apk,filePath为apk文件路径,如/mnt/sdcard/ApiDemos.apk
                String result = execCommand("pm","install","-f",path);
                Toast.makeText(MainActivity.this, "安装结果:"+result, Toast.LENGTH_LONG).show();
            }});

        Button btn2 = (Button) findViewById(R.id.btn2);
        btn2.setOnClickListener(new OnClickListener(){
            @Override
            public void onClick(View v) {
                //卸载apk,packageName为包名,如com.example.android.apis
                String result = execCommand("pm","uninstall", "com.qihoo360.mobilesafe");
                Toast.makeText(MainActivity.this, "卸载结果:"+result, Toast.LENGTH_LONG).show();
            }});

    }

在AndroidManifest.xml中的配置:

<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.xieyuan.mhfilemanager"
    android:versionCode="1"
    android:versionName="1.0"
    android:installLocation="internalOnly"
    android:sharedUserId="android.uid.system" >

也有:

android:sharedUserId="android.uid.system"

这个在前面已经说过了,所以我们现在做的还是将其进行系统签名,具体方法就不多说了,同上

下面是运行的结果图:

Demo工程下载地址:http://download.csdn.net/detail/jiangwei0910410003/7584429

下载之后的工程导入之后需要进行的几步操作和前面的是一模一样的,这里就不做解释了~~

但是我们从上面的方法看到有一个弊端,还是需要系统签名,这个对于一般app来说是个限制,现在机型很多,系统的签名文件也都不一样,所以很难做到这种方式能够适配到所有的机型。

那么还有另外的一种方法:

2、不需要签名文件,但是需要root权限

这种方式很简单和上面的没有太大的区别,就是将上面的命令放到su下面去执行就可以了。

从这里我们可以看到,现在很多需要系统签名的或者是命令不能执行的,都会想到su环境中去执行以下。

这里不多解释了,直接上代码:

public static boolean RootCommand(String command){
        Process process = null;
        DataOutputStream os = null;
        try{
            process = Runtime.getRuntime().exec("su");
            os = new DataOutputStream(process.getOutputStream());
            os.writeBytes(command + "\n");
            os.writeBytes("exit\n");
            os.flush();
            process.waitFor();
        } catch (Exception e){
            Log.d("*** DEBUG ***", "ROOT REE" + e.getMessage());
            return false;
        } finally{
            try{
                if (os != null){
                    os.close();
                }
                process.destroy();
            } catch (Exception e){
            }
        }
        Log.d("*** DEBUG ***", "Root SUC ");
        return true;
    }

然后我们调用这个方法来执行命令即可:

new Thread(){
	@Override
	public void run(){
		RootCommand("pm uninstall com.tencent.mm");
	}
}.start();

这里就可以执行了,这种方式可以适配所有的机型,但是需要root权限,这个就比较麻烦了,但是现在很多安全应用大部分都是采用这种方式的

三、拷贝/删除apk文件实现安装和卸载

这个方式其实很简单,就是直接拷贝和删除文件即可。我们知道Android中安装的apk都是放在/data/app/目录下面的,所以我们可以将我们需要安装的apk放到这个目录下即可。

注:这种方式是可以接收到安装和卸载的系统广播

首先我们在设备的SD卡中存放一个待安装的apk:360MobileSafe.apk

这里的目录可以随便选择的,我这里选择了SD卡的根目录

这里为了看到明显的效果,我们在写一个Demo程序,来接收安装的广播

后台监听广播的Service:

package com.example.installpackage;

import android.app.Service;
import android.content.Intent;
import android.content.IntentFilter;
import android.os.IBinder;

public final class MyService extends Service {

    @Override
    public void onCreate() {
        super.onCreate();
        IntentFilter filter = new IntentFilter(Intent.ACTION_PACKAGE_ADDED);
        filter.addAction(Intent.ACTION_PACKAGE_REMOVED);
        filter.addAction(Intent.ACTION_PACKAGE_CHANGED);
        filter.addDataScheme("package");
        filter.setPriority(Integer.MAX_VALUE);
        registerReceiver(new InstallReceiver(), filter);
    }

    @Override
    public IBinder onBind(Intent paramIntent) {
        return null;
    }

}

用动态方式进行注册

广播广播接收器:

package com.example.installpackage;

import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.util.Log;

public final class InstallReceiver extends BroadcastReceiver {

    @Override
    public void onReceive(final Context context, Intent intent) {
        Log.i("TTT","action:"+intent.getAction());
    }
}

开启服务:

package com.example.installpackage;

import android.os.Bundle;
import android.app.Activity;
import android.content.Intent;

public class MainActivity extends Activity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        Intent i = new Intent(this, MyService.class);
        startService(i);
    }

}

还要记得在AndroidManifest.xml中进行注册服务:

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.example.installpackage"
    android:versionCode="1"
    android:versionName="1.0" >

    <uses-sdk
        android:minSdkVersion="8"
        android:targetSdkVersion="18" />

    <application
        android:allowBackup="true"
        android:icon="@drawable/ic_launcher"
        android:label="@string/app_name"
        android:theme="@style/AppTheme" >
        <activity
            android:name="com.example.installpackage.MainActivity"
            android:label="@string/app_name" >
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />
                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>

        <service android:name=".MyService"></service>

    </application>

</manifest>

我们在PC端可以使用adb push XXX.apk /data/app/  实现拷贝,但是在设备上这个命令不能执行。因为Android是底层是Linux系统,所以自带的有拷贝命令:

1、安装操作

1)、拷贝命令cp

=>adb shell

=>su

=>cd /sdcard/

=>cp 360MobileSafe.apk /data/app

如图效果:

在这个过程中,我们通过打印log信息可以看到,是有点耗时的。

当然除了这种方式还有另外的一种方式:

2)、使用cat命令实现

我们知道cat命令有输出重定向的功能

=>adb shell

=>su

=>cd /sdcard/

=>cat 360MobileSafe.apk > /data/app/com.qihoo.360.apk

运行结果:

2、卸载操作

卸载也很简单,我需要删除/data/app目录下指定的apk文件,但是我们知道,一个app安装好之后,不仅在这个目录中有数据,还有其他目录中也是有数据的:

/data/davlik-cache/   :存放释放的dex文件

/data/data/com.qihoo.360.mobilesafe/  :存放app的数据

/data/system/packages.list  :这个文件是记录安装app的信息的

/data/system/packages.xml  :这个文件是记录安装app的详细信息(权限,uid等)

命令:

=>adb shell

=>su

=>cd /data/app/

=>rm 360MobileSafe.apk

运行结果:

总结

上面就介绍了实现静态安装和卸载的功能,前面两种方法不需要root权限的,但是需要签名文件,这个对于不同机型,有不同的签名
文件,(在第二种方法中的两种实现不同的,不需要签名文件,但是需要root权限)这个是件很头疼的事,第三种是不需要签名文件的,对于所有机型都适合,但是需要root权限的,现在很多安全软件在实现静
默安装和卸载的时候也都是需要root权限才能进行操作的,而且每个机型上都是可以的。所以他们应该采用的是第二种方式中的第二种实现或者是第三种方式。

注:前两种方式是不可以接受系统的安装和卸载广播的,第三种是可以接受系统的安装和卸载广播的。

待解决的问题

1. 上面我们可以看到我们使用的是4.4版本进行签名的,只能安装到系统是4.4版本的机子上,这个有待考证,因为我们开发的应用不
可能只能装到指定的版本中,必须是所有的系统都能进行安装(比如豌豆荚就可以),所以我就做了一个假设,是不是低版本的签名文
件进行系统签名之后的apk可以安装到高版本系统中,那么这样就好办了,我们可以下载Android2.2(因为现在市面上最低的版本是

2.2了)源码,得到他的签名文件,或者从网上搜索到这个版本的签名文件(至今未找到,如果有找到的请分享,谢谢!!)

2. 还有一个问题就是上述的测试环境都是在手机或者模拟器都是root过了,有待考证的是没有root的手机会不会安装时出现问题~~

上述的blog是纠结了我几个月的时间才解决的,所以我真心想说的一句话就是:做事千万不要放弃,办法总比问题多,一定要坚持
~~,其实上面遇到的最大的问题就是在下载源码过程(没有技术可言,就是考验我们的耐心,同时网络也是一个重要的原因,这里由

于某些原因,我下载的是4.4版本的源码,共13G,这里就不公开下载地址了,如果真心需要请留言,我可以共享一下~~),还有就是

编译过程,我花费了一周的时间,因为在这个过程中可以说是千难万险,什么问题都有,我重新编译好几次~~

好吧,这里有现成的干货,咱拿过来直接用呗(当然如果没有源码的那就算了,那能实现的只是demo)。具体步骤:

从源码中拷贝要使用的aidl回调接口:IPackageInstallObserver.aidl、IPackageDeleteObserver.aidl当然完全可以拷贝整个pm目

因为手头上没有4.4系统的机子,又不想刷机,所以就用模拟器了。在这个过程中安装和卸载可能要一段时间,所以要等待一会,不要着急~~

那么我们就介绍了使用隐藏的api来进行默认的安装和卸载app,

Demo工程下载地址:

http://download.csdn.net/detail/jiangwei0910410003/7584423

导入工程之后,需要做的几步:

在SD卡中拷贝一个UC.apk到baidu文件夹(需要新建的)

导出未进行签名的包

下载签名的工具:

http://download.csdn.net/detail/jiangwei0910410003/7584441

按照上面的签名步骤进行操作

然后找到一个系统是4.4版本的测试机或者模拟器进行安装包(因为我的签名文件的版本是4.4)

转载请注明:尼古拉斯.赵四 » Android中实现静态的默认安装和卸载应用

时间: 2024-10-13 06:37:45

android黑科技系列——实现静态的默认安装和卸载应用的相关文章

Android中实现静态的默认安装和卸载应用

最近好长时间都没有写blog了,主要是因为最近工作上的事以及下载Android源码的事耽误的(下载源码这件事会在后续的blog中写道,这个真的很有意义呀~~),那么今天来写点什么呢?主要的灵感来自于早上看新闻看到一篇文章说有一款应用在后台中卸载用户 手机中的所有浏览器的app,不会被用户察觉,但是最后百度浏览器还是用反侦察技术找到这个邪恶的应用然后将其告上法庭了.那么我们就来看看怎么能够实现应用的静态安装和卸载呢?就是不让用户知道,下面就来一步一步的介绍一下实现步骤: 一.访问隐藏的API方式进

Andrdoid中实现静态的默认安装和卸载应用

最近好长时间都没有写blog了,主要是因为最近工作上的事以及下载Android源码的事耽误的(下载源码这件事会在后续的blog中写道,这个真的很有意义呀~~),那么今天来写点什么呢?主要的灵感来自于早上看新闻看到一篇文章说有一款应用在后台中卸载用户手机中的所有浏览器的app,不会被用户察觉,但是最后百度浏览器还是用反侦察技术找到这个邪恶的应用然后将其告上法庭了.那么我们就来看看怎么能够实现应用的静态安装和卸载呢?就是不让用户知道,下面就来一步一步的介绍一下实现步骤: 一.访问隐藏的API方式进行

android黑科技系列——自动注入代码工具icodetools

一.前言 在前面已经介绍完了 自动给apk中注入日志代码工具icodetools原理了,在那里我们曾经说过其实离真正的可使用价值有点距离,本篇就对这个工具进行一些优化,让其真正意义上开始能工作量产.当时在前面一篇文章中说到遗留的三个主要问题: 第一个问题:对每个类中都添加一个静态打印方法堆栈信息的方法,这样会导致有些应用的dex过大,方法数超了问题 第二个问题:在从输入一个apk到给每个类中的每个方法添加日志代码然后在签名输出最终的apk,这个过程其实很多步,但是我们之前都是手动的去进行操作,非

android黑科技系列——破解游戏之修改金币数

我们在玩游戏的时候总是会遇到一些东东需要进行购买的,但是我们可能又舍不得花钱,那么我们该怎么办呢?那就是用游戏外挂吧!我们这里说的是Android中的游戏,在网上搜索一下移动端游戏外挂,可能会找到一款叫做:八门神器.apk 其实这个软件我下载安装了,但是没有什么效果,不知道是不是我哪里设置的有问题,但是我们这个应用也是有很多限制的,他必须要让手机进行root(说实话,现在获取root是很方便的一件事,如果你想玩游戏,并且想得到更多的东西,手机root是必须的,但是这个可能也可能会失去很多). 我

android黑科技系列——爆破一款应用的签名验证问题

一.前言 在之前的文章中说过Android中的安全和破解是相辅相成的,为了防止被破解,很多应用做了一些防护策略,但是防护策略也是分等级,一般简单的策略就是混淆代码和签名校验,而对于签名校验很多应用都是会做的,一般现在就两种方式: 第一种:签名校验不通过直接退出程序,也就是你会发现回编译二次打包运行失败的现象 第二种:签名校验不通过不触发程序指定逻辑,导致没有错误信息,也进不了应用的现象 关于Android中应用防护策略的文章可以看这里:Android中应用的攻防之战 今天我们就来看一下签名校验的

android黑科技系列——微信定位聊天记录中照片的位置信息插件开发详解

一.前言 最近关于微信中,朋友之间发送原图就可能暴露你的位置信息,其实这个问题不在于微信,微信是为了更好的体验效果,才有发送原图功能,而对于拍照,发送普通图片微信后台都会过滤图片的exif信息,这样就不会携带位置信息了.我们本身用手机自带的相机拍摄照片默认都是会在图片中添加位置信息的.当然我们也可以手动的关闭这个功能.这一点个人觉得不能怪微信.因为更好的逆向学习,和用户体验,本文将开发一套更加好用的插件,就是选择图片直接利用微信自带的地图功能,定位图片位置.这个过程会很麻烦.但是本文会逐一详细介

android黑科技系列——静态分析技术来破解Apk

一.前言 从这篇文章开始我们开始我们的破解之路,之前的几篇文章中我们是如何讲解怎么加固我们的Apk,防止被别人破解,那么现在我们要开始破解我们的Apk,针对于之前的加密方式采用相对应的破解技术,Android中的破解其实大体上可以分为静态分析和动态分析,对于这两种方式又可以细分为Java层(smail和dex)和native层(so).所以我们今天主要来讲解如何通过静态分析来破解我们的apk,这篇文章我们会通过破解Java层和native层的例子来讲解. 二.准备工作 在开始今天的文章之前,我们

android黑科技系列——Xposed框架实现拦截系统方法详解

一.前言 关于Xposed框架相信大家应该不陌生了,他是Android中Hook技术的一个著名的框架,还有一个框架是CydiaSubstrate,但是这个框架是收费的,而且个人觉得不怎么好用,而Xposed框架是免费的而且还是开源的,网上也有很多文章介绍了Xposed框架的原理实现,不了解的同学可以自行查阅即可,本文主要介绍如何通过这个框架来进行系统方法的拦截功能,比如我们开发过程中,对于一些测试环境很难模拟,特别是测试同学有时候像随机改变设备的imei,mcc等信息用来模拟不同测试场景,这时候

android黑科技系列——获取加固后应用App的所有方法信息

一.前言 在逆向应用的时候,我们有时候希望能够快速定位到应用的关键方法,在之前我已经详细介绍了一个自己研发的代码动态注入工具icodetools,来进行动态注入日志信息到应用中,不了解的同学可以查看这里:icodetools动态注入代码解析,看完之后都会发现这个工具对于现在加固的应用是没有办法的,所以我们如何能够得到加固的应用的所有方法信息呢?再不用复杂的脱壳步骤也可以轻松的获取对应的方法信息.这个就是本文需要介绍的内容. 二.获取加固应用方法 在之前了解过加固应用原理的同学或者是弄过脱壳的同学