Skip to content

Instantly share code, notes, and snippets.

@Justasic
Last active August 29, 2015 14:00
Show Gist options
  • Save Justasic/11163696 to your computer and use it in GitHub Desktop.
Save Justasic/11163696 to your computer and use it in GitHub Desktop.
A dumb program that corrupts the stack and displays examples of different crashes. Useful to force an application crash without throwing compiler warnings.
#include <stdio.h>
#include <stdlib.h>
#if 0
void __attribute__((naked)) stackcorrupt(void)
{
// Push EAX to the stack (some random value in eax)
__asm__ __volatile__("pushl %eax");
// return, corrupted stack returns to garbage and program crashes.
__asm__ __volatile__("ret");
}
#else
// What better way to corrupt the stack than to clear the stack pointer!
void stackcorrupt(void) { __asm__ __volatile__("xor %esp, %esp"); }
#endif
// Throw an illegal instruction exception
void illegalinstruct(void)
{
// Although vmwrite is a valid instruction on intel CPUs,
// it's being run in privilage ring 3 (not ring 0) and it's
// a ring 0 opcode, therefore it becomes an illegal
// instruction that the CPU will notify the kernel about.
//
// AMD I believe does not have the same opcodes for their
// CPUs and therefore it may very well be invalid.
//
// The vmwrite opcode is part of the Intel VMX extensions.
__asm__ __volatile__("vmwrite %eax, %ecx");
}
// This function could be written in C but compilers
// have gotten too smart about knowing when a divide
// by zero happens statically and i don't want to work
// around that. So instead, we'll just do it in asm
void dividebyzero(void)
{
__asm__ __volatile__ ("xor %eax, %eax\n"
"divl %eax\n"
);
}
// Free an invalid pointer
void invalidfree(void)
{
free((char*)0xDEADBEEF);
}
// Overflow the stack
#if 0
void stackoverflow(void)
{
// Ironically, from stackoverflow.com.
for (long long int i = 0; ++i; (&i)[i] = i);
}
#else
void stackoverflow(void)
{
// Random block of data to save on the stack
char datablock[10000];
// This is just to make the compiler not whine about
// unused variables and also not optimize this out.
datablock[0] = 0;
// When the compiler compiles this, it will
// push that datablock array to the stack and
// call the overflow function again. This means
// that this function will call recursively but
// always push datablock to the stack and therefore
// the stack will fill up rather fast and crash.
stackoverflow();
}
#endif
void nullptrdereference(void)
{
char *data = NULL;
*data = 'c';
}
#if 0
// just a huge array to overflow the stack before main() is run
char big[-1U / 2U];
#endif
int main()
{
#if 1
printf("Corrupting the stack\n");
stackcorrupt();
printf("Stack corrupted. Why are you seeing this?\n");
#endif
#if 0
printf("Running an illegal instruction\n");
illegalinstruct();
printf("You shouldn't see this.\n");
#endif
#if 0
printf("Running division by zero instruction\n");
dividebyzero();
printf("You shouldn't see this.\n");
#endif
#if 0
printf("Running invalid free\n");
invalidfree();
printf("You shouldn't see this.\n");
#endif
#if 0
printf("Overflowing the stack\n");
stackoverflow();
printf("You shouldn't see this.\n");
#endif
#if 0
printf("Dereferencing a null pointer.\n");
nullptrdereference();
printf("You shouldn't see this.\n");
#endif
return 0;
}
@lordofsraam
Copy link

So much evil and sin in such a small program...

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment