Yes i did manually without the double jump and it work. Also try on alternative seem the code cave is very far and double jumps come in very handy, other than that it working very well beta 97you mean double jump? check it by doing a manual edit to see if assembler will assemble the code for you, just edit asm and enter the final destination instead of the intermediate one
it is rare but it does happen that some of the time you can not reach the destination by a single b even when the destination is located in the main code space.
you can also manually calculate it, subtract the difference and compare it with 7FFFFFC
This is the logic :
if ((findfree(m_mainEnd) - m_mainBaseAddr - addr) > 0x7fffffc)
It will always look for free space, reuse cave start comes later. So if you are at the margin and re-assemble a few time it will go past it.
B Instruction Format
The B instruction performs an unconditional branch to a target address, calculated relative to the current PC (Program Counter). Its encoding format is as follows:
31 30 29 28 27 26 | 25 24 23 22 21 20 19 ... 0
Opcode (6 bits) | Immediate (26 bits)
- Opcode: 000101 (6 bits)
- Immediate: A 26-bit signed value representing the offset to the branch target in multiples of 4 bytes.
Steps to Compute the Encoding
- Opcode: 000101 (binary value for the B instruction).
- Immediate field:
- This is a signed 26-bit valuecalculated as:Immediate=Target Address−Current PC4\text{Immediate} = \frac{\text{Target Address} - \text{Current PC}}{4}Immediate=4Target Address−Current PC
- Current PC: The address of the B instruction itself plus 4 (due to prefetching).
- The offset is divided by 4 because instructions in AArch64 are 4 bytes (word-aligned).
- Range: The immediate value must be in the range -2^{25} to 2^{25} - 1 (or -33,554,432 to 33,554,428 in bytes).
- Combine the Opcode and Immediate:
The resulting 32-bit binary value is the full encoding.
Thanks Tom










