GithubHelp home page GithubHelp logo

oasisfeng / condom Goto Github PK

View Code? Open in Web Editor NEW
2.5K 2.5K 169.0 327 KB

一个超轻超薄的Android工具库,阻止三方SDK中常见的有害行为,而不影响应用自身的功能。(例如严重影响用户体验的『链式唤醒』)

License: Apache License 2.0

Java 100.00%

condom's People

Contributors

oasisfeng avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

condom's Issues

部分手机crash

Fatal Exception: java.lang.RuntimeException: Unable to start service com.ss.android.message.NotifyService@42089690 with Intent { act=pull_do_schedule flg=0x4 cmp=com.ss.android.ugc.trill/com.ss.android.message.NotifyService (has extras) }: java.lang.reflect.UndeclaredThrowableException
at android.app.ActivityThread.handleServiceArgs(ActivityThread.java:2994)
at android.app.ActivityThread.access$2200(ActivityThread.java:172)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1402)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:146)
at android.app.ActivityThread.main(ActivityThread.java:5598)
at java.lang.reflect.Method.invokeNative(Method.java)
at java.lang.reflect.Method.invoke(Method.java:515)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1283)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1099)
at dalvik.system.NativeStart.main(NativeStart.java)
Caused by java.lang.reflect.UndeclaredThrowableException
at $Proxy0.serviceDoneExecuting(Unknown Source)
at android.app.ActivityThread.handleServiceArgs(ActivityThread.java:2986)
at android.app.ActivityThread.access$2200(ActivityThread.java:172)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1402)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:146)
at android.app.ActivityThread.main(ActivityThread.java:5598)
at java.lang.reflect.Method.invokeNative(Method.java)
at java.lang.reflect.Method.invoke(Method.java:515)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1283)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1099)
at dalvik.system.NativeStart.main(NativeStart.java)
Caused by java.lang.reflect.InvocationTargetException
at java.lang.reflect.Method.invokeNative(Method.java)
at java.lang.reflect.Method.invoke(Method.java:515)
at com.oasisfeng.condom.CondomProcess$CondomSystemService.invoke(CondomProcess.java:339)
at com.oasisfeng.condom.CondomProcess$CondomProcessActivityManager.invoke(CondomProcess.java:252)
at $Proxy0.serviceDoneExecuting(Unknown Source)
at android.app.ActivityThread.handleServiceArgs(ActivityThread.java:2986)
at android.app.ActivityThread.access$2200(ActivityThread.java:172)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1402)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:146)
at android.app.ActivityThread.main(ActivityThread.java:5598)
at java.lang.reflect.Method.invokeNative(Method.java)
at java.lang.reflect.Method.invoke(Method.java:515)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1283)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1099)
at dalvik.system.NativeStart.main(NativeStart.java)
Caused by android.os.TransactionTooLargeException
at android.os.BinderProxy.transact(Binder.java)
at android.app.ActivityManagerProxy.serviceDoneExecuting(ActivityManagerNative.java:3601)
at java.lang.reflect.Method.invokeNative(Method.java)
at java.lang.reflect.Method.invoke(Method.java:515)
at com.oasisfeng.condom.CondomProcess$CondomSystemService.invoke(CondomProcess.java:339)
at com.oasisfeng.condom.CondomProcess$CondomProcessActivityManager.invoke(CondomProcess.java:252)
at $Proxy0.serviceDoneExecuting(Unknown Source)
at android.app.ActivityThread.handleServiceArgs(ActivityThread.java:2986)
at android.app.ActivityThread.access$2200(ActivityThread.java:172)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1402)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:146)
at android.app.ActivityThread.main(ActivityThread.java:5598)
at java.lang.reflect.Method.invokeNative(Method.java)
at java.lang.reflect.Method.invoke(Method.java:515)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1283)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1099)
at dalvik.system.NativeStart.main(NativeStart.java)

混淆有问题啊

复现步骤:

  1. 新建一个Hello World空项目
  2. 添加依赖
  3. 开启混淆
  4. 编译打包

Will this project work with Android P?

As I just noticed, this project uses "android stub" to access @hide APIs.
Clearly, those APIs are private, and in Android P any call to those APIs should be blocked.

So, my question is will the project work with android P?

调用初始化代码后应用crash

在代码中执行初始化代码后,运行程序,应用崩溃,错误如下:

2021-04-28 16:55:21.767 22289-22289/com.example.myapplication E/AndroidRuntime: FATAL EXCEPTION: main
    Process: com.example.myapplication, PID: 22289
    java.lang.NoSuchMethodError: No static method metafactory(Ljava/lang/invoke/MethodHandles$Lookup;Ljava/lang/String;Ljava/lang/invoke/MethodType;Ljava/lang/invoke/MethodType;Ljava/lang/invoke/MethodHandle;Ljava/lang/invoke/MethodType;)Ljava/lang/invoke/CallSite; in class Ljava/lang/invoke/LambdaMetafactory; or its super classes (declaration of 'java.lang.invoke.LambdaMetafactory' appears in /apex/com.android.runtime/javalib/core-oj.jar)
        at com.oasisfeng.condom.CondomCore.<clinit>(CondomCore.java:293)
        at com.oasisfeng.condom.CondomContext.wrap(CondomContext.java:77)
        at com.oasisfeng.condom.CondomContext.wrap(CondomContext.java:61)
        at com.example.myapplication.MainActivity.onCreate(MainActivity.java:23)
        at android.app.Activity.performCreate(Activity.java:7802)
        at android.app.Activity.performCreate(Activity.java:7791)
        at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1299)
        at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:3245)
        at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:3409)
        at android.app.servertransaction.LaunchActivityItem.execute(LaunchActivityItem.java:83)
        at android.app.servertransaction.TransactionExecutor.executeCallbacks(TransactionExecutor.java:135)
        at android.app.servertransaction.TransactionExecutor.execute(TransactionExecutor.java:95)
        at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2016)
        at android.os.Handler.dispatchMessage(Handler.java:107)
        at android.os.Looper.loop(Looper.java:214)
        at android.app.ActivityThread.main(ActivityThread.java:7356)
        at java.lang.reflect.Method.invoke(Native Method)
        at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:492)
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:930)

demo代码如下:

public class App extends Application {

    @Override
    public void onCreate() {
        super.onCreate();
        CustimLib.init(CondomContext.wrap(this, "A123123"));
    }
}

应如何解决?

Q: Greenify says this is missing from every app?

@oasisfeng Whenever I try Check Convention Fulfillment on any app in Greenify (Donation, but not root), it toasts that this project is missing. Is it supposed to be compiled into Greenify itself or the app I'm checking? If the latter, that severely limits its usefulness.

求助 Island疑问?

您好,试过了您写的Island应用,功能很棒,我想问下正常情况下,四大组件在多用户中都是出于隔离的状态,您是如何做到多用户之间的组件通信呢,比如在用户 0 中获取用户 1 中的应用列表?谢谢!

迁移到maven

jcenter将会在明年停止服务,在此之前是否要迁移到maven?

ProGuard 配置

有些 sdk 通过反射调用方法,例如 微博 sdk,得加上 ProGuard 的配置:
-keep class com.oasisfeng.condom.** { *; }
或者
-keep class com.oasisfeng.condom.CondomContext { *; }

像极光推送,还是没法拦截

我接入了极光的推送和分享,每个init都是传的condomContext,也设置了CondomProcess.installExceptDefaultProcess(this),还设置了option,都没能禁止调唤醒第三方,我是通过miui设置中的应用行为记录中看到的,我看到自己的app还是去唤醒了别人的app,只是被禁止了。然后我在option的allow回调中,没有看到唤醒别家的包名,所以我就有点奇怪纳闷

[doc] Some map SDK may access unwrapped context with View.getContext()

Some map SDK requires developers put their MapView into layout file. For a example, amap use these demo code in their reference:

<com.amap.api.maps.MapView
    android:id="@+id/map"
    android:layout_width="match_parent"
    android:layout_height="match_parent"/>

If we use these views in our layout xml, their views will be constructed in LayoutInflater of Activity and use Activity itself as Context. And then these SDK may access unwrapped context with View.getContext(). This also figures out why these map SDK just does not need a initialization method.

To prevent this, we can construct these views in Activity.onCreate() and add their to layout manually. For a example, following Kotlin code acts same as above layout written in xml:

map = MapView(CondomContext.wrap(this, "MapView")).apply {
    layoutParams = CoordinatorLayout.LayoutParams(MATCH_PARENT, MATCH_PARENT)
}
layout.addView(map, 0)

Replace this with applicationContext also work properly.

Do you have any better idea?

getSystemService的拦截问题

通过CondomContext包装的condomContext, getSystemService 会被拦截到。
但如果
condomContext.startSerivce(new Intent(condomContext,DemoService.class));

DemoService 里面的getSystemService就无法拦截到了

这个有无解决方案?

建议

建议代码格式化一下呀,打算学习一波源码,但是代码格式化的太差了

Android13, Island-dev(after v6.1.2), getApplicationInfo not implemented in subclass

Caused by: java.lang.UnsupportedOperationException: getApplicationInfo not implemented in subclass
at android.content.pm.PackageManager.getApplicationInfo(PackageManager.java:5441)
at com.google.firebase.sessions.settings.LocalOverrideSettings.<init>(LocalOverrideSettings.kt:31)
at com.google.firebase.sessions.settings.SessionsSettings.<init>(SessionsSettings.kt:41)
at com.google.firebase.sessions.FirebaseSessions.<init>(FirebaseSessions.kt:43)
at com.google.firebase.sessions.FirebaseSessionsRegistrar.getComponents$lambda-0(FirebaseSessionsRegistrar.kt:48)
at com.google.firebase.sessions.FirebaseSessionsRegistrar.$r8$lambda$JITndpZCWeA0w9BDlkcI3l22oGY(Unknown Source:0)
com.oasisfeng.island                 E  	at com.google.firebase.sessions.FirebaseSessionsRegistrar$$ExternalSyntheticLambda0.create(Unknown Source:0)
at com.google.firebase.tracing.ComponentMonitor.lambda$processRegistrar$0(ComponentMonitor.java:38)
at com.google.firebase.tracing.ComponentMonitor$$ExternalSyntheticLambda0.create(Unknown Source:4)
at com.google.firebase.components.ComponentRuntime.lambda$discoverComponents$0$com-google-firebase-components-ComponentRuntime(ComponentRuntime.java:140)
at com.google.firebase.components.ComponentRuntime$$ExternalSyntheticLambda1.get(Unknown Source:4)
at com.google.firebase.components.Lazy.get(Lazy.java:53)
at com.google.firebase.components.ComponentContainer.get(ComponentContainer.java:48)
at com.google.firebase.components.ComponentContainer.get(ComponentContainer.java:24)
at com.google.firebase.components.RestrictedComponentContainer.get(RestrictedComponentContainer.java:89)
at com.google.firebase.crashlytics.CrashlyticsRegistrar.buildCrashlytics(CrashlyticsRegistrar.java:69)
at com.google.firebase.crashlytics.CrashlyticsRegistrar.$r8$lambda$Pfd5XmDCFzNyAT9o9H6rDnTBQE4(Unknown Source:0)
at com.google.firebase.crashlytics.CrashlyticsRegistrar$$ExternalSyntheticLambda0.create(Unknown Source:2)
at com.google.firebase.tracing.ComponentMonitor.lambda$processRegistrar$0(ComponentMonitor.java:38)
at com.google.firebase.tracing.ComponentMonitor$$ExternalSyntheticLambda0.create(Unknown Source:4)
at com.google.firebase.components.ComponentRuntime.lambda$discoverComponents$0$com-google-firebase-components-ComponentRuntime(ComponentRuntime.java:140)
at com.google.firebase.components.ComponentRuntime$$ExternalSyntheticLambda1.get(Unknown Source:4)
at com.google.firebase.components.Lazy.get(Lazy.java:53)
at com.google.firebase.components.ComponentRuntime.doInitializeEagerComponents(ComponentRuntime.java:302)
at com.google.firebase.components.ComponentRuntime.initializeEagerComponents(ComponentRuntime.java:292)
at com.google.firebase.FirebaseApp.initializeAllApis(FirebaseApp.java:607)
at com.google.firebase.FirebaseApp.initializeApp(FirebaseApp.java:300)
at com.google.firebase.FirebaseApp.initializeApp(FirebaseApp.java:264)
at com.google.firebase.FirebaseApp.initializeApp(FirebaseApp.java:249)
at com.oasisfeng.island.firebase.FirebaseWrapper.<clinit>(FirebaseWrapper.java:45)

see oasisfeng/island#446
missing override method com.oasisfeng.condom.PackageManagerWrapper#getApplicationInfo(String,ApplicationInfoFlags)
Island version: commit 2aab8f9d6e7ada845ecaa5fa8340180423949c30
Condom version: implementation 'com.oasisfeng.condom:library:2.5.0' in island:shared

debug模式下友盟推送初始化闪退

Caused by: java.lang.NullPointerException: Attempt to invoke interface method 'android.os.Bundle android.content.IContentProvider.call(java.lang.String, java.lang.String, java.lang.String, android.os.Bundle)' on a null object reference
at android.provider.Settings$NameValueCache.getStringForUser(Settings.java:1405)
at android.provider.Settings$Secure.getStringForUser(Settings.java:4021)
at android.provider.Settings$System.getStringForUser(Settings.java:1674)
at android.provider.Settings$System.getString(Settings.java:1664)
at com.umeng.message.common.UmengMessageDeviceConfig.getAndroidId(UmengMessageDeviceConfig.java:276)
at com.umeng.message.common.b.a(Header.java:352)
at com.umeng.message.common.b.b(Header.java:388)
at com.umeng.message.UTrack.d(UTrack.java:615)
at com.umeng.message.UTrack.(UTrack.java:87)
at com.umeng.message.UTrack.getInstance(UTrack.java:94)
at com.umeng.message.PushAgent.setAppkeyAndSecret(PushAgent.java:544)

初始化代码如下:

        mPushAgent = PushAgent.getInstance(CondomContext.wrap(context, null));
        mPushAgent.setAppkeyAndSecret(umeng_key, umeng_secret);

看报错堆栈,Settings.java有这么一段:

        private IContentProvider lazyGetProvider(ContentResolver cr) {
            IContentProvider cp = null;
            synchronized (NameValueCache.this) {
                cp = mContentProvider;
                if (cp == null) {
                    cp = mContentProvider = cr.acquireProvider(mUri.getAuthority());
                }
            }
            return cp;
        }

可能是有多线程同时访问,导致cp可能返回null。但是release版本没问题,奇怪了。把初始化代码改成:

        mPushAgent = PushAgent.getInstance(context);
        mPushAgent.setAppkeyAndSecret(umeng_key, umeng_secret);

也没问题。

//update :

	boolean shouldAllowProvider(final @Nullable ProviderInfo provider) {
		if (provider == null) return false;
		if (mBase.getPackageName().equals(provider.packageName)) return true;
		if (shouldBlockRequestTarget(OutboundType.CONTENT, null, provider.packageName)) return mDryRun;
		if (SDK_INT >= HONEYCOMB_MR1 && mExcludeStoppedPackages && (provider.applicationInfo.flags & FLAG_STOPPED) != 0) return mDryRun;
		return true;
	}

从上面代码看,condom可能有误杀系统provider的可能。在vivo机型上,com.android.providers.settings这个applicationinfo满足 (provider.applicationInfo.flags & FLAG_STOPPED) != 0这个条件,所以在acquireProvider时,返回null。
ps:之所以和release,debug版本有关,是因为友盟有一个设置 mPushAgent.setDebugMode(AppConfig.debuggable());release版本可能绕过了acquireProvider这个地方。

能否拦截第三方 SDK 访问敏感信息

冯老师好~
是这样的,小米推送SDK有一个很恶心的 ManifestChecker,会自动检查你是否按要求申请了 READ_PHONE_STATEACCESS_NETWORK_STATEACCESS_WIFI_STATEGET_TASKSVIBRATEINTERNET等权限,不在 Manifest 申请够就不给初始化,特别恶心
比如手机权限,很敏感,涉及用户隐私。
能否拦截访问 TelephonyManager 等系统服务,返回空值等操作,不让SDK拿到这些数据?
同时,高德等阿里系SDK还会向 SD 卡的 .DataStorage .UTSystemConfig 写入广告垃圾文件,导致应用背锅,能否使用安全套解决?谢谢老师
PS:我知道这个可能有点偏离 防止唤醒 这个主题,但是觉得这是很必要的。

Bugly报错java.lang.AbstractMethodError

bugly的应用升级sdk,一点更新就报错
java.lang.AbstractMethodError
abstract method "android.graphics.drawable.Drawable android.content.pm.PackageManager.getUserBadgeForDensity(android.os.UserHandle, int)"
com.tencent.bugly.beta.ui.c.void a(com.tencent.bugly.beta.download.DownloadTask)(BUGLY:103)

碰上坏坏的淫们怎么办?

坏坏的淫们如果反射拿:

  1. ActivityThread::currentApplication
  2. AppGlobals::getInitialApplication

我们是不是只能怀了....

就像坏坏的淫们在tt上扎了几个孔。

@oasisfeng

Hook sd-card access?

Since those APIs are not in Context but Environment class, some SDK requires WRITE_EXTERNAL_STORAGE permission and write casually in it, which is quite annoying.

Current consideration: use AOP technology to hook class level method calls to Environment class.
Drawback: ill-behaved SDK may hardcode sd card path...(However IOException must be cached, the app won't crash, but sdk may not function normally.)

incomplete proguard config in aar

the proguard.txt which packaged in aar was incomplete:

-dontwarn android.content.IContentProvider
-dontwarn android.content.ContentResolver
-dontwarn android.content.pm.PackageManager
-keep class com.oasisfeng.condom.**

however, the proguard config should be:

-dontwarn android.content.IContentProvider
-dontwarn android.content.ContentResolver
-dontwarn android.content.pm.PackageManager
-dontwarn android.content.pm.PackageManager$**
-dontwarn android.content.pm.IPackageDeleteObserver
-dontwarn android.content.pm.IPackageDataObserver
-dontwarn android.content.pm.IPackageStatsObserver
-dontwarn android.content.pm.KeySet
-keep class com.oasisfeng.condom.**

为什么不增加 Activity 的拦截?

我看到四大组件里,除了 Activity 都有了,这是为什么呢?
我想会不会是因为,Activity 的打开是可见的,所以没有必要拦截。
但是我遇到一个问题,有一些 SDK 的 Service,会在后台默默的开启 Activity,然后关闭掉,我想对这部分做监听和拦截,但是 CondomContext 无法被继承,因为构造方法中存在 CondomCore。

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.