我们再PKMS汇总拦截adb 安装的应用,在分析PKMS的时候我们也知道,在installPackageAsUser有如下代码,代表是adb安装的。

if ((callingUid == Process.SHELL_UID) || (callingUid == Process.ROOT_UID)) {

installFlags |= PackageManager.INSTALL_FROM_ADB;

}

所以我们可以在startCopy函数中做手脚

final boolean startCopy() {

boolean res;

try {

if (DEBUG_INSTALL) Slog.i(TAG, "startCopy " + mUser + ": " + this);

if (++mRetries > MAX_RETRIES) {//超过4次

Slog.w(TAG, "Failed to invoke remote methods on default container service. Giving up");

mHandler.sendEmptyMessage(MCS_GIVE_UP);

handleServiceError();

return false;

} else {

handleStartCopy();

res = true;

}

} catch (RemoteException e) {

if (DEBUG_INSTALL) Slog.i(TAG, "Posting install MCS_RECONNECT");

mHandler.sendEmptyMessage(MCS_RECONNECT);

res = false;

}

//add

if (mApkPath == null) {

handleReturnCode();

return res;

}

//是adb 安装的

if ((((InstallParams)this).installFlags & PackageManager.INSTALL_FROM_ADB) != 0) {

mLock = new ReentrantLock();

mCondition = mLock.newCondition();

class AlertDialogThread extends Thread {

public Handler mHandler;

public void run() {

Looper.prepare();

showAlertDialog();

Looper.loop();

}

}

AlertDialogThread alertDialogThread = new AlertDialogThread();

alertDialogThread.start();

mLock.lock();

try {

mCondition.await();

} catch (InterruptedException e) {

}

mLock.unlock();

/*if (!mContinueToInstall) {

res = false;

}*/

}

handleReturnCode();

return res;

}

上面代码就是增加了一个显示的dialog,点击继续才会继续安装,这里我们有一个当点击取消或者5秒没有点击就不继续安装,这里返回值res不能为false。为什么呢?我们来看下调用startCopy的地方,当startCopy返回true才会把mPendingInstalls中的第一项删除,否则就会不断调用startCopy直到超过4次才会删除。所以我们上面不继续安装的话也不能返回一个false。

else if (mPendingInstalls.size() > 0) {

HandlerParams params = mPendingInstalls.get(0);

if (params != null) {

if (params.startCopy()) {

// We are done... look for more work or to

// go idle.

if (DEBUG_SD_INSTALL) Log.i(TAG,

"Checking for more work or unbind...");

// Delete pending install

if (mPendingInstalls.size() > 0) {

mPendingInstalls.remove(0);

}

if (mPendingInstalls.size() == 0) {

if (mBound) {

if (DEBUG_SD_INSTALL) Log.i(TAG,

"Posting delayed MCS_UNBIND");

removeMessages(MCS_UNBIND);

Message ubmsg = obtainMessage(MCS_UNBIND);

// Unbind after a little delay, to avoid

// continual thrashing.

sendMessageDelayed(ubmsg, 10000);

}

} else {

// There are more pending requests in queue.

// Just post MCS_BOUND message to trigger processing

// of next pending install.

if (DEBUG_SD_INSTALL) Log.i(TAG,

"Posting MCS_BOUND for next work");

mHandler.sendEmptyMessage(MCS_BOUND);

}

}

}

再看看在HandlerParams 中增加的代码,大部分是显示dialog相关。

private abstract class HandlerParams {

private static final int MAX_RETRIES = 4;

/**

* Number of times startCopy() has been attempted and had a non-fatal

* error.

*/

private int mRetries = 0;

/** User handle for the user requesting the information or installation. */

private final UserHandle mUser;

HandlerParams(UserHandle user) {

mUser = user;

mApkPath = null;//add

}

UserHandle getUser() {

return mUser;

}

private Builder mAlertDialogBuilder;

private AlertDialog mAlertDialog;

private CountDownTimer mCountDownTimer;

protected String mApkPath;

protected boolean mContinueToInstall = true;//注意这个很重要

private void cancelAlertDialog(Dialog dialog) {

mLock.lock();

if (mHandler.mPendingInstalls.size() != 0) {

InstallParams params = (InstallParams)mHandler.mPendingInstalls.get(0);

try {

if (params.observer != null) {

params.observer.onPackageInstalled("", INSTALL_FAILED_USER_CANCELLED, null, null);

}

} catch (RemoteException re) {

}

}

mHandler.mPendingInstalls.clear();

mHandler.disconnectService();

mContinueToInstall = false;//没有点击继续安装

mCondition.signal();

mLock.unlock();

dialog.dismiss();

}

private Drawable getApkIcon(Context context, String apkPath) {

PackageManager pm = context.getPackageManager();

PackageInfo info = pm.getPackageArchiveInfo(apkPath,

PackageManager.GET_ACTIVITIES);

if (info != null) {

ApplicationInfo appInfo = info.applicationInfo;

appInfo.sourceDir = apkPath;

appInfo.publicSourceDir = apkPath;

try {

return appInfo.loadIcon(pm);

} catch (OutOfMemoryError e) {

Log.e("getApkIcon", e.toString());

}

}

return null;

}

private CharSequence getAppLabel(Context context, String apkPath) {

PackageManager pm = context.getPackageManager();

PackageInfo info = pm.getPackageArchiveInfo(apkPath,

PackageManager.GET_ACTIVITIES);

if (info != null) {

ApplicationInfo appInfo = info.applicationInfo;

appInfo.sourceDir = apkPath;

appInfo.publicSourceDir = apkPath;

return appInfo.loadLabel(pm);

}

return null;

}

private void showAlertDialog() {

final Context settingsContext = new ContextThemeWrapper(mContext,

com.android.internal.R.style.Theme_DeviceDefault_Settings);

mAlertDialogBuilder = new AlertDialog.Builder(settingsContext);

mAlertDialogBuilder.setTitle(getAppLabel(mContext, mApkPath));

mAlertDialogBuilder.setMessage(R.string.install_hint);

mAlertDialogBuilder.setIcon(getApkIcon(mContext, mApkPath));

mAlertDialogBuilder.setNegativeButton(R.string.adb_install_cancel,

new DialogInterface.OnClickListener() {

public void onClick(DialogInterface dialog, int which) {

mCountDownTimer.cancel();

cancelAlertDialog(mAlertDialog);

}

});

mAlertDialogBuilder.setPositiveButton(R.string.adb_install_continue_to_install,

new DialogInterface.OnClickListener() {

public void onClick(DialogInterface dialog, int which) {

mCountDownTimer.cancel();

mLock.lock();

mContinueToInstall = true;//点击继续安装

mCondition.signal();

mLock.unlock();

mAlertDialog.dismiss();

}

});

mAlertDialog = mAlertDialogBuilder.create();

Window alertDialogWindow = mAlertDialog.getWindow();

alertDialogWindow.setType(WindowManager.LayoutParams.TYPE_KEYGUARD_DIALOG);// TYPE_SYSTEM_DIALOG

mAlertDialog.setCanceledOnTouchOutside(false);

mAlertDialog.show();

alertDialogWindow.setGravity(Gravity.BOTTOM);

final Button negativeButton = mAlertDialog.getButton(AlertDialog.BUTTON_NEGATIVE);

int intervalMs = 1000;

int timeLeftMs = 5000;

final String cancel = mContext.getString(R.string.adb_install_cancel);

mCountDownTimer = new CountDownTimer(timeLeftMs, intervalMs) {

public void onTick(long millisUntilFinished) {

negativeButton.setText(cancel + "(" + millisUntilFinished / 1000 + ")");

}

public void onFinish() {

cancelAlertDialog(mAlertDialog);

}

};

mCountDownTimer.start();

}

其中有一个mApkPath我们接下来看在哪赋值。

就是handleStartCopy函数最后在copyApk函数(就是在copy apk到data/app目录下新建的临时目录)之后,mApkPath就是其目录下的base.apk

ret = args.copyApk(mContainerService, true);

mApkPath = args.getCodePath() + "/base.apk";

我们再看下有了这个apkPath就可以调用PackageManager的getPackageArchiveInfo来获取PackageInfo,然后解析出ICon和Label等。

PackageInfo info = pm.getPackageArchiveInfo(apkPath,

PackageManager.GET_ACTIVITIES);

我们来看看这个函数,也是调用PackageParser来解析apk。

public PackageInfo getPackageArchiveInfo(String archiveFilePath, int flags) {

final PackageParser parser = new PackageParser();

final File apkFile = new File(archiveFilePath);

try {

PackageParser.Package pkg = parser.parseMonolithicPackage(apkFile, 0);

if ((flags & GET_SIGNATURES) != 0) {

parser.collectCertificates(pkg, 0);

parser.collectManifestDigest(pkg);

}

PackageUserState state = new PackageUserState();

return PackageParser.generatePackageInfo(pkg, null, flags, 0, 0, null, state);

} catch (PackageParserException e) {

return null;

}

}

我们继续分析handleReturnCode函数,当mContinueToInstall为true就调用processPendingInstall函数继续装载应用,当为false,就调用doPreInstall。联系到之前mContinueToInstall默认为true,因为不是adb安装的话mContinueToInstall就应该默认为true,要不然不能继续装载应用了。

@Override

void handleReturnCode() {

// If mArgs is null, then MCS couldn't be reached. When it

// reconnects, it will try again to install. At that point, this

// will succeed.

if (mArgs != null) {

if (mContinueToInstall) {

processPendingInstall(mArgs, mRet);

} else {

mArgs.doPreInstall(PackageManager.INSTALL_FAILED_MISSING_FEATURE);

}

}

}

我们再来看doPreInstall函数,当状态不是success,就删除一些临时文件。

int doPreInstall(int status) {

if (status != PackageManager.INSTALL_SUCCEEDED) {

cleanUp();

}

return status;

}



adb广告拦截 android,Android PKMS拦截adb安装应用相关推荐

  1. adb广告拦截 android,IT之家学院:使用adb揪出安卓后台弹窗广告APP原形

    感谢IT之家网友 懒猫咪的夏天 的投稿 背景 相信不少安卓用户中过影子弹窗广告的困扰,这种推广APP本体在后台运行,而且可以在其他APP上弹出覆盖广告,一不小心就会误操作,点击广告或者下载APP,着实 ...

  2. Android Java虚拟机拦截技术分析

    2019独角兽企业重金招聘Python工程师标准>>> 最近反编译金山毒霸,分析其广告拦截功能是如何实现的.根据金山毒霸的介绍,采用了java虚拟机拦截技术,带着好奇去研究了一下.在 ...

  3. android 命令启动服务,adb 命令

    Android 调试桥 adb ( Android Debug Bridge)是一个通用命令行工具,其允许您与模拟器实例或连接的 Android 设备进行通信.它可为各种设备操作提供便利,如安装和调试 ...

  4. 【Android 逆向】函数拦截 ( GOT 表拦截 与 插桩拦截 | 插桩拦截简介 | 插桩拦截涉及的 ARM 和 x86 中的跳转指令 )

    文章目录 一.GOT 表拦截与插桩拦截 二.插桩拦截简介 三.插桩拦截涉及的 ARM 和 x86 中的跳转指令 一.GOT 表拦截与插桩拦截 函数拦截有 222 种方式 : 使用 GOT 表进行函数拦 ...

  5. 【Android 逆向】Android 逆向通用工具开发 ( adb forward 网络端口重定向命令 | PC 端逆向程序主函数分析 )

    文章目录 前言 一.adb forward 网络端口重定向命令 二.PC 端逆向程序主函数分析 前言 本篇博客重点分析 PC 端 hacktool 模块 ; 一.adb forward 网络端口重定向 ...

  6. 遇到问题描述:Android Please ensure that adb is correctly located at问题解决

    遇到问题描述: 运行android程序控制台输出 [2013-11-04 16:18:26 - ] The connection to adb is down, and a severe error ...

  7. adb链接手机调试android应用

    adb链接手机调试android应用 hulk@hulk-Lenovo:~$ adb devices List of devices attached  ???????????? no permiss ...

  8. android 手机命令大全,adb 命令大全

    adb是什么 adb的全称为Android Debug Bridge,就是起到调试桥的作用.它就是一个命令行窗口,用于通过电脑端与模拟器或者是设备之间的交互. adb有什么用 借助adb工具,我们可以 ...

  9. [Android] The connection to adb is down, and a severe error has occured

    一.ADB server didn't ACK 在配置完Android环境后,运行第一个程序时,遇到了如下错误:         ADB server didn't ACK         * fai ...

  10. android root 挂载分区,adb — adb disable-verity, adb remount 实现重新挂载system分区为可读写分区...

    关键词:adb; disable-verity; adb remount; android 7.1; 如果你的安卓版本是android7.1之前的版本,请参考该文章< 1.android 在版本 ...

最新文章

  1. Publons:文章审稿、编辑工作认证平台
  2. #地形剖面图_高考地理笔记:经纬网、等值线、地形剖面图知识汇总
  3. Android 更改签名
  4. python list中的append 与 extended 的区别
  5. 使用Firebase、Angular 8和ASP.NET Core 3.1保护网站安全
  6. 提高网站速度|负载均衡
  7. Codrops 优秀教程:实现效果精美的多层推拉菜单
  8. 佳能g3800打印机黄灯和绿灯交替闪是什么情况?
  9. INVENTOR结构件生成器,新建型材
  10. 计算机无法安装u盘驱动,电脑上插入u盘提示未能成功安装设备驱动程序怎么修复...
  11. 计算机的剪切快捷键是什么意思,word中剪切的快捷键是什么 -电脑资料
  12. Python爬虫 requests使用post请求发送文件
  13. 【计算机网络系列】链路层的差错控制与流量控制
  14. NTFS XCB定位
  15. React之antd Form回显数据
  16. 面试官:你来说一下Spring IOC容器的创建过程
  17. SQL SERVER数据库备份与复制(4):让SQL SERVER自动备份方法一
  18. 连续系统的动态规划问题
  19. 抖音seo账号矩阵源码系统搭建技术开发
  20. 台式计算机如何升级,台式电脑怎样升级系统

热门文章

  1. YDOOK:ESP8266: 官方实测功耗统计
  2. 计算机专业发论文的等级有哪些,计算机专业发表职称论文多少字
  3. 开口式霍尔电流传感器(安科瑞-卓宋兰)
  4. chrome浏览器插件,让您浏览器页面游小鱼儿
  5. BOJINGnet——WiFi内窥镜APP下载方法 WiFi图传内窥镜怎么使用教程
  6. 难倒英语专业的42个翻译句子
  7. Keras多层感知器实例:印第安人糖尿病诊断
  8. 两化融合企业申报奖励制度
  9. ITeye论坛规则测验答案 [最新!]
  10. pycharm安装到32位操作系统