Last active
August 29, 2015 14:00
-
-
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.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#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; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
So much evil and sin in such a small program...