我们再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. 前端进阶(二)webpack开发服务器环境配置
  2. OpenGL创建hello Window你好,窗口
  3. Android Studio打包APK时出现 is not translated in en (English) [MissingTranslation]
  4. jbox2d_JBox2D和JavaFX:事件与力量
  5. python爬虫消费者与生产者_Condition版生产者与消费者模式
  6. 实现服务器和客户端数据交互,Java Socket有妙招
  7. java随机姓名_Java随机产生中文昵称
  8. 经常用到的一些小病的预防的治疗
  9. bzoj 1615: [Usaco2008 Mar]The Loathesome Hay Baler麻烦的干草打包机
  10. Pandas库之DataFrame学习笔记
  11. 苹果home键在哪里设置_苹果手机怎样添加辅助触控功能
  12. 下载mp4v2代码的链接
  13. 新visio2019专业版最新功能和激活密钥!
  14. 关于光学软件设计衍射透镜的一点总结
  15. windos开启IIS管理器
  16. 深度学习数据增强(data_augmentation):Keras ImageDataGenerator
  17. Python3.9数据库SQLite3学起(6)
  18. android全局的dialog,使android的dialog全局显示
  19. 响铃:“新品牌计划”出炉,但拼多多要的不只是C2M
  20. 进销存系统_用户信息更新密码修改(3)

热门文章

  1. interfaces 的用途:开机启用eth0并设置IP为static或者dhcp
  2. 物联网在智慧城市建设中的角色研究
  3. 【发表案例】 CCF推荐网络安全类SCI,仅27天录用
  4. 迈普光彩北区销售部签订辽宁某会议室55寸LCD液晶拼接显示屏项目
  5. oralce 数据库基础
  6. React基础—父子组件通信
  7. HTML5 在a标签内放置块级元素
  8. SpringBoot基础 核心技术
  9. wintogo论坛_说走就走的「Windows」—— Windows To Go 制作详解
  10. 【转】游戏引擎剖析(Game Engine Anatomy 101)