Vector35 / Vector35/binaryninja-api
Offer an option to display pseudo-instructions
Nobody has claimed this yet.
- Dominant language
- C++
- Stars
- 1.3k
- Forks
- 298
- Avg merge
- 5d 5h
- Merged PRs (30d)
- 19
Description
What is the feature you'd like to have?
OS: macOS and Windows 11
Binary Ninja Version: v3.6.4545-dev
ARM64 has ADRL instruction which is a pseudo-instruction.
Simply, it loads a PC-relative or register-relative address into a register.
According to the arm developer documentation it generates 2 32-bit long
instruction:
ADRL always assembles to two 32-bit instructions. Even if the address can be
reached in a single instruction, a second, redundant instruction is produced.
While reversing JavaScriptCore for some gadgets, I have encounter this ADRL
instruction in IDA Pro:
IDA Pro output:
__text:000000018AE9C330 AC 8A FC 97 BL __Z16WTFCrashWithInfoiPKcS0_i ; WTFCrashWithInfo(int,char const*,char const*,int)
__text:000000018AE9C330
__text:000000018AE9C334 ; ---------------------------------------------------------------------------
__text:000000018AE9C334
__text:000000018AE9C334 loc_18AE9C334 ; CODE XREF: JSC::LinkBuffer::copyCompactAndLinkCode<uint>(JSC::MacroAssembler &,JSC::JITCompilationEffort)+2748↑j
__text:000000018AE9C334 E0 03 15 AA MOV X0, X21 ; this
__text:000000018AE9C338 E1 03 14 AA MOV X1, X20 ; void *
__text:000000018AE9C33C E2 03 16 AA MOV X2, X22 ; void *
__text:000000018AE9C340 53 D3 18 94 BL __ZN3JSC13dumpJITMemoryEPKvS1_m ; JSC::dumpJITMemory(void const*,void const*,ulong)
__text:000000018AE9C340
;-----------------------------------------------------
__text:000000018AE9C344 EA 4F 70 B2 8A 21 98 F2 MOV X10, #0xFFFFFC10C
__text:000000018AE9C34C A9 34 35 90 29 01 00 91 ADRL X9, _g_config ; **************** ADRL Here *****************
__text:000000018AE9C354 28 8D 46 39 LDRB W8, [X9,#(byte_1F55301A3 - 0x1F5530000)]
__text:000000018AE9C358 88 C3 FF 35 CBNZ W8, loc_18AE9BBC8
__text:000000018AE9C358
__text:000000018AE9C35C
__text:000000018AE9C35C loc_18AE9C35C ; CODE XREF: JSC::LinkBuffer::copyCompactAndLinkCode<uint>(JSC::MacroAssembler &,JSC::JITCompilationEffort)+2750↑j
__text:000000018AE9C35C 28 E9 40 F9 LDR X8, [X9,#(qword_1F55301D0 - 0x1F5530000)]
__text:000000018AE9C360 A8 01 00 B4 CBZ X8, loc_18AE9C394
I have checked it on Binary Ninja. Binary Ninja output:
18ae9c330 ac8afc97 bl WTFCrashWithInfo
{ Does not return }
18ae9c334 e00315aa mov x0, x21
18ae9c338 e10314aa mov x1, x20
18ae9c33c e20316aa mov x2, x22
18ae9c340 53d31894 bl JSC::dumpJITMemory
;---------------------------------------------------------
18ae9c344 ea4f70b2 mov x10, #0xfffff0000
18ae9c348 8a2198f2 movk x10, #0xc10c {0xfffffc10c}
;---------------------------------------------------------
18ae9c34c a9343590 adrp x9, 0x1f5530000 \ ADRL here
18ae9c350 29010091 add x9, x9, #0 /
;---------------------------------------------------------
18ae9c354 288d4639 ldrb w8, [x9, #0x1a3] {data_1f55301a3}
18ae9c358 88c3ff35 cbnz w8, 0x18ae9bbc8
18ae9c35c 28e940f9 ldr x8, [x9, #0x1d0] {data_1f55301d0}
18ae9c360 a80100b4 cbz x8, 0x18ae9c394
BTW this is the objdump output:
$ objdump -d JavaScriptCore | awk -F"\n" -v RS="\n\n" '$1 ~ /copyCompactAndLinkCode/'
<snip>
18ae9c330: 97fc8aac bl 0x18adbede0 <__Z16WTFCrashWithInfoiPKcS0_i>
18ae9c334: aa1503e0 mov x0, x21
18ae9c338: aa1403e1 mov x1, x20
18ae9c33c: aa1603e2 mov x2, x22
18ae9c340: 9418d353 bl 0x18b4d108c <__ZN3JSC13dumpJITMemoryEPKvS1_m>
18ae9c344: b2704fea mov x10, #68719411200
18ae9c348: f298218a movk x10, #49420
18ae9c34c: 903534a9 adrp x9, 0x1f5530000 <__ZN3JSC9CodeBlock28columnNumberForBytecodeIndexENS_13BytecodeIndexE+0x80>
18ae9c350: 91000129 add x9, x9, #0
18ae9c354: 39468d28 ldrb w8, [x9, #419]
18ae9c358: 35ffc388 cbnz w8, 0x18ae9bbc8 <__ZN3JSC10LinkBuffer22copyCompactAndLinkCodeIjEEvRNS_14MacroAssemblerENS_20JITCompilationEffortE+0x2754>
18ae9c35c: f940e928 ldr x8, [x9, #464]
18ae9c360: b40001a8 cbz x8, 0x18ae9c394 <__ZN3JSC10LinkBuffer22copyCompactAndLinkCodeIjEEvRNS_14MacroAssemblerENS_20JITCompilationEffortE+0x2f20>
<snip>
So Binary ninja chooses the direct instructions. On the other side IDA Pro
chooses to print the pseudo-instruction. As an assembly developer I mostly
use pseudo-instructions and aliases. It is more easy to use, at least in
my opinion.
Is it possible to add an option/switch to disassemble the binary with
pseudo-instructions?
Is your feature request related to a problem?
No, there is not a problem or bug.
Are any alternative solutions acceptable?
No, the decompiler can stay as it is.
Additional Information:
I have included IDA Pro, Binary Ninja and objdump outputs above.
🫶 🧠
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 by comparing the ARM64 disassembly examples for ADRL in the issue, especially the Binary Ninja output versus IDA Pro and objdump. Trace the ARM64 disassembly entry point that controls instruction alias or pseudo-instruction rendering. Done means an explicit option or switch can render the ADRP/ADD pair as ADRL without changing the decompiler output.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- cpp
- Domain
- reverse-engineering
- Issue type
- Feature
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Stale
- Clarity
- Mostly clear
- Newbie friendliness
- 35/100