Merge pull request #20 from ALEX5402/dev

3.1.0-beta android 10 fixes and facebook crash fix and Xiaomi hypros fix
This commit is contained in:
Alex
2026-01-31 12:00:58 +05:30
committed by GitHub
7 changed files with 123 additions and 28 deletions
@@ -50,6 +50,10 @@ public abstract class ClassInvocationStub implements InvocationHandler, IInjectH
@Override
public void injectHook() {
mBase = getWho();
// Skip hook if service doesn't exist on this Android version
if (mBase == null) {
return;
}
mProxyInvocation = Proxy.newProxyInstance(mBase.getClass().getClassLoader(), MethodParameterUtils.getAllInterface(mBase.getClass()), this);
if (!onlyProxy) {
inject(mBase, mProxyInvocation);
@@ -91,7 +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;
// Removed IInputMethodManagerProxy - causes ClassCastException on Android 15
/**
* updated by alex5402 on 3/30/21.
@@ -177,7 +177,7 @@ public class HookManager {
addInjector(new IMediaRouterServiceProxy());
addInjector(new IPowerManagerProxy());
addInjector(new IContextHubServiceProxy());
addInjector(new IInputMethodManagerProxy());
// Removed IInputMethodManagerProxy - causes ClassCastException on Android 15 due to queryLocalInterface returning non-IInterface proxy
addInjector(new IVibratorServiceProxy());
addInjector(new IPersistentDataBlockServiceProxy());
addInjector(AppInstrumentation.get());
@@ -60,9 +60,12 @@ public class SystemProviderStub extends ClassInvocationStub implements BContentP
if ("call".equals(methodName)) {
// Only fix AttributionSource in call() args, don't replace method name
if (args != null) {
Class<?> attributionSourceClass = BRAttributionSource.getRealClass();
for (int i = 0; i < args.length; i++) {
Object arg = args[i];
if (arg != null && arg.getClass().getName().equals(BRAttributionSource.getRealClass().getName())) {
// Check for null - AttributionSource doesn't exist on Android < S (31)
if (arg != null && attributionSourceClass != null &&
arg.getClass().getName().equals(attributionSourceClass.getName())) {
ContextCompat.fixAttributionSourceState(arg, BlackBoxCore.getHostUid());
}
}
@@ -79,8 +82,12 @@ public class SystemProviderStub extends ClassInvocationStub implements BContentP
if (!isSystemProviderAuthority(authority)) {
args[0] = BlackBoxCore.getHostPkg();
}
} else if (arg != null && arg.getClass().getName().equals(BRAttributionSource.getRealClass().getName())) {
ContextCompat.fixAttributionSourceState(arg, BlackBoxCore.getHostUid());
} else if (arg != null) {
Class<?> attrSourceClass = BRAttributionSource.getRealClass();
// Check for null - AttributionSource doesn't exist on Android < S (31)
if (attrSourceClass != null && arg.getClass().getName().equals(attrSourceClass.getName())) {
ContextCompat.fixAttributionSourceState(arg, BlackBoxCore.getHostUid());
}
}
}
return method.invoke(mBase, args);
+47 -22
View File
@@ -1,31 +1,56 @@
# Release Notes - NewBlackbox
## Version: Latest Build (2026-01-30)
## Version: Latest Build (2026-01-31)
### Major Changes
### Bug Fixes
#### 1. Removal of Xposed Framework Support
**Summary:** The Xposed module loading and management features have been completely removed from BlackBox to streamline the core and remove legacy dependencies.
**Details:**
- Removed `BXposedManagerService` and related AIDL interfaces.
- Removed "Install Xposed Module" UI and Settings entries.
- Removed Xposed enablement flags in `BlackBoxCore` and `ClientConfiguration`.
- Cleaned up `AppSystemEnv` and repositories to remove Xposed package checks.
- Removed `FLAG_XPOSED` from `InstallOption` and `USER_XPOSED` from `BUserHandle`.
#### Android 10 Black Screen Fix
**Problem:** Apps would show a black screen and timeout on Android 10 (API 29) due to initialization failures.
**Root Cause:**
- `BRAttributionSource.getRealClass()` returns `null` on Android < 31 (AttributionSource was added in Android S)
- `SystemProviderStub.invoke()` crashed calling `.getName()` on null class
- `ClassInvocationStub.injectHook()` crashed when `getWho()` returned null for non-existent services
#### 2. Anti-Detection Stability Fix
**Problem:** The native file system hooks in `AntiDetection.cpp` were causing application crashes due to infinite recursion (Hook calls logging -> Logging calls `open` -> `open` hook calls Logging).
**Solution:**
- Removed all `LOGD` calls from critical native hooks (`my_fopen`, `my_open`, `my_stat`, etc.).
- Fixed syntax errors in hook implementations.
- Hooks now silently return `ENOENT` for blocked paths without triggering recursion.
- Added null checks in `SystemProviderStub.java` before accessing `BRAttributionSource.getRealClass()`
- Added null check in `ClassInvocationStub.java` to skip hooks when services don't exist
### Technical Details
**Files Changed:**
- `Bcore/src/main/java/top/niunaijun/blackbox/fake/service/context/providers/SystemProviderStub.java`
- `Bcore/src/main/java/top/niunaijun/blackbox/fake/hook/ClassInvocationStub.java`
**Refactoring:**
- Deleted `Bcore/src/main/java/top/niunaijun/blackbox/fake/frameworks/BXposedManager.java`
- Deleted `app/src/main/java/top/niunaijun/blackboxa/view/xp` (Xposed UI)
- Fixed compilation errors in `BlackBoxCore.java` and `AppSystemEnv.java` resulting from the removal.
---
**Known Limitations:**
- **Native Signature Spoofing:** While `AntiDetection` hooks are stable, fully spoofing the APK signature at the native level (for apps that read the APK file directly) is not fully implemented. The current hooks hide blocked files but do not redirect file access to the original APK. Implementing this requires **PLT Hooking** (e.g., via xHook) and knowledge of the original APK path.
### Removed Features
#### Xposed Framework Support Removed
- Removed `BXposedManagerService` and related AIDL interfaces
- Removed "Install Xposed Module" UI and Settings entries
- Removed Xposed enablement flags in `BlackBoxCore` and `ClientConfiguration`
- Cleaned up `AppSystemEnv` and repositories to remove Xposed package checks
---
### 🔧 Stability Improvements
#### Anti-Detection Native Hook Stability
**Problem:** Native file system hooks caused crashes due to infinite recursion.
**Solution:**
- Removed `LOGD` calls from critical native hooks (`my_fopen`, `my_open`, `my_stat`, etc.)
- Fixed syntax errors in hook implementations
- Hooks now silently return `ENOENT` for blocked paths
---
### Compatibility
| Android Version | Status |
|-----------------|--------|
| Android 10 (Q) | ✅ Fixed |
| Android 11 (R) | ✅ Supported |
| Android 12 (S) | ✅ Supported |
| Android 13 (T) | ✅ Supported |
| Android 14 (U) | ✅ Supported |
| Android 15+ | ⚠️ Requires testing |
+6
View File
@@ -6,6 +6,12 @@
<uses-permission android:name="android.permission.QUERY_ALL_PACKAGES"
tools:ignore="QueryAllPackagesPermission" />
<!-- Storage permissions for Android 10 and below -->
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"
android:maxSdkVersion="29" />
<application
android:name=".app.App"
android:allowBackup="true"
@@ -37,6 +37,7 @@ class MainActivity : LoadingActivity() {
companion object {
private const val TAG = "MainActivity"
private const val STORAGE_PERMISSION_REQUEST_CODE = 1001
fun start(context: Context) {
val intent = Intent(context, MainActivity::class.java)
@@ -78,16 +79,68 @@ class MainActivity : LoadingActivity() {
private fun checkStoragePermission() {
try {
if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.R) {
// Android 11+: Need MANAGE_EXTERNAL_STORAGE
if (!android.os.Environment.isExternalStorageManager()) {
Log.w(TAG, "MANAGE_EXTERNAL_STORAGE permission not granted")
showStoragePermissionDialog()
}
} else {
// Android 10 and below: Need READ/WRITE_EXTERNAL_STORAGE
if (androidx.core.content.ContextCompat.checkSelfPermission(
this,
android.Manifest.permission.WRITE_EXTERNAL_STORAGE
) != android.content.pm.PackageManager.PERMISSION_GRANTED ||
androidx.core.content.ContextCompat.checkSelfPermission(
this,
android.Manifest.permission.READ_EXTERNAL_STORAGE
) != android.content.pm.PackageManager.PERMISSION_GRANTED
) {
Log.w(
TAG,
"Storage permissions not granted on Android ${android.os.Build.VERSION.SDK_INT}"
)
requestLegacyStoragePermission()
}
}
} catch (e: Exception) {
Log.e(TAG, "Error checking storage permission: ${e.message}")
}
}
private fun requestLegacyStoragePermission() {
try {
androidx.core.app.ActivityCompat.requestPermissions(
this,
arrayOf(
android.Manifest.permission.READ_EXTERNAL_STORAGE,
android.Manifest.permission.WRITE_EXTERNAL_STORAGE
),
STORAGE_PERMISSION_REQUEST_CODE
)
} catch (e: Exception) {
Log.e(TAG, "Error requesting storage permission: ${e.message}")
}
}
override fun onRequestPermissionsResult(
requestCode: Int,
permissions: Array<out String>,
grantResults: IntArray
) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults)
if (requestCode == STORAGE_PERMISSION_REQUEST_CODE) {
if (grantResults.isNotEmpty() &&
grantResults.all {
it == android.content.pm.PackageManager.PERMISSION_GRANTED
}
) {
Log.d(TAG, "Storage permissions granted")
} else {
Log.w(TAG, "Storage permissions denied")
}
}
}
private fun showStoragePermissionDialog() {
try {
MaterialDialog(this).show {
+1 -1
View File
@@ -11,7 +11,7 @@ ext {
// targetSdkVersion = 35
minSdk = 21
versionCode = 1
versionName = "3.0.13-beta2"
versionName = "3.1.0-beta"
xVersion = '1.1.0'
hiddenApiBypass = '4.3'
}