Vector35 / Vector35/binaryninja-api
ARM64ec PE files default to x86-64 when they should be aarch64
Nobody has claimed this yet.
- Dominant language
- C++
- Stars
- 1.3k
- Forks
- 298
- Avg merge
- 5d 5h
- Merged PRs (30d)
- 19
Description
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_artifactsare 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
- https://launchpad.net/~fex-emu/+archive/ubuntu/fex/+files/fex-emu-wine_2604~q_arm64.deb Direct link to the deb
- 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.
Contributor guide
No contributing guide indexed for this repository
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start with the attached libarm64ecfex.dll and compare its behavior with llvm-project/llvm/include/llvm/Object/COFF.h, especially the getMachine() logic and CHPE metadata handling. Use llvm-readobj --coff-load-config -r on the sample to inspect the load-config data; done means the file defaults to aarch64 rather than x86-64, with the optional CodeMap behavior evaluated separately.
Written by the indexing model from the issue text.
Assessment
- Domain
- reverse-engineering
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Quiet
- Clarity
- Mostly clear
- Newbie friendliness
- 48/100