补全缺失的hook

pull/1/head
Milk 4 years ago
parent ddec6d25eb
commit 3b1f671d61
  1. 50
      Bcore/black-fake/src/main/java/mirror/MirrorReflection.java
  2. 2
      Bcore/black-fake/src/main/java/mirror/android/app/ActivityThread.java
  3. 9
      Bcore/black-fake/src/main/java/mirror/android/app/IActivityManager.java
  4. 13
      Bcore/black-fake/src/main/java/mirror/android/app/IAlarmManager.java
  5. 13
      Bcore/black-fake/src/main/java/mirror/android/content/ContentProviderHolderOreo.java
  6. 42
      Bcore/black-fake/src/main/java/mirror/android/providers/Settings.java
  7. 4
      Bcore/src/main/java/top/niunaijun/blackbox/BlackBoxCore.java
  8. 6
      Bcore/src/main/java/top/niunaijun/blackbox/app/BActivityThread.java
  9. 91
      Bcore/src/main/java/top/niunaijun/blackbox/fake/delegate/ContentProviderDelegate.java
  10. 2
      Bcore/src/main/java/top/niunaijun/blackbox/fake/hook/HookManager.java
  11. 42
      Bcore/src/main/java/top/niunaijun/blackbox/fake/service/IActivityManagerProxy.java
  12. 51
      Bcore/src/main/java/top/niunaijun/blackbox/fake/service/IAlarmManagerProxy.java
  13. 63
      Bcore/src/main/java/top/niunaijun/blackbox/fake/service/provider/ContentProviderStub.java
  14. 59
      Bcore/src/main/java/top/niunaijun/blackbox/fake/service/provider/SettingsProviderStub.java
  15. 15
      Bcore/src/main/java/top/niunaijun/blackbox/fake/service/provider/VContentProvider.java
  16. 4
      app/src/main/java/top/niunaijun/blackdex/App.java
  17. 2
      app/src/main/java/top/niunaijun/blackdex/MainActivity.java

@ -101,6 +101,13 @@ public final class MirrorReflection {
return wrap(getConstructor(clazz, parameterTypes)); return wrap(getConstructor(clazz, parameterTypes));
} }
public <T> ConstructorWrapper<T> constructorStringClass(String... parameterTypes) {
Class<?>[] classes = new Class<?>[parameterTypes.length];
for (int i = 0; i < parameterTypes.length; i++) {
classes[i] = getClassFormString(parameterTypes[i]);
}
return constructor(classes);
}
public static Class<?> findClassOrNull(String name) { public static Class<?> findClassOrNull(String name) {
@ -395,4 +402,47 @@ public final class MirrorReflection {
} }
} }
} }
static Class<?> getClassFormString(String clazz) {
Class<?> type = getProtoType(clazz);
if (type == null) {
try {
type = Class.forName(clazz);
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
}
return type;
}
static Class<?> getProtoType(String typeName) {
if (typeName.equals("int")) {
return Integer.TYPE;
}
if (typeName.equals("long")) {
return Long.TYPE;
}
if (typeName.equals("boolean")) {
return Boolean.TYPE;
}
if (typeName.equals("byte")) {
return Byte.TYPE;
}
if (typeName.equals("short")) {
return Short.TYPE;
}
if (typeName.equals("char")) {
return Character.TYPE;
}
if (typeName.equals("float")) {
return Float.TYPE;
}
if (typeName.equals("double")) {
return Double.TYPE;
}
if (typeName.equals("void")) {
return Void.TYPE;
}
return null;
}
} }

@ -12,6 +12,7 @@ import android.content.pm.ProviderInfo;
import android.os.Handler; import android.os.Handler;
import android.os.IBinder; import android.os.IBinder;
import android.os.IInterface; import android.os.IInterface;
import android.util.ArrayMap;
import java.util.List; import java.util.List;
@ -33,6 +34,7 @@ public class ActivityThread {
public static MirrorReflection.FieldWrapper<Object> mBoundApplication = REF.field("mBoundApplication"); public static MirrorReflection.FieldWrapper<Object> mBoundApplication = REF.field("mBoundApplication");
public static MirrorReflection.FieldWrapper<Handler> mH = REF.field("mH"); public static MirrorReflection.FieldWrapper<Handler> mH = REF.field("mH");
public static MirrorReflection.FieldWrapper<Application> mInitialApplication = REF.field("mInitialApplication"); public static MirrorReflection.FieldWrapper<Application> mInitialApplication = REF.field("mInitialApplication");
public static MirrorReflection.FieldWrapper<ArrayMap<Object, Object>> mProviderMap = REF.field("mProviderMap");
public static MirrorReflection.FieldWrapper<Instrumentation> mInstrumentation = REF.field("mInstrumentation"); public static MirrorReflection.FieldWrapper<Instrumentation> mInstrumentation = REF.field("mInstrumentation");
public static MirrorReflection.FieldWrapper<IInterface> sPackageManager = REF.field("sPackageManager"); public static MirrorReflection.FieldWrapper<IInterface> sPackageManager = REF.field("sPackageManager");
public static MirrorReflection.MethodWrapper<IBinder> getApplicationThread = REF.method("getApplicationThread"); public static MirrorReflection.MethodWrapper<IBinder> getApplicationThread = REF.method("getApplicationThread");

@ -1,9 +1,18 @@
package mirror.android.app; package mirror.android.app;
import android.content.pm.ProviderInfo;
import android.os.IInterface;
import mirror.MirrorReflection; import mirror.MirrorReflection;
public class IActivityManager { public class IActivityManager {
public static final MirrorReflection REF = MirrorReflection.on("android.app.IActivityManager"); public static final MirrorReflection REF = MirrorReflection.on("android.app.IActivityManager");
public static MirrorReflection.MethodWrapper<Integer> startActivity = REF.method("startActivity"); public static MirrorReflection.MethodWrapper<Integer> startActivity = REF.method("startActivity");
public static class ContentProviderHolder {
public static final MirrorReflection REF = MirrorReflection.on("android.app.IActivityManager$ContentProviderHolder");
public static MirrorReflection.FieldWrapper<ProviderInfo> info = REF.field("info");
public static MirrorReflection.FieldWrapper<IInterface> provider = REF.field("provider");
}
} }

@ -0,0 +1,13 @@
package mirror.android.app;
import android.os.IBinder;
import android.os.IInterface;
import mirror.MirrorReflection;
public class IAlarmManager {
public static class Stub {
public static final MirrorReflection REF = MirrorReflection.on("android.app.IAlarmManager$Stub");
public static MirrorReflection.StaticMethodWrapper<IInterface> asInterface = REF.staticMethod("asInterface", IBinder.class);
}
}

@ -0,0 +1,13 @@
package mirror.android.content;
import android.content.pm.ProviderInfo;
import android.os.IInterface;
import mirror.MirrorReflection;
public class ContentProviderHolderOreo {
public static final MirrorReflection REF = MirrorReflection.on("android.app.ContentProviderHolder");
public static MirrorReflection.FieldWrapper<ProviderInfo> info = REF.field("info");
public static MirrorReflection.FieldWrapper<IInterface> provider = REF.field("provider");
}

@ -0,0 +1,42 @@
package mirror.android.providers;
import android.annotation.TargetApi;
import android.os.Build;
import android.os.IInterface;
import mirror.MirrorReflection;
public class Settings {
@TargetApi(Build.VERSION_CODES.JELLY_BEAN_MR1)
public static class Global {
public static final MirrorReflection REF = MirrorReflection.on(android.provider.Settings.Global.class);
public static MirrorReflection.FieldWrapper<Object> sNameValueCache = REF.field("sNameValueCache");
}
public static class NameValueCache {
public static final MirrorReflection REF = MirrorReflection.on("android.provider.Settings$NameValueCache");
public static MirrorReflection.FieldWrapper<Object> mContentProvider = REF.field("mContentProvider");
}
public static class NameValueCacheOreo {
public static final MirrorReflection REF = MirrorReflection.on("android.provider.Settings$NameValueCache");
public static MirrorReflection.FieldWrapper<Object> mProviderHolder = REF.field("mProviderHolder");
}
public static class ContentProviderHolder {
public static final MirrorReflection REF = MirrorReflection.on("android.provider.Settings$ContentProviderHolder");
public static MirrorReflection.FieldWrapper<IInterface> mContentProvider = REF.field("mContentProvider");
}
public static class Secure {
public static final MirrorReflection REF = MirrorReflection.on(android.provider.Settings.Secure.class);
public static MirrorReflection.FieldWrapper<Object> sNameValueCache = REF.field("sNameValueCache");
}
public static class System {
public static final MirrorReflection REF = MirrorReflection.on(android.provider.Settings.System.class);
public static MirrorReflection.FieldWrapper<Object> sNameValueCache = REF.field("sNameValueCache");
}
}

@ -14,6 +14,7 @@ import android.os.IBinder;
import android.os.Process; import android.os.Process;
import top.niunaijun.blackbox.app.configuration.ClientConfiguration; import top.niunaijun.blackbox.app.configuration.ClientConfiguration;
import top.niunaijun.blackbox.fake.delegate.ContentProviderDelegate;
import top.niunaijun.blackbox.fake.frameworks.BDumpManager; import top.niunaijun.blackbox.fake.frameworks.BDumpManager;
import top.niunaijun.blackbox.proxy.ProxyManifest; import top.niunaijun.blackbox.proxy.ProxyManifest;
import top.niunaijun.blackbox.app.configuration.AppLifecycleCallback; import top.niunaijun.blackbox.app.configuration.AppLifecycleCallback;
@ -110,6 +111,9 @@ public class BlackBoxCore extends ClientConfiguration {
} }
public void doCreate() { public void doCreate() {
if (isVirtualProcess()) {
ContentProviderDelegate.init();
}
if (!isServerProcess()) { if (!isServerProcess()) {
initService(); initService();
} }

@ -14,6 +14,7 @@ import android.os.Handler;
import android.os.IBinder; import android.os.IBinder;
import android.os.Looper; import android.os.Looper;
import android.os.Process; import android.os.Process;
import android.util.Log;
import java.io.File; import java.io.File;
import java.util.ArrayList; import java.util.ArrayList;
@ -183,12 +184,11 @@ public class BActivityThread extends IBActivityThread.Stub {
Application application = null; Application application = null;
BlackBoxCore.get().getAppLifecycleCallback().beforeCreateApplication(packageName, processName, packageContext); BlackBoxCore.get().getAppLifecycleCallback().beforeCreateApplication(packageName, processName, packageContext);
try { try {
application = LoadedApk.makeApplication.call(loadedApk, false, null); application = LoadedApk.makeApplication.call(loadedApk, false, null);
} catch (Throwable e) { } catch (Throwable e) {
Slog.e(TAG, "Unable to makeApplication"); // Slog.e(TAG, "Unable to makeApplication");
e.printStackTrace(); // e.printStackTrace();
} }
mInitialApplication = application; mInitialApplication = application;
if (Objects.equals(packageName, processName)) { if (Objects.equals(packageName, processName)) {

@ -0,0 +1,91 @@
package top.niunaijun.blackbox.fake.delegate;
import android.net.Uri;
import android.os.Build;
import android.os.IInterface;
import java.lang.reflect.Proxy;
import java.util.HashSet;
import java.util.Set;
import mirror.android.app.IActivityManager;
import mirror.android.content.ContentProviderHolderOreo;
import mirror.android.providers.Settings;
import top.niunaijun.blackbox.BlackBoxCore;
import top.niunaijun.blackbox.fake.service.provider.ContentProviderStub;
import top.niunaijun.blackbox.fake.service.provider.SettingsProviderStub;
import top.niunaijun.blackbox.utils.compat.BuildCompat;
/**
* Created by Milk on 3/31/21.
* * _
* (`ω
*  つ0
* しーJ
* 此处无Bug
*/
public class ContentProviderDelegate {
public static final String TAG = "ContentProviderDelegate";
private static Set<String> sInjected = new HashSet<>();
public static void update(Object holder, String auth) {
IInterface iInterface;
if (BuildCompat.isOreo()) {
iInterface = ContentProviderHolderOreo.provider.get(holder);
} else {
iInterface = IActivityManager.ContentProviderHolder.provider.get(holder);
}
if (iInterface instanceof Proxy)
return;
IInterface vContentProvider;
switch (auth) {
case "settings":
vContentProvider = new SettingsProviderStub().wrapper(iInterface, BlackBoxCore.getHostPkg());
break;
default:
vContentProvider = new ContentProviderStub().wrapper(iInterface, BlackBoxCore.getHostPkg());
break;
}
if (BuildCompat.isOreo()) {
ContentProviderHolderOreo.provider.set(holder, vContentProvider);
} else {
IActivityManager.ContentProviderHolder.provider.set(holder, vContentProvider);
}
}
public static void init() {
clearSettingProvider();
BlackBoxCore.getContext().getContentResolver().call(Uri.parse("content://settings"), "", null, null);
}
public static void clearSettingProvider() {
Object cache;
cache = Settings.System.sNameValueCache.get();
if (cache != null) {
clearContentProvider(cache);
}
cache = Settings.Secure.sNameValueCache.get();
if (cache != null) {
clearContentProvider(cache);
}
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1 && Settings.Global.REF.getClazz() != null) {
cache = Settings.Global.sNameValueCache.get();
if (cache != null) {
clearContentProvider(cache);
}
}
}
private static void clearContentProvider(Object cache) {
if (BuildCompat.isOreo()) {
Object holder = Settings.NameValueCacheOreo.mProviderHolder.get(cache);
if (holder != null) {
Settings.ContentProviderHolder.mContentProvider.set(holder, null);
}
} else {
Settings.NameValueCache.mContentProvider.set(cache, null);
}
}
}

@ -8,6 +8,7 @@ import java.util.Map;
import top.niunaijun.blackbox.fake.service.IActivityManagerProxy; import top.niunaijun.blackbox.fake.service.IActivityManagerProxy;
import top.niunaijun.blackbox.fake.service.IActivityTaskManagerProxy; import top.niunaijun.blackbox.fake.service.IActivityTaskManagerProxy;
import top.niunaijun.blackbox.fake.service.HCallbackProxy; import top.niunaijun.blackbox.fake.service.HCallbackProxy;
import top.niunaijun.blackbox.fake.service.IAlarmManagerProxy;
import top.niunaijun.blackbox.fake.service.IAppOpsManagerProxy; import top.niunaijun.blackbox.fake.service.IAppOpsManagerProxy;
import top.niunaijun.blackbox.fake.service.IJobServiceProxy; import top.niunaijun.blackbox.fake.service.IJobServiceProxy;
import top.niunaijun.blackbox.fake.service.ITelephonyRegistryProxy; import top.niunaijun.blackbox.fake.service.ITelephonyRegistryProxy;
@ -48,6 +49,7 @@ public class HookManager {
addInjector(new ITelephonyManagerProxy()); addInjector(new ITelephonyManagerProxy());
addInjector(new HCallbackProxy()); addInjector(new HCallbackProxy());
addInjector(new IAppOpsManagerProxy()); addInjector(new IAppOpsManagerProxy());
addInjector(new IAlarmManagerProxy());
addInjector(new IStorageManagerProxy()); addInjector(new IStorageManagerProxy());
addInjector(new ILauncherAppsProxy()); addInjector(new ILauncherAppsProxy());
addInjector(new IJobServiceProxy()); addInjector(new IJobServiceProxy());

@ -1,14 +1,18 @@
package top.niunaijun.blackbox.fake.service; package top.niunaijun.blackbox.fake.service;
import java.lang.reflect.Method; import java.lang.reflect.Method;
import mirror.android.app.ActivityManagerNative; import mirror.android.app.ActivityManagerNative;
import mirror.android.app.ActivityManagerOreo; import mirror.android.app.ActivityManagerOreo;
import mirror.android.util.Singleton; import mirror.android.util.Singleton;
import top.niunaijun.blackbox.BlackBoxCore;
import top.niunaijun.blackbox.fake.delegate.ContentProviderDelegate;
import top.niunaijun.blackbox.fake.hook.ProxyMethod; import top.niunaijun.blackbox.fake.hook.ProxyMethod;
import top.niunaijun.blackbox.fake.hook.ScanClass; import top.niunaijun.blackbox.fake.hook.ScanClass;
import top.niunaijun.blackbox.fake.hook.ClassInvocationStub; import top.niunaijun.blackbox.fake.hook.ClassInvocationStub;
import top.niunaijun.blackbox.fake.hook.MethodHook; import top.niunaijun.blackbox.fake.hook.MethodHook;
import top.niunaijun.blackbox.proxy.ProxyManifest;
import top.niunaijun.blackbox.utils.compat.BuildCompat; import top.niunaijun.blackbox.utils.compat.BuildCompat;
@ -51,6 +55,42 @@ public class IActivityManagerProxy extends ClassInvocationStub {
return false; return false;
} }
@ProxyMethod(name = "getContentProvider")
public static class GetContentProvider extends MethodHook {
@Override
protected Object hook(Object who, Method method, Object[] args) throws Throwable {
int authIndex = getAuthIndex();
Object auth = args[authIndex];
if (auth instanceof String) {
if (ProxyManifest.isProxy((String) auth)) {
return method.invoke(who, args);
}
if (BuildCompat.isQ()) {
args[1] = BlackBoxCore.getHostPkg();
}
if (auth.equals("settings") || auth.equals("media") || auth.equals("telephony")) {
Object content = method.invoke(who, args);
ContentProviderDelegate.update(content, (String) auth);
return content;
}
}
return method.invoke(who, args);
}
private int getAuthIndex() {
// 10.0
if (BuildCompat.isQ()) {
return 2;
} else {
return 1;
}
}
}
@ProxyMethod(name = "startService") @ProxyMethod(name = "startService")
public static class StartService extends MethodHook { public static class StartService extends MethodHook {
@Override @Override
@ -100,7 +140,7 @@ public class IActivityManagerProxy extends ClassInvocationStub {
public static class GetIntentSender extends MethodHook { public static class GetIntentSender extends MethodHook {
@Override @Override
protected Object hook(Object who, Method method, Object[] args) throws Throwable { protected Object hook(Object who, Method method, Object[] args) throws Throwable {
return 0; return null;
} }
} }

@ -0,0 +1,51 @@
package top.niunaijun.blackbox.fake.service;
import android.content.Context;
import java.lang.reflect.Method;
import mirror.android.app.IAlarmManager;
import mirror.android.os.ServiceManager;
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.utils.MethodParameterUtils;
/**
* Created by Milk on 4/3/21.
* * _
* (`ω
*  つ0
* しーJ
* 此处无Bug
*/
public class IAlarmManagerProxy extends BinderInvocationStub {
public IAlarmManagerProxy() {
super(ServiceManager.getService.call(Context.ALARM_SERVICE));
}
@Override
protected Object getWho() {
return IAlarmManager.Stub.asInterface.call(ServiceManager.getService.call(Context.ALARM_SERVICE));
}
@Override
protected void inject(Object baseInvocation, Object proxyInvocation) {
replaceSystemService(Context.ALARM_SERVICE);
}
@ProxyMethod(name = "set")
public static class Set extends MethodHook {
@Override
protected Object hook(Object who, Method method, Object[] args) throws Throwable {
MethodParameterUtils.replaceFirstAppPkg(args);
return method.invoke(who, args);
}
}
@Override
public boolean isBadEnv() {
return false;
}
}

@ -0,0 +1,63 @@
package top.niunaijun.blackbox.fake.service.provider;
import android.os.IInterface;
import java.lang.reflect.Method;
import top.niunaijun.blackbox.BlackBoxCore;
import top.niunaijun.blackbox.fake.hook.ClassInvocationStub;
/**
* Created by Milk on 4/8/21.
* * _
* (`ω
*  つ0
* しーJ
* 此处无Bug
*/
public class ContentProviderStub extends ClassInvocationStub implements VContentProvider {
public static final String TAG = "ContentProviderStub";
private IInterface mBase;
public IInterface wrapper(final IInterface contentProviderProxy, final String appPkg) {
mBase = contentProviderProxy;
injectHook();
return (IInterface) getProxyInvocation();
}
@Override
protected Object getWho() {
return mBase;
}
@Override
protected void inject(Object baseInvocation, Object proxyInvocation) {
}
@Override
protected void onBindMethod() {
}
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
if ("asBinder".equals(method.getName())) {
return method.invoke(mBase, args);
}
if (args != null && args.length > 0 && args[0] instanceof String) {
String pkg = (String) args[0];
args[0] = BlackBoxCore.getHostPkg();
}
try {
return method.invoke(mBase, args);
} catch (Throwable e) {
throw e.getCause();
}
}
@Override
public boolean isBadEnv() {
return false;
}
}

@ -0,0 +1,59 @@
package top.niunaijun.blackbox.fake.service.provider;
import android.os.IInterface;
import java.lang.reflect.Method;
import top.niunaijun.blackbox.BlackBoxCore;
import top.niunaijun.blackbox.fake.hook.ClassInvocationStub;
/**
* Created by Milk on 4/8/21.
* * _
* (`ω
*  つ0
* しーJ
* 此处无Bug
*/
public class SettingsProviderStub extends ClassInvocationStub implements VContentProvider {
private IInterface mBase;
@Override
public IInterface wrapper(IInterface contentProviderProxy, String appPkg) {
mBase = contentProviderProxy;
injectHook();
return (IInterface) getProxyInvocation();
}
@Override
protected Object getWho() {
return mBase;
}
@Override
protected void inject(Object baseInvocation, Object proxyInvocation) {
}
@Override
protected void onBindMethod() {
}
@Override
public boolean isBadEnv() {
return false;
}
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
if ("asBinder".equals(method.getName())) {
return method.invoke(mBase, args);
}
if (args != null && args.length > 0 && args[0] instanceof String) {
String pkg = (String) args[0];
args[0] = BlackBoxCore.getHostPkg();
}
return method.invoke(mBase, args);
}
}

@ -0,0 +1,15 @@
package top.niunaijun.blackbox.fake.service.provider;
import android.os.IInterface;
/**
* Created by Milk on 4/8/21.
* * _
* (`ω
*  つ0
* しーJ
* 此处无Bug
*/
public interface VContentProvider {
IInterface wrapper(final IInterface contentProviderProxy, final String appPkg);
}

@ -3,6 +3,8 @@ package top.niunaijun.blackdex;
import android.app.Application; import android.app.Application;
import android.content.Context; import android.content.Context;
import java.io.File;
import top.niunaijun.blackbox.BlackDexCore; import top.niunaijun.blackbox.BlackDexCore;
import top.niunaijun.blackbox.app.configuration.ClientConfiguration; import top.niunaijun.blackbox.app.configuration.ClientConfiguration;
@ -18,7 +20,7 @@ public class App extends Application {
@Override @Override
protected void attachBaseContext(Context base) { protected void attachBaseContext(Context base) {
super.attachBaseContext(base); super.attachBaseContext(base);
String dir = base.getExternalCacheDir().getParent(); String dir = new File(base.getExternalCacheDir().getParent(), "dump").getAbsolutePath();
BlackDexCore.get().doAttachBaseContext(base, new ClientConfiguration() { BlackDexCore.get().doAttachBaseContext(base, new ClientConfiguration() {
@Override @Override
public String getHostPackageName() { public String getHostPackageName() {

@ -23,7 +23,7 @@ public class MainActivity extends AppCompatActivity {
findViewById(R.id.btn_click).setOnClickListener(v -> { findViewById(R.id.btn_click).setOnClickListener(v -> {
// 此方法会阻塞 // 此方法会阻塞
boolean b = BlackDexCore.get().dumpDex(new File("/sdcard/huluxia.apk")); boolean b = BlackDexCore.get().dumpDex("com.hicorenational.antifraud");
if (!b) { if (!b) {
Log.d(TAG, "dumpDex: error."); Log.d(TAG, "dumpDex: error.");
} }

Loading…
Cancel
Save