adb广告拦截 android,Android PKMS拦截adb安装应用
我们再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安装应用相关推荐
- adb广告拦截 android,IT之家学院:使用adb揪出安卓后台弹窗广告APP原形
感谢IT之家网友 懒猫咪的夏天 的投稿 背景 相信不少安卓用户中过影子弹窗广告的困扰,这种推广APP本体在后台运行,而且可以在其他APP上弹出覆盖广告,一不小心就会误操作,点击广告或者下载APP,着实 ...
- Android Java虚拟机拦截技术分析
2019独角兽企业重金招聘Python工程师标准>>> 最近反编译金山毒霸,分析其广告拦截功能是如何实现的.根据金山毒霸的介绍,采用了java虚拟机拦截技术,带着好奇去研究了一下.在 ...
- android 命令启动服务,adb 命令
Android 调试桥 adb ( Android Debug Bridge)是一个通用命令行工具,其允许您与模拟器实例或连接的 Android 设备进行通信.它可为各种设备操作提供便利,如安装和调试 ...
- 【Android 逆向】函数拦截 ( GOT 表拦截 与 插桩拦截 | 插桩拦截简介 | 插桩拦截涉及的 ARM 和 x86 中的跳转指令 )
文章目录 一.GOT 表拦截与插桩拦截 二.插桩拦截简介 三.插桩拦截涉及的 ARM 和 x86 中的跳转指令 一.GOT 表拦截与插桩拦截 函数拦截有 222 种方式 : 使用 GOT 表进行函数拦 ...
- 【Android 逆向】Android 逆向通用工具开发 ( adb forward 网络端口重定向命令 | PC 端逆向程序主函数分析 )
文章目录 前言 一.adb forward 网络端口重定向命令 二.PC 端逆向程序主函数分析 前言 本篇博客重点分析 PC 端 hacktool 模块 ; 一.adb forward 网络端口重定向 ...
- 遇到问题描述: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 ...
- adb链接手机调试android应用
adb链接手机调试android应用 hulk@hulk-Lenovo:~$ adb devices List of devices attached ???????????? no permiss ...
- android 手机命令大全,adb 命令大全
adb是什么 adb的全称为Android Debug Bridge,就是起到调试桥的作用.它就是一个命令行窗口,用于通过电脑端与模拟器或者是设备之间的交互. adb有什么用 借助adb工具,我们可以 ...
- [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 ...
- android root 挂载分区,adb — adb disable-verity, adb remount 实现重新挂载system分区为可读写分区...
关键词:adb; disable-verity; adb remount; android 7.1; 如果你的安卓版本是android7.1之前的版本,请参考该文章< 1.android 在版本 ...
最新文章
- Publons:文章审稿、编辑工作认证平台
- #地形剖面图_高考地理笔记:经纬网、等值线、地形剖面图知识汇总
- Android 更改签名
- python list中的append 与 extended 的区别
- 使用Firebase、Angular 8和ASP.NET Core 3.1保护网站安全
- 提高网站速度|负载均衡
- Codrops 优秀教程:实现效果精美的多层推拉菜单
- 佳能g3800打印机黄灯和绿灯交替闪是什么情况?
- INVENTOR结构件生成器,新建型材
- 计算机无法安装u盘驱动,电脑上插入u盘提示未能成功安装设备驱动程序怎么修复...
- 计算机的剪切快捷键是什么意思,word中剪切的快捷键是什么 -电脑资料
- Python爬虫 requests使用post请求发送文件
- 【计算机网络系列】链路层的差错控制与流量控制
- NTFS XCB定位
- React之antd Form回显数据
- 面试官:你来说一下Spring IOC容器的创建过程
- SQL SERVER数据库备份与复制(4):让SQL SERVER自动备份方法一
- 连续系统的动态规划问题
- 抖音seo账号矩阵源码系统搭建技术开发
- 台式计算机如何升级,台式电脑怎样升级系统