Tencent/tinker · error · IOException
bad elf magic: %x %x %x %x.
Error message
bad elf magic: %x %x %x %x.
What it means
While parsing the ELF header of an odex/oat/so file, ShareElfFile checks that the first four identification bytes are 0x7F 'E' 'L' 'F'. If not, it throws IOException("bad elf magic: %x %x %x %x.") printing the offending bytes. The file is simply not an ELF binary.
Source
Thrown at tinker-android/tinker-android-loader/src/main/java/com/tencent/tinker/loader/shareutil/ShareElfFile.java:213
public final short eType;
public final short eMachine;
public final int eVersion;
public final long eEntry;
public final long ePhOff;
public final long eShOff;
public final int eFlags;
public final short eEhSize;
public final short ePhEntSize;
public final short ePhNum;
public final short eShEntSize;
public final short eShNum;
public final short eShStrNdx;
private ElfHeader(FileChannel channel) throws IOException {
channel.position(0);
channel.read(ByteBuffer.wrap(eIndent));
if (eIndent[0] != 0x7F || eIndent[1] != 'E' || eIndent[2] != 'L' || eIndent[3] != 'F') {
throw new IOException(String.format("bad elf magic: %x %x %x %x.", eIndent[0], eIndent[1], eIndent[2], eIndent[3]));
}
assertInRange(eIndent[EI_CLASS], ELFCLASS32, ELFCLASS64, "bad elf class: " + eIndent[EI_CLASS]);
assertInRange(eIndent[EI_DATA], ELFDATA2LSB, ELFDATA2MSB, "bad elf data encoding: " + eIndent[EI_DATA]);
final ByteBuffer restBuffer = ByteBuffer.allocate(eIndent[EI_CLASS] == ELFCLASS32 ? 36 : 48);
restBuffer.order(eIndent[EI_DATA] == ELFDATA2LSB ? ByteOrder.LITTLE_ENDIAN : ByteOrder.BIG_ENDIAN);
readUntilLimit(channel, restBuffer, "failed to read rest part of ehdr.");
eType = restBuffer.getShort();
eMachine = restBuffer.getShort();
eVersion = restBuffer.getInt();
assertInRange(eVersion, EV_CURRENT, EV_CURRENT, "bad elf version: " + eVersion);
switch (eIndent[EI_CLASS]) {
case ELFCLASS32:
eEntry = restBuffer.getInt();View on GitHub (pinned to 1b7ea02c23)
Solutions
- Verify the file starts with 0x7F 'ELF' (file command or a 4-byte check) before handing it to ShareElfFile.
- Ensure you point at the real odex location (/oat/<isa>/xxx.odex) and that it exists with size > 0 before parsing.
- If the odex is missing or malformed, skip the oat instruction-set probing and fall back to a different way of obtaining the ISA.
- Regenerate the odex (run the app once so dexopt completes) before applying or verifying patches.
Example fix
// before
elfFile = new ShareElfFile(oatFile);
// after
if (!SharePatchFileUtil.isLegalFile(oatFile) || oatFile.length() < 16) {
throw new IOException("odex missing or too small: " + oatFile);
}
elfFile = new ShareElfFile(oatFile); Defensive patterns
Strategy: validation
Validate before calling
// Check ELF magic before parsing
try (RandomAccessFile raf = new RandomAccessFile(file, "r")) {
int b0 = raf.read(), b1 = raf.read(), b2 = raf.read(), b3 = raf.read();
if (b0 != 0x7F || b1 != 'E' || b2 != 'L' || b3 != 'F') {
// not an ELF: do not hand to ShareElfFile
}
} Try / catch
try {
ShareElfFile elf = new ShareElfFile(file);
} catch (IOException e) {
// message starts with 'bad elf magic': wrong file type supplied
} Prevention
- Always derive the odex path via optimizedPathFor rather than guessing file paths.
- Ensure the odex exists and is non-empty before oat parsing.
- Run the app once after install/OTA so dexopt completes before patching.
When it happens
Trigger: new ShareElfFile(file) (directly or via ShareOatUtil.getOatFileInstructionSet) on a file whose first 4 bytes are not the ELF magic — e.g. a raw dex, zip, or empty file passed where an odex/oat was expected.
Common situations: Passing a .dex path instead of the derived .odex path on Android O+; the odex file not yet generated when the check runs; an art file from an unexpected ART version with a different container format; a zero-length file created by a failed earlier step.
Related errors
- bad elf magic: %x %x %x %x.
- Unexpected elf class: {}
- Unable to find .rodata section.
- {} Rest bytes insufficient, expect to read {} bytes but only
- Unable to find .rodata section.
AI-assisted analysis of Tencent/tinker@1b7ea02c23 (2026-08-14).
Data as JSON: /api/errors/97c91448e2cb3bca.
Report an issue: GitHub.