Let's say I have a function (vuln) that has a local buffer with size of 0x20 bytes. In the beginning of this function, there is push r4-r7,lr.

Is that correct, that the stack looks like:

Buffer: (0x20)...r4(0x4)...r5(0x4)...r6(0x4)...r7(0x4)...lr (for return address 0x4) ...fp (previous frame pointer 0x4)... And then the stack frame of the caller function.

That means, if I want to jump to the function in the address 0xabcd, I need to put in the buffer AA* 0x32 + 0xabcd (0x32 = buffer +r4-r7) .

Is that correct?the place of lr will be replaced but the place of fp stay correct?

Now, if I really will jump to address of 0xabcd. After this function (0xabcd) will finish. The function will try to restore the fp and will crash because it's frame pointer of the vulnerable function.

Is that correct?

1 Answer 1


Your understanding seems mostly correct. But buffer plus four 32-bit registers make up 0x30, not 0x32 bytes. Also be aware that your target address is 32 bits, so it looks more like 0xABCD1234 or 0x0000ABCD then just 0xABCD.

You didn't provide any evidence that proves or disproves that an old fp value is above the pushed link register. I don't expect a copy of the ARM register FP on the stack, though: You are quoting thumb code. Thumb either uses no frame pointer at all, or it uses R7 as frame pointer, as (most) thumb instructions can not access the ARM frame pointer register. If you use R7 as thumb frame pointer by convention, the old frame pointer is the value of r7, which is below the return address (pushed LR), not above.

If you manage to overwrite the return address, you are jumping into the target function without using BL, which is "unconventional". All ARM functions expect their return address to be passed in LR, exactly what BL (or BLX) does. Returning does not set LR, so the target function you inadvertantly return to will jump to the (obsolete) address that happens to be stored in LR at the time the vulnerable function exits. It's likely the return address of a (possibly nested) function call that happened during the execution of the vulnerable function. That code isn't prepared to be returned to from "outside" and will find the stack in a wrong state, so the program will crash.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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