本帖最后由 shenweidaitu 于 2026-9-8 23:47 编辑
ok我又来发帖了朋友们,这次也是一个详细教程,会带着大家大家一步来逆向这个APP
继续经典边写文章边分析,这次我们来逆向Realme手机的手机管家,相信大家在安装app的时候肯定有遇到过安装新安装的APP
但是不准你安装的时候,这次我来教大家怎么hook检查安装这个功能(类似下图)
来跟着小杰的思路一起来学习怎么逆向这个功能
首先打开MT管理器点击Activity记录
通过这一步我们可以看到屏幕最顶层显示的类
然后安装一个演员APP(我这里用的算法助手,膜拜军哥大佬)
因为我发现我安装那种云控APP居然没有弹出不让我安装,但是算法助手居然不行[发呆]
不管他了,ok然后会弹一个不让安装的提示
然后回到MT管理器,看一下记录的Activity记录
也就是这个应用包安装器,看一下报名oplus就知道这肯定是厂家弄的
先不管他先提取出APP
提前第一个
一般逆向思路都是先根据字符串定位,没有的话在思考别的
所以我先定位高风险看看有没有记录这个字符串
这里为了分析方便我选择采用jadx
可以看到空空如也,然后呢字符串索引失败我们该怎么继续往下走
大家可以看到我之前的图那个activity记录,里面有显示最上层的类名
也就是com.oplus.appdetail.model.guide.ui.InstallGuideActivity
那我们直接进来这个类看看package com.oplus.appdetail.model.guide.ui;
import android.content.ComponentName;
import android.content.ContentResolver;
import android.content.Context;
import android.content.Intent;
import android.database.ContentObserver;
import android.net.Uri;
import android.os.Bundle;
import android.os.Handler;
import android.provider.Settings;
import android.text.TextUtils;
import android.widget.FrameLayout;
import androidx.fragment.app.Fragment;
import androidx.fragment.app.r;
import androidx.lifecycle.LifecycleOwnerKt;
import com.oplus.appdetail.R;
import com.oplus.appdetail.base.activity.BaseActivity;
import com.oplus.appdetail.install.AppInstallManager;
import com.oplus.appdetail.model.finish.InstallFinishActivity;
import com.oplus.appdetail.model.guide.repository.ExtJumpParam;
import com.oplus.appdetail.model.guide.repository.netrequest.g;
import com.oplus.appdetail.model.guide.viewModel.GuideShareViewModel;
import com.oplus.appdetail.modelv2.helper.c;
import ge.o;
import he.d;
import kotlin.jvm.internal.s;
import kotlinx.coroutines.j;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
/* compiled from: InstallGuideActivity.kt */
/* loaded from: classes2.dex */
public final class InstallGuideActivity extends BaseActivity {
private GuideShareViewModel K;
private ContentObserver L;
private ContentObserver M;
/* compiled from: InstallGuideActivity.kt */
/* loaded from: classes2.dex */
public static final class a extends ContentObserver {
/* renamed from: a reason: collision with root package name */
final /* synthetic */ Uri f13262a;
/* renamed from: b reason: collision with root package name */
final /* synthetic */ InstallGuideActivity f13263b;
/* JADX WARN: 'super' call moved to the top of the method (can break code semantics) */
a(Handler handler, Uri uri, InstallGuideActivity installGuideActivity) {
super(handler);
this.f13262a = uri;
this.f13263b = installGuideActivity;
}
@Override // android.database.ContentObserver
public void onChange(boolean z10, @Nullable Uri uri) {
if (s.a(this.f13262a, uri)) {
this.f13263b.E0();
}
}
}
/* compiled from: InstallGuideActivity.kt */
/* loaded from: classes2.dex */
public static final class b extends ContentObserver {
/* renamed from: a reason: collision with root package name */
final /* synthetic */ Uri f13264a;
/* renamed from: b reason: collision with root package name */
final /* synthetic */ InstallGuideActivity f13265b;
/* JADX WARN: 'super' call moved to the top of the method (can break code semantics) */
b(Handler handler, Uri uri, InstallGuideActivity installGuideActivity) {
super(handler);
this.f13264a = uri;
this.f13265b = installGuideActivity;
}
@Override // android.database.ContentObserver
public void onChange(boolean z10, @Nullable Uri uri) {
if (s.a(this.f13264a, uri)) {
this.f13265b.E0();
}
}
}
/* JADX INFO: Access modifiers changed from: private */
public final void C0() {
GuideShareViewModel guideShareViewModel = this.K;
if (guideShareViewModel == null) {
s.x("mViewModel");
guideShareViewModel = null;
}
guideShareViewModel.d().observe(this, new com.oplus.appdetail.model.guide.ui.b(new InstallGuideActivity$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$addFragmentReloadObserver$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$1(this)));
}
/* JADX INFO: Access modifiers changed from: private */
public final void D0() {
FrameLayout frameLayout = new FrameLayout(this);
frameLayout.setLayoutParams(new FrameLayout.LayoutParams(-1, -1));
frameLayout.setClipToPadding(false);
frameLayout.setId(R.id.view_id_contentview);
setContentView(frameLayout);
}
/* JADX INFO: Access modifiers changed from: private */
public final void E0() {
GuideShareViewModel guideShareViewModel = this.K;
GuideShareViewModel guideShareViewModel2 = null;
if (guideShareViewModel == null) {
s.x("mViewModel");
guideShareViewModel = null;
}
ExtJumpParam c10 = guideShareViewModel.c();
GuideShareViewModel guideShareViewModel3 = this.K;
if (guideShareViewModel3 == null) {
s.x("mViewModel");
} else {
guideShareViewModel2 = guideShareViewModel3;
}
guideShareViewModel2.i();
Fragment a10 = c.a(c10);
if (a10 instanceof com.oplus.appdetail.base.activity.a) {
t0((com.oplus.appdetail.base.activity.a) a10);
}
r m10 = M().m();
if (M().k0("guide_fragment") != null) {
m10.q(R.anim.guide_activity_fade_in, R.anim.activity_fade_out_500);
}
m10.p(R.id.view_id_contentview, a10, "guide_fragment");
m10.i();
}
/* JADX INFO: Access modifiers changed from: private */
public final void F0(Context context, Handler handler) {
Uri uriFor = Settings.Secure.getUriFor("minors_mode_enabled");
s.e(uriFor, "getUriFor("minors_mode_enabled")");
this.M = new a(handler, uriFor, this);
ContentResolver contentResolver = context.getContentResolver();
ContentObserver contentObserver = this.M;
if (contentObserver == null) {
s.x("mEnableStateObserver");
contentObserver = null;
}
contentResolver.registerContentObserver(uriFor, false, contentObserver);
}
/* JADX INFO: Access modifiers changed from: private */
public final void G0(Context context, Handler handler) {
Uri uriFor = Settings.Secure.getUriFor("minors_mode_other_install_type");
s.e(uriFor, "getUriFor("minors_mode_other_install_type")");
this.L = new b(handler, uriFor, this);
ContentResolver contentResolver = context.getContentResolver();
ContentObserver contentObserver = this.L;
if (contentObserver == null) {
s.x("mInstallStateObserver");
contentObserver = null;
}
contentResolver.registerContentObserver(uriFor, false, contentObserver);
}
private final void H0() {
if (getIntent() != null && this.K != null) {
ComponentName component = getIntent().getComponent();
GuideShareViewModel guideShareViewModel = this.K;
if (guideShareViewModel == null) {
s.x("mViewModel");
guideShareViewModel = null;
}
ExtJumpParam c10 = guideShareViewModel.c();
if (component != null && c10 != null) {
boolean isFullDecouple = c10.isFullDecouple();
boolean equals = TextUtils.equals(component.getClassName(), InstallFinishActivity.class.getName());
if (isFullDecouple && !equals) {
AppInstallManager.q(c10.getExtJumpTag(), null, false, false);
AppInstallManager.p(c10.getExtJumpTag(), this);
g.d(c10.getInstallTrackId());
}
}
}
}
/* JADX INFO: Access modifiers changed from: protected */
@Override // androidx.fragment.app.FragmentActivity, androidx.activity.ComponentActivity, android.app.Activity
public void onActivityResult(int i10, int i11, @Nullable Intent intent) {
super.onActivityResult(i10, i11, intent);
if (i10 != 999) {
return;
}
int i12 = -1;
if (intent != null) {
i12 = intent.getIntExtra("key_authentication_type", -1);
}
if (i11 != 100) {
if (i11 != 101) {
fe.g.a("InstallGuideActivity", "onActivityResult minors verify other");
} else {
fe.g.a("InstallGuideActivity", "onActivityResult minors verify fail");
}
} else {
GuideShareViewModel guideShareViewModel = this.K;
if (guideShareViewModel == null) {
s.x("mViewModel");
guideShareViewModel = null;
}
guideShareViewModel.g(i11);
}
o.t(d.g().h(this), fd.g.a(), i11, i12, "1");
fe.g.a("InstallGuideActivity", "onActivityResult minors verify resultCode : " + i11 + ", type : " + i12);
}
/* JADX INFO: Access modifiers changed from: protected */
@Override // com.oplus.appdetail.base.activity.BaseActivity, androidx.fragment.app.FragmentActivity, androidx.activity.ComponentActivity, androidx.core.app.ComponentActivity, android.app.Activity
public void onCreate(@Nullable Bundle bundle) {
super.onCreate(bundle);
if (getIntent() != null) {
j.d(LifecycleOwnerKt.getLifecycleScope(this), null, null, new InstallGuideActivity$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$onCreate$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$1(this, null), 3, null);
return;
}
o.A(null, "intent_null", null);
kc.b.g(this);
}
/* JADX INFO: Access modifiers changed from: protected */
@Override // androidx.appcompat.app.AppCompatActivity, androidx.fragment.app.FragmentActivity, android.app.Activity
public void onDestroy() {
super.onDestroy();
ContentObserver contentObserver = null;
if (this.L != null) {
ContentResolver contentResolver = getContentResolver();
ContentObserver contentObserver2 = this.L;
if (contentObserver2 == null) {
s.x("mInstallStateObserver");
contentObserver2 = null;
}
contentResolver.unregisterContentObserver(contentObserver2);
}
if (this.M != null) {
ContentResolver contentResolver2 = getContentResolver();
ContentObserver contentObserver3 = this.M;
if (contentObserver3 == null) {
s.x("mEnableStateObserver");
} else {
contentObserver = contentObserver3;
}
contentResolver2.unregisterContentObserver(contentObserver);
}
H0();
}
/* JADX INFO: Access modifiers changed from: protected */
@Override // com.oplus.appdetail.base.activity.BaseActivity, androidx.fragment.app.FragmentActivity, android.app.Activity
public void onResume() {
super.onResume();
GuideShareViewModel guideShareViewModel = this.K;
if (guideShareViewModel != null) {
GuideShareViewModel guideShareViewModel2 = null;
if (guideShareViewModel == null) {
s.x("mViewModel");
guideShareViewModel = null;
}
if (guideShareViewModel.c() != null) {
GuideShareViewModel guideShareViewModel3 = this.K;
if (guideShareViewModel3 == null) {
s.x("mViewModel");
} else {
guideShareViewModel2 = guideShareViewModel3;
}
ExtJumpParam c10 = guideShareViewModel2.c();
s.c(c10);
fd.g.b(c10.getExtJumpTag());
}
}
}
/* JADX INFO: Access modifiers changed from: protected */
@Override // com.oplus.appdetail.base.activity.BaseActivity, androidx.activity.ComponentActivity, androidx.core.app.ComponentActivity, android.app.Activity
public void onSaveInstanceState(@NotNull Bundle outState) {
s.f(outState, "outState");
super.onSaveInstanceState(outState);
GuideShareViewModel guideShareViewModel = this.K;
if (guideShareViewModel != null) {
if (guideShareViewModel == null) {
s.x("mViewModel");
guideShareViewModel = null;
}
outState.putBoolean("isFullDecouple", guideShareViewModel.f());
}
}
/* JADX INFO: Access modifiers changed from: protected */
@Override // com.oplus.appdetail.base.activity.BaseActivity
public void r0(@Nullable Bundle bundle) {
super.r0(bundle);
if (bundle != null && bundle.getBoolean("isFullDecouple", false)) {
com.oplus.appdetail.install.a.a(this);
}
}
}
这里贴一下这个类完整代码
这里教一下大家怎拆解public final class InstallGuideActivity extends BaseActivity {
private GuideShareViewModel K;
private ContentObserver L;
private ContentObserver M;
首先 extends 了一个base activity 说明这是一个activity页面,封装了视图的基础能力,
private GuideShareViewModel K;
private ContentObserver L;
private ContentObserver M;
有三个成员变量 第一个是viewmodel 存储状态的
有两个contentobserver a和b 这两个是用来监听变化的
contentobserver会有三个需要重写的方法
registerContentObserver注册,onChange回调触发业务方法,unregister销毁反注册
一般分析回调onchange
然后我带大家来看一下这两个onchange都是调用了e0方法
说明这个e0是古希腊掌管代码变化的神,一个安装页面又能安装又能不让你安装
肯定是有个什么东东控制了,这个e0就是那个东东
那我们肯定分析e0
public final void E0() {
GuideShareViewModel guideShareViewModel = this.K;
GuideShareViewModel guideShareViewModel2 = null;
if (guideShareViewModel == null) {
s.x("mViewModel");
guideShareViewModel = null;
}
ExtJumpParam c10 = guideShareViewModel.c();
GuideShareViewModel guideShareViewModel3 = this.K;
if (guideShareViewModel3 == null) {
s.x("mViewModel");
} else {
guideShareViewModel2 = guideShareViewModel3;
}
guideShareViewModel2.i();
Fragment a10 = c.a(c10);
if (a10 instanceof com.oplus.appdetail.base.activity.a) {
t0((com.oplus.appdetail.base.activity.a) a10);
}
r m10 = M().m();
if (M().k0("guide_fragment") != null) {
m10.q(R.anim.guide_activity_fade_in, R.anim.activity_fade_out_500);
}
m10.p(R.id.view_id_contentview, a10, "guide_fragment");
m10.i();
}
来带大家分析下
private GuideShareViewModel K;
private ContentObserver L;
private ContentObserver M; GuideShareViewModel guideShareViewModel = this.K;
这个也就是我们sharevm对象 控制视图的
ExtJumpParam c10 = guideShareViewModel.c();
从这个视图对象获取跳转参数c10
为后续跳转做准备
GuideShareViewModel guideShareViewModel3 = this.K;
vm3也是我们的viewmodel对象
guideShareViewModel2 = guideShareViewModel3;
vm2也是,所以其实vm1-3其实都是同一个对象
guideShareViewModel2.i();
这里viewmodel执行了一个i方法
我看了一下是个埋点的void方法 本来想带着分析下的 但是这个是干扰项没用就忽略它
Fragment a10 = c.a(c10);走到这一行
是一个fragment
fragment这里得重点强调
先给大家普及一下小知识,一个activity我们可以看作成一个浏览器,而fragment便是浏览器的一个个网页
所以一个activity能变化出不同的样式,fragment是一个很关键的东西
Fragment a10 = c.a(c10);
并且传参是c10,刚好是那个跳转参数
ok大概这就应该是我们要找的东西了,跟进去
public static final Fragment a(@Nullable ExtJumpParam extJumpParam) {
String str;
boolean z10;
Context appContext = AppUtil.getAppContext();
String str2 = null;
if (mc.d.b(appContext)) {
if (extJumpParam != null) {
str = extJumpParam.getPackageUri();
} else {
str = null;
}
if (str != null && str.length() != 0) {
z10 = false;
} else {
z10 = true;
}
if (!z10) {
GuideFragmentType guideFragmentType = GuideFragmentType.ScanningGuide;
if (extJumpParam != null) {
str2 = extJumpParam.getExtJumpTag();
}
o.Q(guideFragmentType, str2);
if (n.e(appContext)) {
if (n.d(appContext)) {
return new EnhanceMinorsFragment();
}
return new BasicMinorsFragment();
}
return new EnhanceGuardFragment();
}
}
GuideFragmentType guideFragmentType2 = GuideFragmentType.NoScanningGuide;
if (extJumpParam != null) {
str2 = extJumpParam.getExtJumpTag();
}
o.Q(guideFragmentType2, str2);
return new id.b();
}
}
这就是他的代码
[hide]
哎呀我的妈呀好多if呀,没关系,我带大家一步一步来拆解
if (mc.d.b(appContext)) {
第一个if 传了一个appcontext 一般是获取管理器的时候用到
我们可以先猜一下 应该是获取包名什么的,判断一下是不是特殊包名 public static boolean b(Context context) {
if (context == null) {
return false;
}
if (f19036a == null) {
try {
context.getPackageManager().getPackageInfo(a(), 0);
f19036a = Boolean.TRUE;
} catch (Exception unused) {
f19036a = Boolean.FALSE;
}
}
return f19036a.booleanValue();
}
if (context == null) {
return false;
}
如果没有context环境直接返回false
if (f19036a == null) {
try {
context.getPackageManager().getPackageInfo(a(), 0);
f19036a = Boolean.TRUE;
} catch (Exception unused) {
f19036a = Boolean.FALSE;
}
}
return f19036a.booleanValue();
然后这里 有一个f19036a 看后面也知道其实是一个布尔值
context.getPackageManager().getPackageInfo(a(), 0); 获取这个包
如果没抛异常就为true
抛了就是false
public static String a() {
if (Build.VERSION.SDK_INT >= 29) {
return "com.heytap.market";
}
return "com." + EraseBrandUtil.BRAND_O2 + ".market";
}
跟进去发现是检测com.heytap.market这个包
搜了一下发现是这个包
这不就是我手机的应用商店吗
如果他在就返回true
不在就false
回到刚刚那个fragment a方法
public static final Fragment a(@Nullable ExtJumpParam extJumpParam) {
String str;
boolean z10;
Context appContext = AppUtil.getAppContext();
String str2 = null;
if (mc.d.b(appContext)) {
if (extJumpParam != null) {
str = extJumpParam.getPackageUri();
} else {
str = null;
}
if (str != null && str.length() != 0) {
z10 = false;
} else {
z10 = true;
}
if (!z10) {
GuideFragmentType guideFragmentType = GuideFragmentType.ScanningGuide;
if (extJumpParam != null) {
str2 = extJumpParam.getExtJumpTag();
}
o.Q(guideFragmentType, str2);
if (n.e(appContext)) {
if (n.d(appContext)) {
return new EnhanceMinorsFragment();
}
return new BasicMinorsFragment();
}
return new EnhanceGuardFragment();
}
}
GuideFragmentType guideFragmentType2 = GuideFragmentType.NoScanningGuide;
if (extJumpParam != null) {
str2 = extJumpParam.getExtJumpTag();
}
o.Q(guideFragmentType2, str2);
return new id.b();
}
也就是说如果没安装这个的话
GuideFragmentType guideFragmentType2 = GuideFragmentType.NoScanningGuide;
if (extJumpParam != null) {
str2 = extJumpParam.getExtJumpTag();
}
o.Q(guideFragmentType2, str2);
return new id.b();
手机安装只会执行这一点点代码
前面那么多if全跳过
ok我也猜到了应该就是有应用商店就会查毒,没商店就应该正常走安装逻辑
然后我跟进了一下 new id.b();
是一个fragment页面我看了一下就是正常安装页面
........所以说想安装应用大家可以试试删掉应用商店
但是因为这个贴我奔着精华帖去的,所以不这么快结束
分析前面的if
如果安装了商店那么会怎么走
然后看着名字其实也知道
enhance增强
guard防护
这不就是增强防护嘛。。。。。。
但是还是继续带大家一起分析
if (extJumpParam != null) {
str = extJumpParam.getPackageUri();
} else {
str = null;
}
如果带进来的jump参数不为空
就放进str如果没参数str就为null
if (str != null && str.length() != 0) {
z10 = false;
} else {
z10 = true;
}
z10是个布尔值,str不为null为false 为null就是true
如果z10为false就进入这个循环
也就是说
如果之前那个页面传了参数就进去那个扫描页面
没传参数就正常安装
GuideFragmentType guideFragmentType = GuideFragmentType.ScanningGuide;
if (extJumpParam != null) {
str2 = extJumpParam.getExtJumpTag();
}
o.Q(guideFragmentType, str2);
if (n.e(appContext)) {
if (n.d(appContext)) {
return new EnhanceMinorsFragment();
}
return new BasicMinorsFragment();
}
return new EnhanceGuardFragment();
分析下这段
GuideFragmentType guideFragmentType = GuideFragmentType.ScanningGuide; GuideFragmentType guideFragmentType2 = GuideFragmentType.NoScanningGuide;
见明知意啊,和下面那个形成对比
上面的就是扫描模式,下面的就是不扫描模式
也就是说传了参数就给你扫描
if (extJumpParam != null) {
str2 = extJumpParam.getExtJumpTag();
}
提取下参数tag 放到str2里
if (n.e(appContext)) {
if (n.d(appContext)) {
return new EnhanceMinorsFragment();
}
return new BasicMinorsFragment();
}
这个e方法跟进去看一下
public static boolean e(Context context) {
if (h(context) && b(context)) {
return true;
}
return false;
}
public static boolean b(Context context) {
if (context == null || Settings.Secure.getInt(context.getContentResolver(), "minors_mode_enabled", 0) != 1) {
return false;
}
return true;
}
public static boolean h(Context context) {
if (context == null || Settings.Secure.getInt(context.getContentResolver(), "minors_mode", 0) != 1) {
return false;
}
return true;
}
见明知意啊 未成年模式 我也不知道为啥叫未成年模式
可能我们都还是小朋友吧
意思就是如果两个未成年模式都打开就执行
如果没打开就执行这个
return new EnhanceGuardFragment();
点进去看一下
好家伙
还是一样见明知意
大家自己去搜一下啥意思吧
就是一个风险安装面
ok在看这个代码
if (n.d(appContext)) {
return new EnhanceMinorsFragment();
}
return new BasicMinorsFragment();
}
跟进d方法
public static boolean d(Context context) {
if (a(context) == 1) {
return true;
}
return false;
}
在跟进a
public static int a(Context context) {
if (context == null) {
return -1;
}
return Settings.Secure.getInt(context.getContentResolver(), "minors_mode_other_install_type", 0);
}
关键是这个minors_mode_other_install_type 青少年模式其他安装类型
如果为1就是 return new EnhanceMinorsFragment();
如果是0就是 return new BasicMinorsFragment();
因为代码好长我就不贴这两个代码了
return new BasicMinorsFragment(); 这个我看了一下
是会提示风险但是可以让你点继续安装
new EnhanceGuardFragment();
这个是完全不准你安装
return new EnhanceMinorsFragment();
这个是跳到设置 不知道让你去干嘛
不管她,这样我们就分析完了
所以hook点就是这段的b方法
让他为false就好
但是我们先用frida验证下看进没进来a方法
let c = Java.use("com.oplus.appdetail.modelv2.helper.c");
c["a"].implementation = function (extJumpParam) {
console.log(`c.a is called: extJumpParam=$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$${extJumpParam}`);
let result = this["a"](extJumpParam);
console.log(`c.a result=$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$${result}`);
return result;
};
Error: java.lang.ClassNotFoundException: com.oplus.appdetail.modelv2.helper.c
at <anonymous> (frida/node_modules/frida-java-bridge/lib/env.js:124)
at <anonymous> (frida/node_modules/frida-java-bridge/lib/env.js:115)
at apply (native)
at <anonymous> (frida/node_modules/frida-java-bridge/lib/env.js:97)
at <anonymous> (frida/node_modules/frida-java-bridge/lib/class-factory.js:488)
at value (frida/node_modules/frida-java-bridge/lib/class-factory.js:945)
居然hook不到!!!我的妈呀写这么一大串难道是错的??
不应该我觉得,先hookeE0试试
ok E0也不行
大家正好来和小杰来一起学一下遇到这种翻车我们该如何分析
Error: java.lang.ClassNotFoundException: com.oplus.appdetail.modelv2.helper.c
首先找不到这个方法这是为什么,定位这个类确实有
难道是因为线程不在java里??
加一个java.perform
。。。。还真的ok现在没报错了
Java.perform(function () {
let c = Java.use("com.oplus.appdetail.modelv2.helper.c");
c["a"].implementation = function (extJumpParam) {
console.log(`c.a is called: extJumpParam=$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$${extJumpParam}`);
let result = this["a"](extJumpParam);
console.log(`c.a result=$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$${result}`);
return result;
};
console.log(222)
})
> _ | Commands:
/_/ |_| help -> Displays the help system
. . . . object? -> Display information about 'object'
. . . . exit/quit -> Exit
. . . .
. . . . More info at https://frida.re/docs/home/
. . . .
. . . . Connected to RMX3700 (id=192.168.3.56:5555)
[RMX3700::应用安装器 ]-> 222
222打印了就说明钩子没问题c.a is called: extJumpParam=ExtJumpParam{channelPkg=com.coloros.filemanager, pkg= com.pingan.carowner, appVerCode=4127, appVerName=5.03.2, appName=平安好车主, installId=com.pingan.carowner1788782374984appIcon=16685, appRequirePermissions=98, appSize=105421700, safeRecommendSwitch=0, packageUri=file:///storage/emulated/0/Download/pa.apk, appFilePath=file:///storage/emulated/0/Download/pa.apk, is64Bit=0, extJumpTag=com.pingan.carowner1788782374984, callerPkg=com.android.packageinstaller, channelName=文件管理,isFullDecouple=falseshowAutoDeleteApk=trueautoDeleteApkSwith=true}
c.a result=EnhanceGuardFragment{ac72a67} (843f41cf-c6a0-40ae-9578-4310441170b6)
找一个软件随便安装一下
okhook出来了,确实进入了这个函数那就没问题了
ok我就说像我这种天才怎么可能出错(手动滑稽)
所以就是hook这个b方法直接返回false就好了
让我来试试
然后hook代码Java.perform(function(){
let d = Java.use("mc.d");
d["b"].implementation = function (context) {
console.log(`d.b is called: context=$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$${context}`);
let result = this["b"](context);
console.log(`d.b result=$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$${result}`);
return result;
};
})
然后这是日志[RMX3700::应用安装器 ]-> d.b is called: context=com.oplus.appdetail.model.cancel.CancelInstallActivity@6a676ca
d.b result=true
d.b is called: context=com.oplus.appdetail.model.cancel.CancelInstallActivity@6a676ca
d.b result=true
d.b is called: context=com.oplus.appdetail.app.BaseApplication@79c52b8
d.b result=true
现在是返回true的需要扫描
Java.perform(function(){
let d = Java.use("mc.d");
d["b"].implementation = function (context) {
console.log(`d.b is called: context=$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$${context}`);
let result = this["b"](context);
console.log(`d.b result=$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$${result}`);
return false;
};
})
强制返回false
直接来到安装,完美呀
聪明如我
所以就是说如果你想跳过安装有两种方法
一种是吧应用商店删了,他就不会管你
另一种就是
找到这个安装包的这个d类的b方法强制返回false
以后你就可以随便安装你自己想安装的应用啦
我有预感此帖必加精好吧
|