To build a stack buffer overflow based exploit, you first need to understand how variables, function arguments and return values are laid out on the stack.
In this section, you will learn how the clang
compiler lays out the stack frame.
Using a file editor, save the contents of the program shown below into a file named stack-layout.c
. Save the file in the directory where you ran docker run
. You can do this outside the docker container.
__attribute__((noinline))
long f() {
volatile char buffer1[4];
volatile char buffer2[7];
buffer1[3] = 10;
buffer2[6] = 20;
return buffer1[3]+buffer2[6];
}
int main() {
f();
return 0;
}
The file will show up in the docker container under the path
/armlearningpaths
.
Compile it with the following command at your docker prompt:
clang -O1 -S -fno-asynchronous-unwind-tables stack-layout.c
This produces the disassembly file stack-layout.s
. When you open it, you see the
following disassembly for function f
:
sub sp, sp, #16
mov w8, #10
mov w9, #20
strb w8, [sp, #12]
strb w9, [sp, #8]
ldrb w8, [sp, #12]
ldrb w9, [sp, #8]
add x0, x9, x8
add sp, sp, #16
ret
Here you can see that the first instruction sub sp, sp #16
reserves 16 bytes on the
stack as the stack frame for this function. The stack on AArch64 grows
downwards, which means it grows towards the lower memory addresses.
The next 4 instructions store value 10
and 20
to buffer1[3]
and
buffer2[6]
.
From the offset [sp, #8]
and [sp, #12]
you can compute the frame layout.
Draw the frame layout of function f
: How are buffer1
and buffer2
laid out
in the 16 bytes that are reserved?
The answer to this exercise can be found in the Answers section .
For the main
function, clang
produces the following assembly:
stp x29, x30, [sp, #-16]! // 16-byte Folded Spill
mov x29, sp
bl f
mov w0, wzr
ldp x29, x30, [sp], #16 // 16-byte Folded Reload
ret
The bl f
instruction in the middle performs a function call to function f
.
It writes the address of the instruction after it – in this case mov w0, wzr
– to register x30
. Then it lets the program continue to the first instruction
of function f
.
Register x30
is also often called the link register, or lr
.
The ret
instruction at the end of the main function will branch to the address
stored in register x30
. The correct address that function main
should return
to was set by a bl main
instruction somewhere else in the program.
Because the bl f
instruction overwrites the value in x30
, the original value
in x30
at the start of function main
needs to be saved somewhere. It is
saved on the stack by the instruction stp x29, x30, [sp, #-16]!
.
The stp
instruction is a “store pair” instruction. It stores 2 registers to a
location in memory. The location in memory in this case is [sp, #-16]!
, that is
the address in register sp
(also known as the stack pointer), at an offset of
-16. The exclamation mark indicates that the value in register sp
should be
updated to the value with the offset. In other words, after this instruction
executes, sp
will have a value that is 16 less than before the instruction
executes. [sp, #-16]!
is a
Pre-index addressing mode
type of instruction.
Register x29
contains the
“
frame pointer
”,
and is sometimes called fp
. The frame pointer points to a location in the
stack frame that contains the “frame record”. The frame record has two
fields: a pointer to the frame record of the function that called the current
function; and the address the current function needs to return to.
At the start of function main
, it contains the value of the frame pointer of
the previous function. Since the function f
that is being called might change
the value of x29
, that value also needs to be stored in the function prologue.
It will be restored by the instruction ldp x29, x30, [sp], #16
in the function
epilogue. [sp], #16
is a
post-index addressing mode
type of instruction:
it specifies to load from the address in register sp
, and then to increase the
value in sp
with 16.
Draw the frame layout of function main
.
x29
) and stack pointer (sp
) point to just
before the call to function f
, which is done by instruction bl f
?The answer to this exercise can be found in the Answers section .