Fix dex2oat crash on Android 10 due to architecture mismatch (#521)
Previously, the daemon determined the architecture of the target `dex2oat` binary based on its own process architecture (`Process.is64Bit()`). On Android 10, `/apex/com.android.runtime/bin/dex2oat` is frequently a 32-bit binary, even on 64-bit devices. This caused the daemon to incorrectly treat the target as 64-bit and mount the 64-bit wrapper (`bin/dex2oat64`). Consequently, the wrapper attempted to execute the 32-bit binary using `linker64`, resulting in a crash: `error: "/apex/.../dex2oat" is 32-bit instead of 64-bit` This commit changes the logic to inspect the ELF header of the target binary. We now explicitly check `e_ident[EI_CLASS]` to determine if the file is 32-bit or 64-bit and assign it to the correct mounting slot. This ensures the 32-bit wrapper is mounted over 32-bit targets, preventing the linker mismatch.
This commit is contained in:
parent
1436f692fb
commit
047ad98c65
|
|
@ -40,6 +40,7 @@ import androidx.annotation.RequiresApi;
|
|||
|
||||
import java.io.File;
|
||||
import java.io.FileDescriptor;
|
||||
import java.io.FileInputStream;
|
||||
import java.io.IOException;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Paths;
|
||||
|
|
@ -67,15 +68,74 @@ public class Dex2OatService implements Runnable {
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks the ELF header of the target file.
|
||||
* If 32-bit -> Assigns to Index 0 (Release) or 1 (Debug).
|
||||
* If 64-bit -> Assigns to Index 2 (Release) or 3 (Debug).
|
||||
*/
|
||||
private void checkAndAddDex2Oat(String path) {
|
||||
if (path == null)
|
||||
return;
|
||||
File file = new File(path);
|
||||
if (!file.exists())
|
||||
return;
|
||||
|
||||
try (FileInputStream fis = new FileInputStream(file)) {
|
||||
byte[] header = new byte[5];
|
||||
if (fis.read(header) != 5)
|
||||
return;
|
||||
|
||||
// 1. Verify ELF Magic: 0x7F 'E' 'L' 'F'
|
||||
if (header[0] != 0x7F || header[1] != 'E' || header[2] != 'L' || header[3] != 'F') {
|
||||
return;
|
||||
}
|
||||
|
||||
// 2. Check Architecture (header[4]): 1 = 32-bit, 2 = 64-bit
|
||||
boolean is32Bit = (header[4] == 1);
|
||||
boolean is64Bit = (header[4] == 2);
|
||||
boolean isDebug = path.contains("dex2oatd");
|
||||
|
||||
int index = -1;
|
||||
|
||||
if (is32Bit) {
|
||||
index = isDebug ? 1 : 0; // Index 0/1 maps to r32/d32 in C++
|
||||
} else if (is64Bit) {
|
||||
index = isDebug ? 3 : 2; // Index 2/3 maps to r64/d64 in C++
|
||||
}
|
||||
|
||||
// 3. Assign to the detected slot
|
||||
if (index != -1 && dex2oatArray[index] == null) {
|
||||
dex2oatArray[index] = path;
|
||||
try {
|
||||
// Open the FD for the wrapper to use later
|
||||
fdArray[index] = Os.open(path, OsConstants.O_RDONLY, 0);
|
||||
Log.i(TAG, "Detected " + path + " as " + (is64Bit ? "64-bit" : "32-bit") + " -> Assigned Index "
|
||||
+ index);
|
||||
} catch (ErrnoException e) {
|
||||
Log.e(TAG, "Failed to open FD for " + path, e);
|
||||
dex2oatArray[index] = null;
|
||||
}
|
||||
}
|
||||
} catch (IOException e) {
|
||||
// File not readable, skip
|
||||
}
|
||||
}
|
||||
|
||||
public Dex2OatService() {
|
||||
if (Build.VERSION.SDK_INT == Build.VERSION_CODES.Q) {
|
||||
openDex2oat(Process.is64Bit() ? 2 : 0, "/apex/com.android.runtime/bin/dex2oat");
|
||||
openDex2oat(Process.is64Bit() ? 3 : 1, "/apex/com.android.runtime/bin/dex2oatd");
|
||||
// Android 10: Check the standard path.
|
||||
// Logic will detect if it is 32-bit and put it in Index 0.
|
||||
checkAndAddDex2Oat("/apex/com.android.runtime/bin/dex2oat");
|
||||
checkAndAddDex2Oat("/apex/com.android.runtime/bin/dex2oatd");
|
||||
|
||||
// Check for explicit 64-bit paths (just in case)
|
||||
checkAndAddDex2Oat("/apex/com.android.runtime/bin/dex2oat64");
|
||||
checkAndAddDex2Oat("/apex/com.android.runtime/bin/dex2oatd64");
|
||||
} else {
|
||||
openDex2oat(0, "/apex/com.android.art/bin/dex2oat32");
|
||||
openDex2oat(1, "/apex/com.android.art/bin/dex2oatd32");
|
||||
openDex2oat(2, "/apex/com.android.art/bin/dex2oat64");
|
||||
openDex2oat(3, "/apex/com.android.art/bin/dex2oatd64");
|
||||
checkAndAddDex2Oat("/apex/com.android.art/bin/dex2oat32");
|
||||
checkAndAddDex2Oat("/apex/com.android.art/bin/dex2oatd32");
|
||||
checkAndAddDex2Oat("/apex/com.android.art/bin/dex2oat64");
|
||||
checkAndAddDex2Oat("/apex/com.android.art/bin/dex2oatd64");
|
||||
}
|
||||
|
||||
openDex2oat(4, "/data/adb/modules/zygisk_lsposed/bin/liboat_hook32.so");
|
||||
|
|
|
|||
Loading…
Reference in New Issue