/* systest v0.2 */
/* do NOT link statically ! */
/* usage: ./systest 2>/dev/null >interesting-data */
/* Changelog:
* 0.2 error messages, mmap() /bin/sh if mmap() /dev/zero fails */
#include <fcntl.h>
#include <setjmp.h>
#include <signal.h>
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/mman.h>
#include <unistd.h>
#include <errno.h>
#include <string.h>
int stack_increment;
unsigned int *stack_top;
void *sbrk_start;
void *mmap_start;
jmp_buf env;
void SIGSEGVBUS_handler() {
longjmp(env,1);
}
void probe_stack_growth(unsigned int *foo) {
if (foo<(unsigned int *)&foo) {
/* stack grows upwards */
stack_increment=-1;
} else {
/* stack grows downwards */
stack_increment=1;
}
}
int bss;
int data=42;
const char* fn[]={"/dev/zero","/bin/sh"};
int main() {
unsigned int i;
unsigned int reported_errors;
int fd;
char *rodata="foobar";
reported_errors=0;
/* determine stack data */
probe_stack_growth(&i);
if (signal(SIGSEGV,(void (*)())SIGSEGVBUS_handler)==(void (*)(int))-1) {
stack_top=(void *)-1;
if (!reported_errors) {
printf("----------------- errors report -----------------\n");
reported_errors=1;
}
printf("signal(SIGSEGV,SISEGVBUS_handler): %d %s\n",errno,strerror(errno));
} else {
if (signal(SIGBUS,(void (*)())SIGSEGVBUS_handler)==(void (*)(int))-1) {
stack_top=(void *)-1;
if (!reported_errors) {
printf("----------------- errors report -----------------\n");
reported_errors=1;
}
printf("signal(SIGBUS,SISEGVBUS_handler): %d %s\n",errno,strerror(errno));
} else {
if (!setjmp(env)) {
for (stack_top=&i;;stack_top+=stack_increment) {
fprintf(stderr,"%lx\t-> 0x%x\n",(unsigned long)stack_top,*stack_top);
}
}
}
}
/* determine heap data */
sbrk_start=sbrk(0);
if (((long int)sbrk_start)==-1) {
if (!reported_errors) {
printf("----------------- errors report -----------------\n");
reported_errors=1;
}
printf("sbrk(0): %d %s\n",errno,strerror(errno));
}
/* determine mmap data */
for (i=0;i<2;i++) {
fd=open(fn[i],O_RDONLY,0);
if (fd<0) {
mmap_start=(void *)-1;
if (!reported_errors) {
printf("----------------- errors report -----------------\n");
reported_errors=1;
}
printf("open(\"%s\",O_RDONLY,0): %d %s\n",fn[i],errno,strerror(errno));
} else {
mmap_start=mmap(0,0x4212,PROT_READ,MAP_PRIVATE,fd,0);
if (((long int)mmap_start)==-1) {
if (!reported_errors) {
printf("----------------- errors report -----------------\n");
reported_errors=1;
}
printf("mmap(0,0x4212,PROT_READ,MAP_PRIVATE,%d,0): %d %s\n",fd,errno,
strerror(errno));
}
}
}
/* display results */
printf("----------------- interesting data starts here -----------------\n");
printf("code around 0x%lx\n",(unsigned long)probe_stack_growth);
printf("rodata around 0x%lx\n",(unsigned long)rodata);
printf("data around 0x%lx\n",(unsigned long)&mmap_start);
printf("bss around 0x%lx\n",(unsigned long)&bss);
printf("sbrk start around 0x%lx\n",(unsigned long)sbrk_start);
printf("stack grows %s from 0x%lx\n",
(stack_increment>0)?"downwards":"upwards",
(unsigned long)stack_top);
printf("shared libraries mapped around 0x%lx\n",(unsigned long)&errno);
printf("mmap start around 0x%lx\n",(unsigned long)mmap_start);
printf("uname -a: ");
fflush(stdout);
system("uname -a");
return 0;
}