Skip to content

Instantly share code, notes, and snippets.

@tnishinaga
Last active November 7, 2018 18:33
Show Gist options
  • Save tnishinaga/c01573c5098bc89ebaa39075b9adec34 to your computer and use it in GitHub Desktop.
Save tnishinaga/c01573c5098bc89ebaa39075b9adec34 to your computer and use it in GitHub Desktop.
ARM stack execution

environment

pi@raspberrypi:~ $ uname -a
Linux raspberrypi 4.9.35+ #1014 Fri Jun 30 14:34:49 BST 2017 armv6l GNU/Linux
pi@raspberrypi:~ $ gcc -v
Using built-in specs.
COLLECT_GCC=gcc
COLLECT_LTO_WRAPPER=/usr/lib/gcc/arm-linux-gnueabihf/4.9/lto-wrapper
Target: arm-linux-gnueabihf
Configured with: ../src/configure -v --with-pkgversion='Raspbian 4.9.2-10+deb8u1' --with-bugurl=file:///usr/share/doc/gcc-4.9/README.Bugs --enable-languages=c,c++,java,go,d,fortran,objc,obj-c++ --prefix=/usr --program-suffix=-4.9 --enable-shared --enable-linker-build-id --libexecdir=/usr/lib --without-included-gettext --enable-threads=posix --with-gxx-include-dir=/usr/include/c++/4.9 --libdir=/usr/lib --enable-nls --with-sysroot=/ --enable-clocale=gnu --enable-libstdcxx-debug --enable-libstdcxx-time=yes --enable-gnu-unique-object --disable-libitm --disable-libquadmath --enable-plugin --with-system-zlib --disable-browser-plugin --enable-java-awt=gtk --enable-gtk-cairo --with-java-home=/usr/lib/jvm/java-1.5.0-gcj-4.9-armhf/jre --enable-java-home --with-jvm-root-dir=/usr/lib/jvm/java-1.5.0-gcj-4.9-armhf --with-jvm-jar-dir=/usr/lib/jvm-exports/java-1.5.0-gcj-4.9-armhf --with-arch-directory=arm --with-ecj-jar=/usr/share/java/eclipse-ecj.jar --enable-objc-gc --enable-multiarch --disable-sjlj-exceptions --with-arch=armv6 --with-fpu=vfp --with-float=hard --enable-checking=release --build=arm-linux-gnueabihf --host=arm-linux-gnueabihf --target=arm-linux-gnueabihf
Thread model: posix
gcc version 4.9.2 (Raspbian 4.9.2-10+deb8u1) 
pi@raspberrypi:~ $ ld -v
GNU ld (GNU Binutils for Raspbian) 2.25
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int show_memmap_stack(void)
{
FILE *fp = NULL;
fp = fopen("/proc/self/maps", "re");
if (fp == NULL) {
exit(EXIT_FAILURE);
} else {
char buf[256];
while (fgets(buf, sizeof(buf), fp) != NULL) {
char *p = strstr(buf, "[stack]");
if (p != NULL) {
printf("%s",buf);
}
}
}
fclose(fp);
return 0;
}
int main(void)
{
volatile char buf[256];
printf("buf address: %p\n", buf);
show_memmap_stack();
printf("Hello\n");
return 0;
}
CC=gcc
CFLAGS=-g3
NOEXEC_FLAG=-z noexecstack
all: stack_exec hello_map stack_noexec hello_map_noexec
stack_exec: stack_exec.c ret1.S
$(CC) $(CFLAGS) $^ -o $@
hello_map: hello_map.c
$(CC) $(CFLAGS) $^ -o $@
stack_noexec: stack_exec.c ret1.S
$(CC) $(CFLAGS) $(NOEXEC_FLAG) $^ -o $@
hello_map_noexec: hello_map.c
$(CC) $(CFLAGS) $(NOEXEC_FLAG) $^ -o $@
clean:
rm -f stack_exec hello_map stack_noexec hello_map_noexec

results

pi@raspberrypi:~/kernelvm_hokuriku $ sudo execstack -q stack_exec
X stack_exec
pi@raspberrypi:~/kernelvm_hokuriku $ sudo execstack -q stack_noexec
- stack_noexec
pi@raspberrypi:~/kernelvm_hokuriku $ ./stack_exec 
buf address: 0xbea1451c
be9f4000-bea15000 rwxp 00000000 00:00 0          [stack]
ret1 addr: 0x10750
ret1_fin addr: 0x10758
func addr = 0xbea1451c
retval = 1
pi@raspberrypi:~/kernelvm_hokuriku $ ./stack_noexec 
buf address: 0xbec5951c
bec39000-bec5a000 rwxp 00000000 00:00 0          [stack]
ret1 addr: 0x10750
ret1_fin addr: 0x10758
func addr = 0xbec5951c
retval = 1

.global ret1
.align 4
ret1:
mov r0, #1
bx lr
.global ret1_fin
ret1_fin:
nop
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
extern int ret1(void);
extern void ret1_fin(void);
int show_memmap_stack(void)
{
FILE *fp = NULL;
fp = fopen("/proc/self/maps", "re");
if (fp == NULL) {
exit(EXIT_FAILURE);
} else {
char buf[256];
while (fgets(buf, sizeof(buf), fp) != NULL) {
char *p = strstr(buf, "[stack]");
if (p != NULL) {
printf("%s",buf);
}
}
}
fclose(fp);
return 0;
}
int main(void)
{
volatile char buf[256];
printf("buf address: %p\n", buf);
show_memmap_stack();
printf("ret1 addr: %p\n", ret1);
printf("ret1_fin addr: %p\n", ret1_fin);
memcpy((void *)buf, (void *)ret1, (size_t)((void *)ret1_fin - (void *)ret1));
int (*func)() = (int (*)())buf;
int retval = func();
printf("func addr = %p\n", func);
printf("retval = %d\n", retval);
return 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment