mirror of
https://github.com/QM4RS/FridaBox.git
synced 2026-10-09 01:12:18 +02:00
259 lines
8.5 KiB
Markdown
259 lines
8.5 KiB
Markdown
# Real-World APK Path Fix
|
|
|
|
## Problem Analysis
|
|
|
|
The previous fallback paths were using simplified formats that don't match the actual APK installation structure on modern Android devices. The real APK paths use a complex hash-based directory structure:
|
|
|
|
**Example Real Path:**
|
|
```
|
|
/data/app/~~LqmY0IHlKQJtJ6Cih1C6jA==/com.linkedin.android-G8hAJLQTgTz1gJ0rAUxcqA==/base.apk
|
|
```
|
|
|
|
**Previous Incorrect Paths:**
|
|
```
|
|
/data/app/com.twitter.android-1/base.apk ❌ (Doesn't exist)
|
|
```
|
|
|
|
## Issues Identified
|
|
|
|
1. **Incorrect Path Format**: Using simplified paths that don't match real Android APK installation structure
|
|
2. **Missing Hash Directories**: Not accounting for the `~~hash==` directory structure
|
|
3. **Missing Package Hashes**: Not accounting for package-specific hash suffixes
|
|
4. **Limited Path Discovery**: Only checking a few basic paths
|
|
5. **No Dynamic Discovery**: Not searching through actual directory structures
|
|
|
|
## Real-World APK Path Structure
|
|
|
|
### Modern Android APK Installation Format
|
|
```
|
|
/data/app/~~{INSTALL_HASH}==/{PACKAGE_NAME}-{PACKAGE_HASH}==/base.apk
|
|
```
|
|
|
|
**Components:**
|
|
- `~~{INSTALL_HASH}==` - Installation session hash (e.g., `~~LqmY0IHlKQJtJ6Cih1C6jA==`)
|
|
- `{PACKAGE_NAME}-{PACKAGE_HASH}==` - Package name with unique hash (e.g., `com.linkedin.android-G8hAJLQTgTz1gJ0rAUxcqA==`)
|
|
- `base.apk` - The actual APK file
|
|
|
|
### Legacy Paths (Still Used)
|
|
```
|
|
/data/app/{PACKAGE_NAME}-{VERSION}/base.apk
|
|
/data/app/{PACKAGE_NAME}/base.apk
|
|
```
|
|
|
|
### System Paths
|
|
```
|
|
/system/app/{PACKAGE_NAME}.apk
|
|
/system/priv-app/{PACKAGE_NAME}.apk
|
|
/system_ext/app/{PACKAGE_NAME}.apk
|
|
/product/app/{PACKAGE_NAME}.apk
|
|
/vendor/app/{PACKAGE_NAME}.apk
|
|
```
|
|
|
|
## Fixes Implemented
|
|
|
|
### 1. Enhanced Path Discovery (`BPackageManager.java`)
|
|
|
|
**Updated `findActualApkPath` method with real-world paths:**
|
|
|
|
```java
|
|
private String findActualApkPath(String packageName) {
|
|
if (sIsFindingApkPath) {
|
|
Log.w(TAG, "findActualApkPath called recursively, returning null to prevent infinite loop.");
|
|
return null;
|
|
}
|
|
sIsFindingApkPath = true;
|
|
try {
|
|
// Skip PackageManager call to prevent infinite recursion
|
|
Log.d(TAG, "Skipping PackageManager call to prevent recursion for " + packageName);
|
|
|
|
// Try common paths including real-world hash-based paths
|
|
String[] commonPaths = {
|
|
// Real-world hash-based paths (most common)
|
|
"/data/app/~~*/" + packageName + "-*/base.apk",
|
|
"/data/app/~~*/" + packageName + "*/base.apk",
|
|
|
|
// Legacy paths
|
|
"/data/app/" + packageName + "-1/base.apk",
|
|
"/data/app/" + packageName + "-2/base.apk",
|
|
"/data/app/" + packageName + "/base.apk",
|
|
|
|
// System paths
|
|
"/system/app/" + packageName + ".apk",
|
|
"/system/priv-app/" + packageName + ".apk",
|
|
"/system_ext/app/" + packageName + ".apk",
|
|
"/product/app/" + packageName + ".apk",
|
|
"/vendor/app/" + packageName + ".apk"
|
|
};
|
|
|
|
// First try exact path matching
|
|
for (String path : commonPaths) {
|
|
if (isValidApkPath(path)) {
|
|
Log.d(TAG, "Found existing APK at: " + path);
|
|
return path;
|
|
}
|
|
}
|
|
|
|
// If exact paths don't work, try to find hash-based paths dynamically
|
|
String hashBasedPath = findHashBasedApkPath(packageName);
|
|
if (hashBasedPath != null) {
|
|
Log.d(TAG, "Found hash-based APK at: " + hashBasedPath);
|
|
return hashBasedPath;
|
|
}
|
|
|
|
Log.w(TAG, "No existing APK found for " + packageName + ", using null path");
|
|
return null;
|
|
} finally {
|
|
sIsFindingApkPath = false; // Reset flag
|
|
}
|
|
}
|
|
```
|
|
|
|
### 2. Dynamic Hash-Based Path Discovery (`BPackageManager.java`)
|
|
|
|
**Added `findHashBasedApkPath` method for real-world path discovery:**
|
|
|
|
```java
|
|
private String findHashBasedApkPath(String packageName) {
|
|
try {
|
|
File dataAppDir = new File("/data/app");
|
|
if (!dataAppDir.exists() || !dataAppDir.isDirectory()) {
|
|
return null;
|
|
}
|
|
|
|
// Look for hash directories (~~hash==)
|
|
File[] hashDirs = dataAppDir.listFiles((dir, name) -> name.startsWith("~~") && name.endsWith("=="));
|
|
if (hashDirs == null) {
|
|
return null;
|
|
}
|
|
|
|
for (File hashDir : hashDirs) {
|
|
if (!hashDir.isDirectory()) {
|
|
continue;
|
|
}
|
|
|
|
// Look for package directories within hash directories
|
|
File[] packageDirs = hashDir.listFiles((dir, name) -> name.startsWith(packageName));
|
|
if (packageDirs == null) {
|
|
continue;
|
|
}
|
|
|
|
for (File packageDir : packageDirs) {
|
|
if (!packageDir.isDirectory()) {
|
|
continue;
|
|
}
|
|
|
|
// Look for base.apk within package directory
|
|
File baseApk = new File(packageDir, "base.apk");
|
|
if (isValidApkPath(baseApk.getAbsolutePath())) {
|
|
return baseApk.getAbsolutePath();
|
|
}
|
|
}
|
|
}
|
|
} catch (Exception e) {
|
|
Log.d(TAG, "Error searching for hash-based APK path for " + packageName + ": " + e.getMessage());
|
|
}
|
|
|
|
return null;
|
|
}
|
|
```
|
|
|
|
### 3. Enhanced Path Validation (`BPackageManager.java`)
|
|
|
|
**Updated `isValidApkPath` to handle wildcard patterns:**
|
|
|
|
```java
|
|
private boolean isValidApkPath(String path) {
|
|
try {
|
|
// Skip wildcard patterns - they need to be resolved first
|
|
if (path.contains("*")) {
|
|
return false;
|
|
}
|
|
|
|
File apkFile = new File(path);
|
|
if (!apkFile.exists()) {
|
|
return false;
|
|
}
|
|
|
|
// Additional validation: check if it's readable and has reasonable size
|
|
if (!apkFile.canRead()) {
|
|
Log.d(TAG, "APK file not readable: " + path);
|
|
return false;
|
|
}
|
|
|
|
long fileSize = apkFile.length();
|
|
if (fileSize < 1024) { // Less than 1KB is probably not a valid APK
|
|
Log.d(TAG, "APK file too small: " + path + " (size: " + fileSize + ")");
|
|
return false;
|
|
}
|
|
|
|
return true;
|
|
} catch (Exception e) {
|
|
Log.d(TAG, "Error checking APK path " + path + ": " + e.getMessage());
|
|
return false;
|
|
}
|
|
}
|
|
```
|
|
|
|
## Key Changes Made
|
|
|
|
### 1. **Real-World Path Patterns**
|
|
- Added hash-based directory patterns (`~~hash==`)
|
|
- Added package hash patterns (`package-hash==`)
|
|
- Included all system partition paths
|
|
- Added legacy path support
|
|
|
|
### 2. **Dynamic Path Discovery**
|
|
- Scan `/data/app` directory for hash directories
|
|
- Search within hash directories for package directories
|
|
- Find `base.apk` files within package directories
|
|
- Handle multiple installation sessions
|
|
|
|
### 3. **Enhanced Validation**
|
|
- Skip wildcard patterns that need resolution
|
|
- Validate file existence, readability, and size
|
|
- Comprehensive error handling
|
|
- Detailed logging for debugging
|
|
|
|
### 4. **Comprehensive Path Coverage**
|
|
- Modern hash-based paths (most common)
|
|
- Legacy version-based paths
|
|
- All system partition paths
|
|
- Dynamic discovery for unknown patterns
|
|
|
|
## Expected Results
|
|
|
|
After implementing these fixes, the app should:
|
|
|
|
✅ **Find real APK paths** using hash-based directory structure
|
|
✅ **Handle modern Android installations** correctly
|
|
✅ **Support legacy installations** for older devices
|
|
✅ **Discover APKs dynamically** when exact paths are unknown
|
|
✅ **Validate APK files** before using them
|
|
✅ **Provide detailed logging** for path discovery
|
|
|
|
## Testing Recommendations
|
|
|
|
1. **Test on modern Android devices** (Android 10+)
|
|
2. **Test on legacy devices** (Android 9 and below)
|
|
3. **Monitor logcat** for path discovery messages
|
|
4. **Test with different APK installation methods**
|
|
5. **Verify hash-based path discovery** works correctly
|
|
6. **Test with system apps** in different partitions
|
|
|
|
## Additional Notes
|
|
|
|
- The fix supports both modern and legacy APK installation formats
|
|
- Dynamic discovery handles unknown hash patterns
|
|
- Enhanced validation prevents using invalid APK files
|
|
- Comprehensive logging helps with debugging path issues
|
|
- The solution is backward compatible with older Android versions
|
|
|
|
## Build Instructions
|
|
|
|
1. Clean and rebuild the project in Android Studio
|
|
2. Test app startup on the target device
|
|
3. Monitor logcat for path discovery messages
|
|
4. Verify that real APK paths are found correctly
|
|
|
|
The comprehensive real-world APK path discovery implemented should resolve the path issues and allow the app to find actual APK files on modern Android devices.
|