diff --git a/Bcore/src/main/java/top/niunaijun/blackbox/fake/hook/HookManager.java b/Bcore/src/main/java/top/niunaijun/blackbox/fake/hook/HookManager.java index b45a413..8651216 100644 --- a/Bcore/src/main/java/top/niunaijun/blackbox/fake/hook/HookManager.java +++ b/Bcore/src/main/java/top/niunaijun/blackbox/fake/hook/HookManager.java @@ -91,6 +91,7 @@ import top.niunaijun.blackbox.utils.compat.BuildCompat; import top.niunaijun.blackbox.fake.service.ISettingsProviderProxy; import top.niunaijun.blackbox.fake.service.FeatureFlagUtilsProxy; import top.niunaijun.blackbox.fake.service.WorkManagerProxy; +import top.niunaijun.blackbox.fake.service.IInputMethodManagerProxy; /** * updated by alex5402 on 3/30/21. @@ -176,6 +177,7 @@ public class HookManager { addInjector(new IMediaRouterServiceProxy()); addInjector(new IPowerManagerProxy()); addInjector(new IContextHubServiceProxy()); + addInjector(new IInputMethodManagerProxy()); addInjector(new IVibratorServiceProxy()); addInjector(new IPersistentDataBlockServiceProxy()); addInjector(AppInstrumentation.get()); diff --git a/Bcore/src/main/java/top/niunaijun/blackbox/fake/service/IActivityManagerProxy.java b/Bcore/src/main/java/top/niunaijun/blackbox/fake/service/IActivityManagerProxy.java index 8f19079..d956877 100644 --- a/Bcore/src/main/java/top/niunaijun/blackbox/fake/service/IActivityManagerProxy.java +++ b/Bcore/src/main/java/top/niunaijun/blackbox/fake/service/IActivityManagerProxy.java @@ -139,21 +139,87 @@ public class IActivityManagerProxy extends ClassInvocationStub { public static class GetContentProvider extends MethodHook { @Override protected Object hook(Object who, Method method, Object[] args) throws Throwable { - try { - // Try to use the original method first - Object result = method.invoke(who, args); - if (result != null) { - return result; + int authIndex = getAuthIndex(); + Object auth = args[authIndex]; + Object content = null; + + if (auth instanceof String) { + if (ProxyManifest.isProxy((String) auth)) { + return method.invoke(who, args); } - - // If original method fails, return null to prevent crashes - Slog.w(TAG, "getContentProvider failed, returning null to prevent crash"); - return null; - - } catch (Exception e) { - Slog.w(TAG, "Error in getContentProvider, returning null: " + e.getMessage()); - return null; + + if (BuildCompat.isQ()) { + args[1] = BlackBoxCore.getHostPkg(); + } + + if (auth.equals("settings") + || auth.equals("media") + || auth.equals("telephony") + || ((String) auth).contains("com.google.android.gms") + || ((String) auth).contains("com.android.vending") + || ((String) auth).contains("com.google.android.gsf") + || auth.equals("com.google.android.gms.chimera") + || auth.equals("com.huawei.android.launcher.settings") + || auth.equals("com.hihonor.android.launcher.settings")) { + content = method.invoke(who, args); + ContentProviderDelegate.update(content, (String) auth); + return content; + } else { + // Log.d(TAG, "hook getContentProvider: " + auth); + + ProviderInfo providerInfo = BlackBoxCore.getBPackageManager() + .resolveContentProvider( + (String) auth, GET_META_DATA, BActivityThread.getUserId()); + if (providerInfo == null) { + // Fallback removed to avoid using original Google services + return null; + } + + // Log.d(TAG, "hook app: " + auth); + IBinder providerBinder = null; + if (BActivityThread.getAppPid() != -1) { + AppConfig appConfig = BlackBoxCore.getBActivityManager() + .initProcess( + providerInfo.packageName, + providerInfo.processName, + BActivityThread.getUserId()); + if (appConfig.bPID != BActivityThread.getAppPid()) { + providerBinder = BlackBoxCore.getBActivityManager() + .acquireContentProviderClient(providerInfo); + } + args[authIndex] = ProxyManifest.getProxyAuthorities(appConfig.bPID); + args[getUserIndex()] = BlackBoxCore.getHostUserId(); + } + if (providerBinder == null) + return null; + + content = method.invoke(who, args); + Reflector.with(content).field("info").set(providerInfo); + Reflector.with(content) + .field("provider") + .set( + new ContentProviderStub() + .wrapper( + BRContentProviderNative.get().asInterface(providerBinder), + providerInfo.packageName)); + } + + return content; } + return method.invoke(who, args); + } + + protected int getAuthIndex() { + // 10.0 + if (BuildCompat.isQ()) { + return 2; + } else { + return 1; + } + } + + protected int getUserIndex() { + return getAuthIndex() + 1; } } diff --git a/Bcore/src/main/java/top/niunaijun/blackbox/fake/service/IInputMethodManagerProxy.java b/Bcore/src/main/java/top/niunaijun/blackbox/fake/service/IInputMethodManagerProxy.java new file mode 100644 index 0000000..b8eb69b --- /dev/null +++ b/Bcore/src/main/java/top/niunaijun/blackbox/fake/service/IInputMethodManagerProxy.java @@ -0,0 +1,51 @@ +package top.niunaijun.blackbox.fake.service; + +import android.content.Context; +import android.os.IBinder; + +import java.lang.reflect.Method; + +import black.android.os.BRServiceManager; +import top.niunaijun.blackbox.fake.hook.BinderInvocationStub; +import top.niunaijun.blackbox.fake.hook.MethodHook; +import top.niunaijun.blackbox.fake.hook.ProxyMethod; +import top.niunaijun.blackbox.fake.hook.ScanClass; + +/** + * Created by Milk on 2021/4/26. + * * ∧_∧ + * (`・ω・∥ + * 丶 つ0 + * しーJ + */ +@ScanClass(IInputMethodManagerProxy.class) +public class IInputMethodManagerProxy extends BinderInvocationStub { + public static final String TAG = "IInputMethodManagerProxy"; + + public IInputMethodManagerProxy() { + super(BRServiceManager.get().getService(Context.INPUT_METHOD_SERVICE)); + } + + @Override + protected Object getWho() { + return BRServiceManager.get().getService(Context.INPUT_METHOD_SERVICE); + } + + @Override + protected void inject(Object baseInvocation, Object proxyInvocation) { + replaceSystemService(Context.INPUT_METHOD_SERVICE); + } + + @Override + public boolean isBadEnv() { + return false; + } + + @ProxyMethod("startInputOrWindowGainedFocus") + public static class StartInputOrWindowGainedFocus extends MethodHook { + @Override + protected Object hook(Object who, Method method, Object[] args) throws Throwable { + return method.invoke(who, args); + } + } +} diff --git a/Bcore/src/main/java/top/niunaijun/blackbox/fake/service/WebViewProxy.java b/Bcore/src/main/java/top/niunaijun/blackbox/fake/service/WebViewProxy.java index 7fbdc59..6d697e3 100644 --- a/Bcore/src/main/java/top/niunaijun/blackbox/fake/service/WebViewProxy.java +++ b/Bcore/src/main/java/top/niunaijun/blackbox/fake/service/WebViewProxy.java @@ -28,6 +28,14 @@ public class WebViewProxy extends ClassInvocationStub { super(); } + /** + * getWho() returns null and inject() is empty because this class hooks + * instance/static methods on WebView class itself, NOT a system service binder. + * + * Unlike binder proxies (e.g., IActivityManagerProxy) that replace services + * in ServiceManager.sCache, class proxies use @ProxyMethod inner classes + * to intercept specific methods via reflection/instrumentation. + */ @Override protected Object getWho() { return null; // Not needed for class method hooks