# Offset calculation for branch instruction in ARM

As the title says, how to calculate offsets for branch instructions? For example i have following assembly code,

``````0x60ECE    B loc_60EE6
;
;
;
0x60EE6    LDR.W R2, #0x123
``````

Hex code for location `0x60ECE` is `0A E0`. i want to know how it is calculated. According to https://stackoverflow.com/questions/6744661/understanding-arm-assembler-branch-offset-calculation , offset should be `04` instead of `0A`.

I'm working on android binary.

The instruction format is in little-endian, so bytes `0A E0` gets parsed as machine code `0xE00A`, or `1110000000001010b` in binary.

According to the documentation for the THUMB Instruction Set, the first 5 bits (`11100b`) decode to an unconditional branch opcode, and the last 11 bits (`00000001010b`) decode to Offset11:

As per the documentation above, the destination address is calculated as "PC relative +/- Offset11 << 1" plus 4 for the prefetch operation.

If we do the math, we see that everything works out:

``````   0x60ECE + (00000001010b << 1) + 0x4
== 0x60ECE +       10100b        + 0x4
== 0x60ECE +        0x14         + 0x4
== 0x60EE6
``````

You're missing the fact that you're working in THUMB mode, where you have two bytes per instruction (for most instructions at least), and that link describes ARM mode, where every instruction has 4 bytes.

(How do i know you're in THUMB mode? Apart from your last question, your `0x60ECE B loc_60EE6` isn't 4-byte aligned, so it must be THUMB).

If you add 4 bytes to the instruction at `loc_60ECE`, you get `0x60ED2`. Subtract this from `60EE6` to get `14`, or 20 decimal. Divide by 2 (2 byte instructions in THUMB mode) to get `10` decimal, or `0A` hex.

As calculating offsets can be hard and is error-prone, i let the gnu arm assembler handle it for me. First write an assembly file, like this (named q.s, choose any name you want):

``````.thumb
.arch armv7a
.syntax unified
.org 0x60ECE
B codecave
original:
.org 0x60EE6
codecave:
movw R2, #0x123
B original
``````

then assemble it and check the result:

``````arm-linux-gnueabi-as q.s
arm-linux-gnueabi-objdump -s a.out | grep -v "00000000 00000000 00000000 00000000"

Contents of section .text:
60ec0 00000000 00000000 00000000 00000ae0  ................
60ee0 00000000 000040f2 2312f1e7           ......@.#...
``````

You see your `0ae0` at `60ece`, and `40f22312f1e7` at `60ee6`. You can patch this in IDA directly, or use the idapatcher plugin to copy/paste the hex. I found this to be much easier than crafting the patched bytes manually.

• Thank you sir for pointing out this trick. It made everything a lot easier for me. Finally i was able to create codecave. Commented Jun 9, 2015 at 4:31