Version and Platform (required):
- Binary Ninja Version: 5.3.9409-dev Personal (0c30837b)
- Edition: Non-Commercial
- OS: Ubuntu
- OS Version: Ubuntu 25.10
- CPU Architecture: AArch64 (AmpereOne A192-32X)
Bug Description:
ARM64ec PE files are AArch64 files with x86-64 compatibility.
The COFF_Header machine field has IMAGE_FILE_MACHINE_AMD64 for compatibility, but one must continue to walking the PE64_Optional_Header in to the loadConfigTableEntry which points to eventually points to the CHPEMetadataPointer so you can get the CHPE metadata (symbol __chpe_metadata).
At this point, once you have confirmed that the CHPEMetadata entry exists, you can confirm that if the COFF header declares itself as AMD64 then it's /actually/ ARM64EC, and if the COFF header declares itself as ARM64 then it's actually ARM64X.
Some visibility in to the exact logic can be see in LLVM's source at llvm-project/llvm/include/llvm/Object/COFF.h in the getMachine() function. Additionally llvm-readobj can dump this information as well llvm-readobj --coff-load-config -r libarm64ecfex.dll as long as LLVM is 21 or newer.
Steps To Reproduce:
- Open an arm64ec dll and see it try and disassemble as x86-64
- Close that file, open with options and see it defaults to windows-x86_64
Expected Behavior:
I expect when loading a libarm64ecfex.dll file that is Arm64ec, that instead of default disassembling as x86-64, it instead default disassembles as aarch64.
Binary:
- https://github.com/FEX-Emu/FEX/actions/runs/24476520323 the
wine_dll_artifacts are built from our CI for every commit (but self-deletes after a couple weeks)
- You can rip the DLL from our Ubuntu launchpad release builders. https://launchpad.net/~fex-emu/+archive/ubuntu/fex/+sourcepub/18299389/+listing-archive-extra
- Or use the direct attached zip. libarm64ecfex.dll.zip
- You could technically build an arm64ec binary yourself in msvc or llvm-mingw pretty easily but I don't have a direct example.
Additional Information:
Bonus points for parsing the CPHE config header CodeMap section, as this claims which sections in the COFF file are arm64ec, and which ones are x86-64 helper routines. Then having binja default disassemble those regions correctly with the different architectures.
Version and Platform (required):
Bug Description:
ARM64ec PE files are AArch64 files with x86-64 compatibility.
The
COFF_Headermachine field hasIMAGE_FILE_MACHINE_AMD64for compatibility, but one must continue to walking thePE64_Optional_Headerin to theloadConfigTableEntrywhich points to eventually points to the CHPEMetadataPointer so you can get the CHPE metadata (symbol__chpe_metadata).At this point, once you have confirmed that the CHPEMetadata entry exists, you can confirm that if the COFF header declares itself as
AMD64then it's /actually/ARM64EC, and if the COFF header declares itself asARM64then it's actuallyARM64X.Some visibility in to the exact logic can be see in LLVM's source at
llvm-project/llvm/include/llvm/Object/COFF.hin thegetMachine()function. Additionally llvm-readobj can dump this information as wellllvm-readobj --coff-load-config -r libarm64ecfex.dllas long as LLVM is 21 or newer.Steps To Reproduce:
Expected Behavior:
I expect when loading a
libarm64ecfex.dllfile that is Arm64ec, that instead of default disassembling as x86-64, it instead default disassembles as aarch64.Binary:
wine_dll_artifactsare built from our CI for every commit (but self-deletes after a couple weeks)Additional Information:
Bonus points for parsing the CPHE config header
CodeMapsection, as this claims which sections in the COFF file are arm64ec, and which ones are x86-64 helper routines. Then having binja default disassemble those regions correctly with the different architectures.