In a disassembled elf binary i found these arm thumb instructions:

0x002cc3a8  8079       ldrb r0, [r0, #6]
0x002cc3aa  7047       bx      lr

In the codecave these were the initial hex bytes:

0x00033fd8 00 00 00 00 00 00 00 00 
0x00033fe0 00 00 00 00 00 00 00 00

Then i just branched to the code cave(converted the instruction to a thumb hex):

0x002cc3a8  33F0EABF        b 0x33fd8

Then inserted the same hex bytes into the code cave(I did not change anything):

0x00033fd8 80 79 70 47 00 00 00 00
0x00033fe0 00 00 00 00 00 00 00 00

Function0 and the codecave were in different sections but both sections had the same readable and executable flags. After running the application when that function was called there was an error. The app just quit. It seems like the problem comes from branching to the codecave. Is there something wrong that i did? Should both the function and the codecave be in the same section?


Yeah, finally figured it out by myself. After further testing, it turns out that the problem was indeed with branching. Instead of branching in thumb state, I should have branched in arm state.

The instruction

0x2cc3a8  33F0EABF      b 0x33fd8 

Should be

0x2cc3a8  4C3A0CEA      b 0x33fd8

I don't exactly understand the reason behind this since the original instructions were executed in thumb state and I don't understand why the processor didn't recognise the instruction. I will edit the answer after I get more info on this. By the way the arm state is ARM-7 state since the processor architecture is ARM-7.

EDIT: From the information i got about the branch(b) instruction from the arm and keil website, turns out there are limitations when branching. When branching in thumb mode the distance from the program counter and the address you are branching to should be 2KB in which in my case the code cave was about 111KB far. Branching in arm state worked since limit is 32 MB but somehow it caused errors like increasing the values in registers.

Solution: Load with psedo instruction to the pc the register the address of the start of the code cave e.g ldr pc, =0x30e93c. This may not work if the function is less than 8 bytes long. In thumb mode loading to the program counter(pc) does not work. So instead you need to load to a general purpose register then move the value to pc . e.g

ldr r0, =0x30e93c
mov pc, r0
  • I havent tested it yet but it seems like the error in which values in registers were increased came from replacing two instruction with one. I will test this and if its true i will comment here.
    – Silent
    Oct 22 '21 at 11:44

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.