SlideShare a Scribd company logo
1 of 357
Download to read offline
Insecure coding in C (and C++)
Let's turn the table. Suppose your goal is to deliberately create buggy programs in C and C++ with serious
security vulnerabilities that can be "easily" exploited.Then you need to know about things like stack smashing,
shellcode, arc injection, return-oriented programming. You also need to know about annoying protection
mechanisms such as address space layout randomization, stack canaries, data execution prevention, and more.
This session will teach you the basics of how to deliberately write insecure programs in C and C++.
a 60 minute presentation
Norwegian Developer Conference
Oslo, June 5 2014, 16:20-17:20
Olve Maudal
Update:A recording of this talk is available at http://vimeo.com/channels/ndc2014/97505677
Insecure coding in C (and C++)
Let's turn the table. Suppose your goal is to deliberately create buggy programs in C and C++ with serious
security vulnerabilities that can be "easily" exploited.Then you need to know about things like stack smashing,
shellcode, arc injection, return-oriented programming. You also need to know about annoying protection
mechanisms such as address space layout randomization, stack canaries, data execution prevention, and more.
This session will teach you the basics of how to deliberately write insecure programs in C and C++.
a 60 minute presentation
Norwegian Developer Conference
Oslo, June 5 2014, 16:20-17:20
Olve Maudal
Insecure coding in C (and C++)
Let's turn the table. Suppose your goal is to deliberately create buggy programs in C and C++ with serious
security vulnerabilities that can be "easily" exploited.Then you need to know about things like stack smashing,
shellcode, arc injection, return-oriented programming. You also need to know about annoying protection
mechanisms such as address space layout randomization, stack canaries, data execution prevention, and more.
This session will teach you the basics of how to deliberately write insecure programs in C and C++.
a 60 minute presentation
Norwegian Developer Conference
Oslo, June 5 2014, 16:20-17:20
Olve Maudal
Level:
Introduction
Advanced
Expert
Insecure coding in C (and C++)
Let's turn the table. Suppose your goal is to deliberately create buggy programs in C and C++ with serious
security vulnerabilities that can be "easily" exploited.Then you need to know about things like stack smashing,
shellcode, arc injection, return-oriented programming. You also need to know about annoying protection
mechanisms such as address space layout randomization, stack canaries, data execution prevention, and more.
This session will teach you the basics of how to deliberately write insecure programs in C and C++.
a 60 minute presentation
Norwegian Developer Conference
Oslo, June 5 2014, 16:20-17:20
Olve Maudal
Level:
Introduction
Advanced
Expert
Insecure coding in C (and C++)
Let's turn the table. Suppose your goal is to deliberately create buggy programs in C and C++ with serious
security vulnerabilities that can be "easily" exploited.Then you need to know about things like stack smashing,
shellcode, arc injection, return-oriented programming. You also need to know about annoying protection
mechanisms such as address space layout randomization, stack canaries, data execution prevention, and more.
This session will teach you the basics of how to deliberately write insecure programs in C and C++.
a 60 minute presentation
Norwegian Developer Conference
Oslo, June 5 2014, 16:20-17:20
Olve Maudal
Level:
Introduction
Advanced
Expert
Insecure coding in C (and C++)
Let's turn the table. Suppose your goal is to deliberately create buggy programs in C and C++ with serious
security vulnerabilities that can be "easily" exploited.Then you need to know about things like stack smashing,
shellcode, arc injection, return-oriented programming. You also need to know about annoying protection
mechanisms such as address space layout randomization, stack canaries, data execution prevention, and more.
This session will teach you the basics of how to deliberately write insecure programs in C and C++.
a 60 minute presentation
Norwegian Developer Conference
Oslo, June 5 2014, 16:20-17:20
Olve Maudal
Level:
Introduction
Advanced
Expert
When I refer to "my machine" it is a fairly up-to-date Ubuntu
distro (13.10) running inVirtualBox with x86-32 Linux kernel
(3.11) and gcc (4.8.1) - there is nothing special here...
I will briefly discuss the following topics:
•stack buffer overflow (aka stack smashing)
•call stack (aka activation frames)
•writing exploits
•arc injection (aka return to lib-c)
•code injection (aka shell code)
•data execution protection (aka DEP, PAE/NX,W^X)
•address space layout randomization (ASLR)
•stack protection (aka stack canaries)
•return-oriented programming (ROP)
•writing code with "surprising" behavior
•layered security
•information leakage
•patching binaries
•summary - a few tricks for insecure coding
void launch_missiles(int n)
{
printf("Launching %d missilesn", n);
// TODO: implement this function
}
void authenticate_and_launch(void)
{
int n_missiles = 2;
bool allowaccess = false;
char response[8];
printf("Secret: ");
gets(response);
if (strcmp(response, "Joshua") == 0)
allowaccess = true;
if (allowaccess) {
puts("Access granted");
launch_missiles(n_missiles);
}
if (!allowaccess)
puts("Access denied");
}
int main(void)
{
puts("WarGames MissileLauncher v0.1");
authenticate_and_launch();
puts("Operation complete");
}
Here is a classic example of exploitable code
void launch_missiles(int n)
{
printf("Launching %d missilesn", n);
// TODO: implement this function
}
void authenticate_and_launch(void)
{
int n_missiles = 2;
bool allowaccess = false;
char response[8];
printf("Secret: ");
gets(response);
if (strcmp(response, "Joshua") == 0)
allowaccess = true;
if (allowaccess) {
puts("Access granted");
launch_missiles(n_missiles);
}
if (!allowaccess)
puts("Access denied");
}
int main(void)
{
puts("WarGames MissileLauncher v0.1");
authenticate_and_launch();
puts("Operation complete");
}
Here is a classic example of exploitable code
void launch_missiles(int n)
{
printf("Launching %d missilesn", n);
// TODO: implement this function
}
void authenticate_and_launch(void)
{
int n_missiles = 2;
bool allowaccess = false;
char response[8];
printf("Secret: ");
gets(response);
if (strcmp(response, "Joshua") == 0)
allowaccess = true;
if (allowaccess) {
puts("Access granted");
launch_missiles(n_missiles);
}
if (!allowaccess)
puts("Access denied");
}
int main(void)
{
puts("WarGames MissileLauncher v0.1");
authenticate_and_launch();
puts("Operation complete");
}
Here is a classic example of exploitable code
void launch_missiles(int n)
{
printf("Launching %d missilesn", n);
// TODO: implement this function
}
void authenticate_and_launch(void)
{
int n_missiles = 2;
bool allowaccess = false;
char response[8];
printf("Secret: ");
gets(response);
if (strcmp(response, "Joshua") == 0)
allowaccess = true;
if (allowaccess) {
puts("Access granted");
launch_missiles(n_missiles);
}
if (!allowaccess)
puts("Access denied");
}
int main(void)
{
puts("WarGames MissileLauncher v0.1");
authenticate_and_launch();
puts("Operation complete");
}
This program is bad in so many ways, but
the main weakness we are going to have fun
with is of course the use of gets()
Here is a classic example of exploitable code
void launch_missiles(int n)
{
printf("Launching %d missilesn", n);
// TODO: implement this function
}
void authenticate_and_launch(void)
{
int n_missiles = 2;
bool allowaccess = false;
char response[8];
printf("Secret: ");
gets(response);
if (strcmp(response, "Joshua") == 0)
allowaccess = true;
if (allowaccess) {
puts("Access granted");
launch_missiles(n_missiles);
}
if (!allowaccess)
puts("Access denied");
}
int main(void)
{
puts("WarGames MissileLauncher v0.1");
authenticate_and_launch();
puts("Operation complete");
}
This program is bad in so many ways, but
the main weakness we are going to have fun
with is of course the use of gets()
gets() is a function that will read characters
from stdin until a newline or end-of-file is
reached, and then a null character is
appended. In this case, any input of more than
7 characters will overwrite data outside of the
allocated space for the buffer
Here is a classic example of exploitable code
void launch_missiles(int n)
{
printf("Launching %d missilesn", n);
// TODO: implement this function
}
void authenticate_and_launch(void)
{
int n_missiles = 2;
bool allowaccess = false;
char response[8];
printf("Secret: ");
gets(response);
if (strcmp(response, "Joshua") == 0)
allowaccess = true;
if (allowaccess) {
puts("Access granted");
launch_missiles(n_missiles);
}
if (!allowaccess)
puts("Access denied");
}
int main(void)
{
puts("WarGames MissileLauncher v0.1");
authenticate_and_launch();
puts("Operation complete");
}
This program is bad in so many ways, but
the main weakness we are going to have fun
with is of course the use of gets()
gets() is a function that will read characters
from stdin until a newline or end-of-file is
reached, and then a null character is
appended. In this case, any input of more than
7 characters will overwrite data outside of the
allocated space for the buffer
I never use gets()
Here is a classic example of exploitable code
void launch_missiles(int n)
{
printf("Launching %d missilesn", n);
// TODO: implement this function
}
void authenticate_and_launch(void)
{
int n_missiles = 2;
bool allowaccess = false;
char response[8];
printf("Secret: ");
gets(response);
if (strcmp(response, "Joshua") == 0)
allowaccess = true;
if (allowaccess) {
puts("Access granted");
launch_missiles(n_missiles);
}
if (!allowaccess)
puts("Access denied");
}
int main(void)
{
puts("WarGames MissileLauncher v0.1");
authenticate_and_launch();
puts("Operation complete");
}
This program is bad in so many ways, but
the main weakness we are going to have fun
with is of course the use of gets()
gets() is a function that will read characters
from stdin until a newline or end-of-file is
reached, and then a null character is
appended. In this case, any input of more than
7 characters will overwrite data outside of the
allocated space for the buffer
I never use gets()
That's nice to hear, and gets() has actually
been deprecated and removed from latest
version of the language.We use it anyway here
just to make it easier to illustrate the basics. In
C and C++ there are plenty of ways to
accidentally allow you to poke directly into
memory - we will mention some of those later
later. But for now...
Here is a classic example of exploitable code
void launch_missiles(int n)
{
printf("Launching %d missilesn", n);
// TODO: implement this function
}
void authenticate_and_launch(void)
{
int n_missiles = 2;
bool allowaccess = false;
char response[8];
printf("Secret: ");
gets(response);
if (strcmp(response, "Joshua") == 0)
allowaccess = true;
if (allowaccess) {
puts("Access granted");
launch_missiles(n_missiles);
}
if (!allowaccess)
puts("Access denied");
}
int main(void)
{
puts("WarGames MissileLauncher v0.1");
authenticate_and_launch();
puts("Operation complete");
}
void launch_missiles(int n)
{
printf("Launching %d missilesn", n);
// TODO: implement this function
}
void authenticate_and_launch(void)
{
int n_missiles = 2;
bool allowaccess = false;
char response[8];
printf("Secret: ");
gets(response);
if (strcmp(response, "Joshua") == 0)
allowaccess = true;
if (allowaccess) {
puts("Access granted");
launch_missiles(n_missiles);
}
if (!allowaccess)
puts("Access denied");
}
int main(void)
{
puts("WarGames MissileLauncher v0.1");
authenticate_and_launch();
puts("Operation complete");
}
Let's try executing the code
and see what happens.
$ ./launch
void launch_missiles(int n)
{
printf("Launching %d missilesn", n);
// TODO: implement this function
}
void authenticate_and_launch(void)
{
int n_missiles = 2;
bool allowaccess = false;
char response[8];
printf("Secret: ");
gets(response);
if (strcmp(response, "Joshua") == 0)
allowaccess = true;
if (allowaccess) {
puts("Access granted");
launch_missiles(n_missiles);
}
if (!allowaccess)
puts("Access denied");
}
int main(void)
{
puts("WarGames MissileLauncher v0.1");
authenticate_and_launch();
puts("Operation complete");
}
Let's try executing the code
and see what happens.
$ ./launch
WarGames MissileLauncher v0.1
void launch_missiles(int n)
{
printf("Launching %d missilesn", n);
// TODO: implement this function
}
void authenticate_and_launch(void)
{
int n_missiles = 2;
bool allowaccess = false;
char response[8];
printf("Secret: ");
gets(response);
if (strcmp(response, "Joshua") == 0)
allowaccess = true;
if (allowaccess) {
puts("Access granted");
launch_missiles(n_missiles);
}
if (!allowaccess)
puts("Access denied");
}
int main(void)
{
puts("WarGames MissileLauncher v0.1");
authenticate_and_launch();
puts("Operation complete");
}
Let's try executing the code
and see what happens.
$ ./launch
WarGames MissileLauncher v0.1
Secret:
void launch_missiles(int n)
{
printf("Launching %d missilesn", n);
// TODO: implement this function
}
void authenticate_and_launch(void)
{
int n_missiles = 2;
bool allowaccess = false;
char response[8];
printf("Secret: ");
gets(response);
if (strcmp(response, "Joshua") == 0)
allowaccess = true;
if (allowaccess) {
puts("Access granted");
launch_missiles(n_missiles);
}
if (!allowaccess)
puts("Access denied");
}
int main(void)
{
puts("WarGames MissileLauncher v0.1");
authenticate_and_launch();
puts("Operation complete");
}
Let's try executing the code
and see what happens.
$ ./launch
WarGames MissileLauncher v0.1
Secret:
void launch_missiles(int n)
{
printf("Launching %d missilesn", n);
// TODO: implement this function
}
void authenticate_and_launch(void)
{
int n_missiles = 2;
bool allowaccess = false;
char response[8];
printf("Secret: ");
gets(response);
if (strcmp(response, "Joshua") == 0)
allowaccess = true;
if (allowaccess) {
puts("Access granted");
launch_missiles(n_missiles);
}
if (!allowaccess)
puts("Access denied");
}
int main(void)
{
puts("WarGames MissileLauncher v0.1");
authenticate_and_launch();
puts("Operation complete");
}
David
Let's try executing the code
and see what happens.
$ ./launch
WarGames MissileLauncher v0.1
Secret:
void launch_missiles(int n)
{
printf("Launching %d missilesn", n);
// TODO: implement this function
}
void authenticate_and_launch(void)
{
int n_missiles = 2;
bool allowaccess = false;
char response[8];
printf("Secret: ");
gets(response);
if (strcmp(response, "Joshua") == 0)
allowaccess = true;
if (allowaccess) {
puts("Access granted");
launch_missiles(n_missiles);
}
if (!allowaccess)
puts("Access denied");
}
int main(void)
{
puts("WarGames MissileLauncher v0.1");
authenticate_and_launch();
puts("Operation complete");
}
Access denied
David
Let's try executing the code
and see what happens.
$ ./launch
WarGames MissileLauncher v0.1
Secret:
void launch_missiles(int n)
{
printf("Launching %d missilesn", n);
// TODO: implement this function
}
void authenticate_and_launch(void)
{
int n_missiles = 2;
bool allowaccess = false;
char response[8];
printf("Secret: ");
gets(response);
if (strcmp(response, "Joshua") == 0)
allowaccess = true;
if (allowaccess) {
puts("Access granted");
launch_missiles(n_missiles);
}
if (!allowaccess)
puts("Access denied");
}
int main(void)
{
puts("WarGames MissileLauncher v0.1");
authenticate_and_launch();
puts("Operation complete");
}
Access denied
Operation complete
David
Let's try executing the code
and see what happens.
$ ./launch
WarGames MissileLauncher v0.1
Secret:
void launch_missiles(int n)
{
printf("Launching %d missilesn", n);
// TODO: implement this function
}
void authenticate_and_launch(void)
{
int n_missiles = 2;
bool allowaccess = false;
char response[8];
printf("Secret: ");
gets(response);
if (strcmp(response, "Joshua") == 0)
allowaccess = true;
if (allowaccess) {
puts("Access granted");
launch_missiles(n_missiles);
}
if (!allowaccess)
puts("Access denied");
}
int main(void)
{
puts("WarGames MissileLauncher v0.1");
authenticate_and_launch();
puts("Operation complete");
}
Access denied
Operation complete
$ ./launch
David
Let's try executing the code
and see what happens.
$ ./launch
WarGames MissileLauncher v0.1
Secret:
void launch_missiles(int n)
{
printf("Launching %d missilesn", n);
// TODO: implement this function
}
void authenticate_and_launch(void)
{
int n_missiles = 2;
bool allowaccess = false;
char response[8];
printf("Secret: ");
gets(response);
if (strcmp(response, "Joshua") == 0)
allowaccess = true;
if (allowaccess) {
puts("Access granted");
launch_missiles(n_missiles);
}
if (!allowaccess)
puts("Access denied");
}
int main(void)
{
puts("WarGames MissileLauncher v0.1");
authenticate_and_launch();
puts("Operation complete");
}
Access denied
Operation complete
$ ./launch
WarGames MissileLauncher v0.1
David
Let's try executing the code
and see what happens.
$ ./launch
WarGames MissileLauncher v0.1
Secret:
void launch_missiles(int n)
{
printf("Launching %d missilesn", n);
// TODO: implement this function
}
void authenticate_and_launch(void)
{
int n_missiles = 2;
bool allowaccess = false;
char response[8];
printf("Secret: ");
gets(response);
if (strcmp(response, "Joshua") == 0)
allowaccess = true;
if (allowaccess) {
puts("Access granted");
launch_missiles(n_missiles);
}
if (!allowaccess)
puts("Access denied");
}
int main(void)
{
puts("WarGames MissileLauncher v0.1");
authenticate_and_launch();
puts("Operation complete");
}
Access denied
Operation complete
$ ./launch
WarGames MissileLauncher v0.1
Secret:
David
Let's try executing the code
and see what happens.
$ ./launch
WarGames MissileLauncher v0.1
Secret:
void launch_missiles(int n)
{
printf("Launching %d missilesn", n);
// TODO: implement this function
}
void authenticate_and_launch(void)
{
int n_missiles = 2;
bool allowaccess = false;
char response[8];
printf("Secret: ");
gets(response);
if (strcmp(response, "Joshua") == 0)
allowaccess = true;
if (allowaccess) {
puts("Access granted");
launch_missiles(n_missiles);
}
if (!allowaccess)
puts("Access denied");
}
int main(void)
{
puts("WarGames MissileLauncher v0.1");
authenticate_and_launch();
puts("Operation complete");
}
Access denied
Operation complete
$ ./launch
WarGames MissileLauncher v0.1
Secret: Joshua
David
Let's try executing the code
and see what happens.
$ ./launch
WarGames MissileLauncher v0.1
Secret:
void launch_missiles(int n)
{
printf("Launching %d missilesn", n);
// TODO: implement this function
}
void authenticate_and_launch(void)
{
int n_missiles = 2;
bool allowaccess = false;
char response[8];
printf("Secret: ");
gets(response);
if (strcmp(response, "Joshua") == 0)
allowaccess = true;
if (allowaccess) {
puts("Access granted");
launch_missiles(n_missiles);
}
if (!allowaccess)
puts("Access denied");
}
int main(void)
{
puts("WarGames MissileLauncher v0.1");
authenticate_and_launch();
puts("Operation complete");
}
Access granted
Access denied
Operation complete
$ ./launch
WarGames MissileLauncher v0.1
Secret: Joshua
David
Let's try executing the code
and see what happens.
$ ./launch
WarGames MissileLauncher v0.1
Secret:
void launch_missiles(int n)
{
printf("Launching %d missilesn", n);
// TODO: implement this function
}
void authenticate_and_launch(void)
{
int n_missiles = 2;
bool allowaccess = false;
char response[8];
printf("Secret: ");
gets(response);
if (strcmp(response, "Joshua") == 0)
allowaccess = true;
if (allowaccess) {
puts("Access granted");
launch_missiles(n_missiles);
}
if (!allowaccess)
puts("Access denied");
}
int main(void)
{
puts("WarGames MissileLauncher v0.1");
authenticate_and_launch();
puts("Operation complete");
}
Access granted
Launching 2 missiles
Access denied
Operation complete
$ ./launch
WarGames MissileLauncher v0.1
Secret: Joshua
David
Let's try executing the code
and see what happens.
$ ./launch
WarGames MissileLauncher v0.1
Secret:
void launch_missiles(int n)
{
printf("Launching %d missilesn", n);
// TODO: implement this function
}
void authenticate_and_launch(void)
{
int n_missiles = 2;
bool allowaccess = false;
char response[8];
printf("Secret: ");
gets(response);
if (strcmp(response, "Joshua") == 0)
allowaccess = true;
if (allowaccess) {
puts("Access granted");
launch_missiles(n_missiles);
}
if (!allowaccess)
puts("Access denied");
}
int main(void)
{
puts("WarGames MissileLauncher v0.1");
authenticate_and_launch();
puts("Operation complete");
}
Access granted
Launching 2 missiles
Operation complete
Access denied
Operation complete
$ ./launch
WarGames MissileLauncher v0.1
Secret: Joshua
David
Let's try executing the code
and see what happens.
$ ./launch
WarGames MissileLauncher v0.1
Secret:
void launch_missiles(int n)
{
printf("Launching %d missilesn", n);
// TODO: implement this function
}
void authenticate_and_launch(void)
{
int n_missiles = 2;
bool allowaccess = false;
char response[8];
printf("Secret: ");
gets(response);
if (strcmp(response, "Joshua") == 0)
allowaccess = true;
if (allowaccess) {
puts("Access granted");
launch_missiles(n_missiles);
}
if (!allowaccess)
puts("Access denied");
}
int main(void)
{
puts("WarGames MissileLauncher v0.1");
authenticate_and_launch();
puts("Operation complete");
}
Access granted
Launching 2 missiles
Operation complete
$ ./launch
Access denied
Operation complete
$ ./launch
WarGames MissileLauncher v0.1
Secret: Joshua
David
Let's try executing the code
and see what happens.
$ ./launch
WarGames MissileLauncher v0.1
Secret:
void launch_missiles(int n)
{
printf("Launching %d missilesn", n);
// TODO: implement this function
}
void authenticate_and_launch(void)
{
int n_missiles = 2;
bool allowaccess = false;
char response[8];
printf("Secret: ");
gets(response);
if (strcmp(response, "Joshua") == 0)
allowaccess = true;
if (allowaccess) {
puts("Access granted");
launch_missiles(n_missiles);
}
if (!allowaccess)
puts("Access denied");
}
int main(void)
{
puts("WarGames MissileLauncher v0.1");
authenticate_and_launch();
puts("Operation complete");
}
Access granted
Launching 2 missiles
Operation complete
$ ./launch
WarGames MissileLauncher v0.1
Access denied
Operation complete
$ ./launch
WarGames MissileLauncher v0.1
Secret: Joshua
David
Let's try executing the code
and see what happens.
$ ./launch
WarGames MissileLauncher v0.1
Secret:
void launch_missiles(int n)
{
printf("Launching %d missilesn", n);
// TODO: implement this function
}
void authenticate_and_launch(void)
{
int n_missiles = 2;
bool allowaccess = false;
char response[8];
printf("Secret: ");
gets(response);
if (strcmp(response, "Joshua") == 0)
allowaccess = true;
if (allowaccess) {
puts("Access granted");
launch_missiles(n_missiles);
}
if (!allowaccess)
puts("Access denied");
}
int main(void)
{
puts("WarGames MissileLauncher v0.1");
authenticate_and_launch();
puts("Operation complete");
}
Access granted
Launching 2 missiles
Operation complete
$ ./launch
WarGames MissileLauncher v0.1
Secret:
Access denied
Operation complete
$ ./launch
WarGames MissileLauncher v0.1
Secret: Joshua
David
Let's try executing the code
and see what happens.
$ ./launch
WarGames MissileLauncher v0.1
Secret:
void launch_missiles(int n)
{
printf("Launching %d missilesn", n);
// TODO: implement this function
}
void authenticate_and_launch(void)
{
int n_missiles = 2;
bool allowaccess = false;
char response[8];
printf("Secret: ");
gets(response);
if (strcmp(response, "Joshua") == 0)
allowaccess = true;
if (allowaccess) {
puts("Access granted");
launch_missiles(n_missiles);
}
if (!allowaccess)
puts("Access denied");
}
int main(void)
{
puts("WarGames MissileLauncher v0.1");
authenticate_and_launch();
puts("Operation complete");
}
Access granted
Launching 2 missiles
Operation complete
$ ./launch
WarGames MissileLauncher v0.1
Secret: globalthermonuclearwar
Access denied
Operation complete
$ ./launch
WarGames MissileLauncher v0.1
Secret: Joshua
David
Let's try executing the code
and see what happens.
$ ./launch
WarGames MissileLauncher v0.1
Secret:
void launch_missiles(int n)
{
printf("Launching %d missilesn", n);
// TODO: implement this function
}
void authenticate_and_launch(void)
{
int n_missiles = 2;
bool allowaccess = false;
char response[8];
printf("Secret: ");
gets(response);
if (strcmp(response, "Joshua") == 0)
allowaccess = true;
if (allowaccess) {
puts("Access granted");
launch_missiles(n_missiles);
}
if (!allowaccess)
puts("Access denied");
}
int main(void)
{
puts("WarGames MissileLauncher v0.1");
authenticate_and_launch();
puts("Operation complete");
}
Access granted
Launching 2 missiles
Operation complete
$ ./launch
WarGames MissileLauncher v0.1
Secret: globalthermonuclearwar
Access denied
Operation complete
$ ./launch
WarGames MissileLauncher v0.1
Secret: Joshua
David
Access granted
Let's try executing the code
and see what happens.
$ ./launch
WarGames MissileLauncher v0.1
Secret:
void launch_missiles(int n)
{
printf("Launching %d missilesn", n);
// TODO: implement this function
}
void authenticate_and_launch(void)
{
int n_missiles = 2;
bool allowaccess = false;
char response[8];
printf("Secret: ");
gets(response);
if (strcmp(response, "Joshua") == 0)
allowaccess = true;
if (allowaccess) {
puts("Access granted");
launch_missiles(n_missiles);
}
if (!allowaccess)
puts("Access denied");
}
int main(void)
{
puts("WarGames MissileLauncher v0.1");
authenticate_and_launch();
puts("Operation complete");
}
Access granted
Launching 2 missiles
Operation complete
$ ./launch
WarGames MissileLauncher v0.1
Secret: globalthermonuclearwar
Access denied
Operation complete
$ ./launch
WarGames MissileLauncher v0.1
Secret: Joshua
David
Access granted
Launching 1869443685 missiles
Let's try executing the code
and see what happens.
$ ./launch
WarGames MissileLauncher v0.1
Secret:
void launch_missiles(int n)
{
printf("Launching %d missilesn", n);
// TODO: implement this function
}
void authenticate_and_launch(void)
{
int n_missiles = 2;
bool allowaccess = false;
char response[8];
printf("Secret: ");
gets(response);
if (strcmp(response, "Joshua") == 0)
allowaccess = true;
if (allowaccess) {
puts("Access granted");
launch_missiles(n_missiles);
}
if (!allowaccess)
puts("Access denied");
}
int main(void)
{
puts("WarGames MissileLauncher v0.1");
authenticate_and_launch();
puts("Operation complete");
}
Access granted
Launching 2 missiles
Operation complete
$ ./launch
WarGames MissileLauncher v0.1
Secret: globalthermonuclearwar
Access denied
Operation complete
$ ./launch
WarGames MissileLauncher v0.1
Secret: Joshua
David
Access granted
Launching 1869443685 missiles
Access denied
Let's try executing the code
and see what happens.
$ ./launch
WarGames MissileLauncher v0.1
Secret:
void launch_missiles(int n)
{
printf("Launching %d missilesn", n);
// TODO: implement this function
}
void authenticate_and_launch(void)
{
int n_missiles = 2;
bool allowaccess = false;
char response[8];
printf("Secret: ");
gets(response);
if (strcmp(response, "Joshua") == 0)
allowaccess = true;
if (allowaccess) {
puts("Access granted");
launch_missiles(n_missiles);
}
if (!allowaccess)
puts("Access denied");
}
int main(void)
{
puts("WarGames MissileLauncher v0.1");
authenticate_and_launch();
puts("Operation complete");
}
Operation complete
Access granted
Launching 2 missiles
Operation complete
$ ./launch
WarGames MissileLauncher v0.1
Secret: globalthermonuclearwar
Access denied
Operation complete
$ ./launch
WarGames MissileLauncher v0.1
Secret: Joshua
David
Access granted
Launching 1869443685 missiles
Access denied
Let's try executing the code
and see what happens.
$ ./launch
WarGames MissileLauncher v0.1
Secret:
void launch_missiles(int n)
{
printf("Launching %d missilesn", n);
// TODO: implement this function
}
void authenticate_and_launch(void)
{
int n_missiles = 2;
bool allowaccess = false;
char response[8];
printf("Secret: ");
gets(response);
if (strcmp(response, "Joshua") == 0)
allowaccess = true;
if (allowaccess) {
puts("Access granted");
launch_missiles(n_missiles);
}
if (!allowaccess)
puts("Access denied");
}
int main(void)
{
puts("WarGames MissileLauncher v0.1");
authenticate_and_launch();
puts("Operation complete");
}
Operation complete
$
Access granted
Launching 2 missiles
Operation complete
$ ./launch
WarGames MissileLauncher v0.1
Secret: globalthermonuclearwar
Access denied
Operation complete
$ ./launch
WarGames MissileLauncher v0.1
Secret: Joshua
David
Access granted
Launching 1869443685 missiles
Access denied
Let's try executing the code
and see what happens.
$ ./launch
WarGames MissileLauncher v0.1
Secret:
void launch_missiles(int n)
{
printf("Launching %d missilesn", n);
// TODO: implement this function
}
void authenticate_and_launch(void)
{
int n_missiles = 2;
bool allowaccess = false;
char response[8];
printf("Secret: ");
gets(response);
if (strcmp(response, "Joshua") == 0)
allowaccess = true;
if (allowaccess) {
puts("Access granted");
launch_missiles(n_missiles);
}
if (!allowaccess)
puts("Access denied");
}
int main(void)
{
puts("WarGames MissileLauncher v0.1");
authenticate_and_launch();
puts("Operation complete");
}
Operation complete
$
Access granted
Launching 2 missiles
Operation complete
$ ./launch
WarGames MissileLauncher v0.1
Secret: globalthermonuclearwar
Access denied
Operation complete
$ ./launch
WarGames MissileLauncher v0.1
Secret: Joshua
David
Access granted
Launching 1869443685 missiles
Access denied
Let's try executing the code
and see what happens.
Due to an overflow we seem to have
changed the value of allowaccess and
the value of n_missiles. Interesting!
$ ./launch
WarGames MissileLauncher v0.1
Secret:
void launch_missiles(int n)
{
printf("Launching %d missilesn", n);
// TODO: implement this function
}
void authenticate_and_launch(void)
{
int n_missiles = 2;
bool allowaccess = false;
char response[8];
printf("Secret: ");
gets(response);
if (strcmp(response, "Joshua") == 0)
allowaccess = true;
if (allowaccess) {
puts("Access granted");
launch_missiles(n_missiles);
}
if (!allowaccess)
puts("Access denied");
}
int main(void)
{
puts("WarGames MissileLauncher v0.1");
authenticate_and_launch();
puts("Operation complete");
}
Operation complete
$
Access granted
Launching 2 missiles
Operation complete
$ ./launch
WarGames MissileLauncher v0.1
Secret: globalthermonuclearwar
Access denied
Operation complete
$ ./launch
WarGames MissileLauncher v0.1
Secret: Joshua
David
Access granted
Launching 1869443685 missiles
Access denied
Huh?
Let's try executing the code
and see what happens.
Due to an overflow we seem to have
changed the value of allowaccess and
the value of n_missiles. Interesting!
$ ./launch
WarGames MissileLauncher v0.1
Secret:
void launch_missiles(int n)
{
printf("Launching %d missilesn", n);
// TODO: implement this function
}
void authenticate_and_launch(void)
{
int n_missiles = 2;
bool allowaccess = false;
char response[8];
printf("Secret: ");
gets(response);
if (strcmp(response, "Joshua") == 0)
allowaccess = true;
if (allowaccess) {
puts("Access granted");
launch_missiles(n_missiles);
}
if (!allowaccess)
puts("Access denied");
}
int main(void)
{
puts("WarGames MissileLauncher v0.1");
authenticate_and_launch();
puts("Operation complete");
}
Operation complete
$
Access granted
Launching 2 missiles
Operation complete
$ ./launch
WarGames MissileLauncher v0.1
Secret: globalthermonuclearwar
Access denied
Operation complete
$ ./launch
WarGames MissileLauncher v0.1
Secret: Joshua
David
Access granted
Launching 1869443685 missiles
Access denied
Huh?
Let's try executing the code
and see what happens.
Due to an overflow we seem to have
changed the value of allowaccess and
the value of n_missiles. Interesting!
... but why did it also print
Access denied?
void launch_missiles(int n)
{
printf("Launching %d missilesn", n);
// TODO: implement this function
}
void authenticate_and_launch(void)
{
int n_missiles = 2;
bool allowaccess = false;
char response[8];
printf("Secret: ");
gets(response);
if (strcmp(response, "Joshua") == 0)
allowaccess = true;
if (allowaccess) {
puts("Access granted");
launch_missiles(n_missiles);
}
if (!allowaccess)
puts("Access denied");
}
int main(void)
{
puts("WarGames MissileLauncher v0.1");
authenticate_and_launch();
puts("Operation complete");
}
$ ./launch
WarGames MissileLauncher v0.1
Secret: David
Access denied
Operation complete
$ ./launch
WarGames MissileLauncher v0.1
Secret: Joshua
Access granted
Launching 2 missiles
Operation complete
$ ./launch
WarGames MissileLauncher v0.1
Secret: globalthermonuclearwar
Access granted
Launching 1869443685 missiles
Access denied
Operation complete
$
void launch_missiles(int n)
{
printf("Launching %d missilesn", n);
// TODO: implement this function
}
void authenticate_and_launch(void)
{
int n_missiles = 2;
bool allowaccess = false;
char response[8];
printf("Secret: ");
gets(response);
if (strcmp(response, "Joshua") == 0)
allowaccess = true;
if (allowaccess) {
puts("Access granted");
launch_missiles(n_missiles);
}
if (!allowaccess)
puts("Access denied");
}
int main(void)
{
puts("WarGames MissileLauncher v0.1");
authenticate_and_launch();
puts("Operation complete");
}
$ ./launch
WarGames MissileLauncher v0.1
Secret: David
Access denied
Operation complete
$ ./launch
WarGames MissileLauncher v0.1
Secret: Joshua
Access granted
Launching 2 missiles
Operation complete
$ ./launch
WarGames MissileLauncher v0.1
Secret: globalthermonuclearwar
Access granted
Launching 1869443685 missiles
Access denied
Operation complete
$
What we just saw was an example of stack
buffer overflow, aka stack smashing.When
overwriting the response buffer we also
changed the memory location used by variable
allowaccess and n_missiles
void launch_missiles(int n)
{
printf("Launching %d missilesn", n);
// TODO: implement this function
}
void authenticate_and_launch(void)
{
int n_missiles = 2;
bool allowaccess = false;
char response[8];
printf("Secret: ");
gets(response);
if (strcmp(response, "Joshua") == 0)
allowaccess = true;
if (allowaccess) {
puts("Access granted");
launch_missiles(n_missiles);
}
if (!allowaccess)
puts("Access denied");
}
int main(void)
{
puts("WarGames MissileLauncher v0.1");
authenticate_and_launch();
puts("Operation complete");
}
$ ./launch
WarGames MissileLauncher v0.1
Secret: David
Access denied
Operation complete
$ ./launch
WarGames MissileLauncher v0.1
Secret: Joshua
Access granted
Launching 2 missiles
Operation complete
$ ./launch
WarGames MissileLauncher v0.1
Secret: globalthermonuclearwar
Access granted
Launching 1869443685 missiles
Access denied
Operation complete
$
C and C++ are languages that are mostly defined by
its behavior.The standards says very little about how
things should be implemented. Indeed, while it is
common to hear discussions about call stack when
talking about C and C++, it is worth noting that the
standards does not mention the concept at all.
What we just saw was an example of stack
buffer overflow, aka stack smashing.When
overwriting the response buffer we also
changed the memory location used by variable
allowaccess and n_missiles
void launch_missiles(int n)
{
printf("Launching %d missilesn", n);
// TODO: implement this function
}
void authenticate_and_launch(void)
{
int n_missiles = 2;
bool allowaccess = false;
char response[8];
printf("Secret: ");
gets(response);
if (strcmp(response, "Joshua") == 0)
allowaccess = true;
if (allowaccess) {
puts("Access granted");
launch_missiles(n_missiles);
}
if (!allowaccess)
puts("Access denied");
}
int main(void)
{
puts("WarGames MissileLauncher v0.1");
authenticate_and_launch();
puts("Operation complete");
}
$ ./launch
WarGames MissileLauncher v0.1
Secret: David
Access denied
Operation complete
$ ./launch
WarGames MissileLauncher v0.1
Secret: Joshua
Access granted
Launching 2 missiles
Operation complete
$ ./launch
WarGames MissileLauncher v0.1
Secret: globalthermonuclearwar
Access granted
Launching 1869443685 missiles
Access denied
Operation complete
$
C and C++ are languages that are mostly defined by
its behavior.The standards says very little about how
things should be implemented. Indeed, while it is
common to hear discussions about call stack when
talking about C and C++, it is worth noting that the
standards does not mention the concept at all.
We can learn a lot about C and C++ by
studying what happens when it executes. Here is
a detailed explanation about what actually
happened on my machine. Let's start from the
beginning...
What we just saw was an example of stack
buffer overflow, aka stack smashing.When
overwriting the response buffer we also
changed the memory location used by variable
allowaccess and n_missiles
void launch_missiles(int n)
{
printf("Launching %d missilesn", n);
// TODO: implement this function
}
void authenticate_and_launch(void)
{
int n_missiles = 2;
bool allowaccess = false;
char response[8];
printf("Secret: ");
gets(response);
if (strcmp(response, "Joshua") == 0)
allowaccess = true;
if (allowaccess) {
puts("Access granted");
launch_missiles(n_missiles);
}
if (!allowaccess)
puts("Access denied");
}
int main(void)
{
puts("WarGames MissileLauncher v0.1");
authenticate_and_launch();
puts("Operation complete");
}
void launch_missiles(int n)
{
printf("Launching %d missilesn", n);
// TODO: implement this function
}
void authenticate_and_launch(void)
{
int n_missiles = 2;
bool allowaccess = false;
char response[8];
printf("Secret: ");
gets(response);
if (strcmp(response, "Joshua") == 0)
allowaccess = true;
if (allowaccess) {
puts("Access granted");
launch_missiles(n_missiles);
}
if (!allowaccess)
puts("Access denied");
}
int main(void)
{
puts("WarGames MissileLauncher v0.1");
authenticate_and_launch();
puts("Operation complete");
}
main() is the entry point for the program.
void launch_missiles(int n)
{
printf("Launching %d missilesn", n);
// TODO: implement this function
}
void authenticate_and_launch(void)
{
int n_missiles = 2;
bool allowaccess = false;
char response[8];
printf("Secret: ");
gets(response);
if (strcmp(response, "Joshua") == 0)
allowaccess = true;
if (allowaccess) {
puts("Access granted");
launch_missiles(n_missiles);
}
if (!allowaccess)
puts("Access denied");
}
int main(void)
{
puts("WarGames MissileLauncher v0.1");
authenticate_and_launch();
puts("Operation complete");
}
main() is the entry point for the program.
void launch_missiles(int n)
{
printf("Launching %d missilesn", n);
// TODO: implement this function
}
void authenticate_and_launch(void)
{
int n_missiles = 2;
bool allowaccess = false;
char response[8];
printf("Secret: ");
gets(response);
if (strcmp(response, "Joshua") == 0)
allowaccess = true;
if (allowaccess) {
puts("Access granted");
launch_missiles(n_missiles);
}
if (!allowaccess)
puts("Access denied");
}
int main(void)
{
puts("WarGames MissileLauncher v0.1");
authenticate_and_launch();
puts("Operation complete");
}
main() is the entry point for the program.
At this point, a call stack has been
set up for us.
void launch_missiles(int n)
{
printf("Launching %d missilesn", n);
// TODO: implement this function
}
void authenticate_and_launch(void)
{
int n_missiles = 2;
bool allowaccess = false;
char response[8];
printf("Secret: ");
gets(response);
if (strcmp(response, "Joshua") == 0)
allowaccess = true;
if (allowaccess) {
puts("Access granted");
launch_missiles(n_missiles);
}
if (!allowaccess)
puts("Access denied");
}
int main(void)
{
puts("WarGames MissileLauncher v0.1");
authenticate_and_launch();
puts("Operation complete");
}
main() is the entry point for the program.
At this point, a call stack has been
set up for us.
high address
low address
void launch_missiles(int n)
{
printf("Launching %d missilesn", n);
// TODO: implement this function
}
void authenticate_and_launch(void)
{
int n_missiles = 2;
bool allowaccess = false;
char response[8];
printf("Secret: ");
gets(response);
if (strcmp(response, "Joshua") == 0)
allowaccess = true;
if (allowaccess) {
puts("Access granted");
launch_missiles(n_missiles);
}
if (!allowaccess)
puts("Access denied");
}
int main(void)
{
puts("WarGames MissileLauncher v0.1");
authenticate_and_launch();
puts("Operation complete");
}
main() is the entry point for the program.
At this point, a call stack has been
set up for us.
high address
low address
The calling function has pushed the address of
its next instruction to be executed on the stack,
just before it made a jmp into main()
void launch_missiles(int n)
{
printf("Launching %d missilesn", n);
// TODO: implement this function
}
void authenticate_and_launch(void)
{
int n_missiles = 2;
bool allowaccess = false;
char response[8];
printf("Secret: ");
gets(response);
if (strcmp(response, "Joshua") == 0)
allowaccess = true;
if (allowaccess) {
puts("Access granted");
launch_missiles(n_missiles);
}
if (!allowaccess)
puts("Access denied");
}
int main(void)
{
puts("WarGames MissileLauncher v0.1");
authenticate_and_launch();
puts("Operation complete");
}
main() is the entry point for the program.
At this point, a call stack has been
set up for us.
return address, next intruction in _starthigh address
low address
The calling function has pushed the address of
its next instruction to be executed on the stack,
just before it made a jmp into main()
void launch_missiles(int n)
{
printf("Launching %d missilesn", n);
// TODO: implement this function
}
void authenticate_and_launch(void)
{
int n_missiles = 2;
bool allowaccess = false;
char response[8];
printf("Secret: ");
gets(response);
if (strcmp(response, "Joshua") == 0)
allowaccess = true;
if (allowaccess) {
puts("Access granted");
launch_missiles(n_missiles);
}
if (!allowaccess)
puts("Access denied");
}
int main(void)
{
puts("WarGames MissileLauncher v0.1");
authenticate_and_launch();
puts("Operation complete");
}
main() is the entry point for the program.
At this point, a call stack has been
set up for us.
return address, next intruction in _starthigh address
low address
The calling function has pushed the address of
its next instruction to be executed on the stack,
just before it made a jmp into main()
The first thing that happens when entering
main(), is that the current base pointer is
pushed on to the stack.
void launch_missiles(int n)
{
printf("Launching %d missilesn", n);
// TODO: implement this function
}
void authenticate_and_launch(void)
{
int n_missiles = 2;
bool allowaccess = false;
char response[8];
printf("Secret: ");
gets(response);
if (strcmp(response, "Joshua") == 0)
allowaccess = true;
if (allowaccess) {
puts("Access granted");
launch_missiles(n_missiles);
}
if (!allowaccess)
puts("Access denied");
}
int main(void)
{
puts("WarGames MissileLauncher v0.1");
authenticate_and_launch();
puts("Operation complete");
}
main() is the entry point for the program.
At this point, a call stack has been
set up for us.
return address, next intruction in _starthigh address
low address
The calling function has pushed the address of
its next instruction to be executed on the stack,
just before it made a jmp into main()
The first thing that happens when entering
main(), is that the current base pointer is
pushed on to the stack.
Then the base pointer and stack pointer is
changed so main() get's it's own activation
frame.
void launch_missiles(int n)
{
printf("Launching %d missilesn", n);
// TODO: implement this function
}
void authenticate_and_launch(void)
{
int n_missiles = 2;
bool allowaccess = false;
char response[8];
printf("Secret: ");
gets(response);
if (strcmp(response, "Joshua") == 0)
allowaccess = true;
if (allowaccess) {
puts("Access granted");
launch_missiles(n_missiles);
}
if (!allowaccess)
puts("Access denied");
}
int main(void)
{
puts("WarGames MissileLauncher v0.1");
authenticate_and_launch();
puts("Operation complete");
}
main() is the entry point for the program.
At this point, a call stack has been
set up for us.
return address, next intruction in _start
pointer to stack frame for _start
high address
low address
The calling function has pushed the address of
its next instruction to be executed on the stack,
just before it made a jmp into main()
The first thing that happens when entering
main(), is that the current base pointer is
pushed on to the stack.
Then the base pointer and stack pointer is
changed so main() get's it's own activation
frame.
void launch_missiles(int n)
{
printf("Launching %d missilesn", n);
// TODO: implement this function
}
void authenticate_and_launch(void)
{
int n_missiles = 2;
bool allowaccess = false;
char response[8];
printf("Secret: ");
gets(response);
if (strcmp(response, "Joshua") == 0)
allowaccess = true;
if (allowaccess) {
puts("Access granted");
launch_missiles(n_missiles);
}
if (!allowaccess)
puts("Access denied");
}
int main(void)
{
puts("WarGames MissileLauncher v0.1");
authenticate_and_launch();
puts("Operation complete");
} return address, next intruction in _start
pointer to stack frame for _start
high address
low address
void launch_missiles(int n)
{
printf("Launching %d missilesn", n);
// TODO: implement this function
}
void authenticate_and_launch(void)
{
int n_missiles = 2;
bool allowaccess = false;
char response[8];
printf("Secret: ");
gets(response);
if (strcmp(response, "Joshua") == 0)
allowaccess = true;
if (allowaccess) {
puts("Access granted");
launch_missiles(n_missiles);
}
if (!allowaccess)
puts("Access denied");
}
int main(void)
{
puts("WarGames MissileLauncher v0.1");
authenticate_and_launch();
puts("Operation complete");
} return address, next intruction in _start
pointer to stack frame for _start
high address
low address
void launch_missiles(int n)
{
printf("Launching %d missilesn", n);
// TODO: implement this function
}
void authenticate_and_launch(void)
{
int n_missiles = 2;
bool allowaccess = false;
char response[8];
printf("Secret: ");
gets(response);
if (strcmp(response, "Joshua") == 0)
allowaccess = true;
if (allowaccess) {
puts("Access granted");
launch_missiles(n_missiles);
}
if (!allowaccess)
puts("Access denied");
}
int main(void)
{
puts("WarGames MissileLauncher v0.1");
authenticate_and_launch();
puts("Operation complete");
}
The first statement in main() is to call
puts() with a string.
return address, next intruction in _start
pointer to stack frame for _start
high address
low address
void launch_missiles(int n)
{
printf("Launching %d missilesn", n);
// TODO: implement this function
}
void authenticate_and_launch(void)
{
int n_missiles = 2;
bool allowaccess = false;
char response[8];
printf("Secret: ");
gets(response);
if (strcmp(response, "Joshua") == 0)
allowaccess = true;
if (allowaccess) {
puts("Access granted");
launch_missiles(n_missiles);
}
if (!allowaccess)
puts("Access denied");
}
int main(void)
{
puts("WarGames MissileLauncher v0.1");
authenticate_and_launch();
puts("Operation complete");
}
The first statement in main() is to call
puts() with a string.
return address, next intruction in _start
pointer to stack frame for _start
high address
low address
A pointer to the string is pushed on the stack,
this is the argument to puts()
void launch_missiles(int n)
{
printf("Launching %d missilesn", n);
// TODO: implement this function
}
void authenticate_and_launch(void)
{
int n_missiles = 2;
bool allowaccess = false;
char response[8];
printf("Secret: ");
gets(response);
if (strcmp(response, "Joshua") == 0)
allowaccess = true;
if (allowaccess) {
puts("Access granted");
launch_missiles(n_missiles);
}
if (!allowaccess)
puts("Access denied");
}
int main(void)
{
puts("WarGames MissileLauncher v0.1");
authenticate_and_launch();
puts("Operation complete");
}
The first statement in main() is to call
puts() with a string.
return address, next intruction in _start
pointer to stack frame for _start
high address
low address
A pointer to the string is pushed on the stack,
this is the argument to puts()
pointer to string "WarGames..."
void launch_missiles(int n)
{
printf("Launching %d missilesn", n);
// TODO: implement this function
}
void authenticate_and_launch(void)
{
int n_missiles = 2;
bool allowaccess = false;
char response[8];
printf("Secret: ");
gets(response);
if (strcmp(response, "Joshua") == 0)
allowaccess = true;
if (allowaccess) {
puts("Access granted");
launch_missiles(n_missiles);
}
if (!allowaccess)
puts("Access denied");
}
int main(void)
{
puts("WarGames MissileLauncher v0.1");
authenticate_and_launch();
puts("Operation complete");
}
The first statement in main() is to call
puts() with a string.
return address, next intruction in _start
pointer to stack frame for _start
high address
low address
A pointer to the string is pushed on the stack,
this is the argument to puts()
Then we push the return address, a memory
address pointing to the next instruction in
main()
pointer to string "WarGames..."
void launch_missiles(int n)
{
printf("Launching %d missilesn", n);
// TODO: implement this function
}
void authenticate_and_launch(void)
{
int n_missiles = 2;
bool allowaccess = false;
char response[8];
printf("Secret: ");
gets(response);
if (strcmp(response, "Joshua") == 0)
allowaccess = true;
if (allowaccess) {
puts("Access granted");
launch_missiles(n_missiles);
}
if (!allowaccess)
puts("Access denied");
}
int main(void)
{
puts("WarGames MissileLauncher v0.1");
authenticate_and_launch();
puts("Operation complete");
}
The first statement in main() is to call
puts() with a string.
return address, next intruction in _start
pointer to stack frame for _start
high address
low address
A pointer to the string is pushed on the stack,
this is the argument to puts()
Then we push the return address, a memory
address pointing to the next instruction in
main()
pointer to string "WarGames..."
return address, next intruction in main
void launch_missiles(int n)
{
printf("Launching %d missilesn", n);
// TODO: implement this function
}
void authenticate_and_launch(void)
{
int n_missiles = 2;
bool allowaccess = false;
char response[8];
printf("Secret: ");
gets(response);
if (strcmp(response, "Joshua") == 0)
allowaccess = true;
if (allowaccess) {
puts("Access granted");
launch_missiles(n_missiles);
}
if (!allowaccess)
puts("Access denied");
}
int main(void)
{
puts("WarGames MissileLauncher v0.1");
authenticate_and_launch();
puts("Operation complete");
}
The first statement in main() is to call
puts() with a string.
return address, next intruction in _start
pointer to stack frame for _start
high address
low address
A pointer to the string is pushed on the stack,
this is the argument to puts()
Then we push the return address, a memory
address pointing to the next instruction in
main()
pointer to string "WarGames..."
return address, next intruction in main
The puts() function will do whatever it needs
to do, just making sure that the base pointer is
restored before using the return address to
jump back to the next instruction in main()
void launch_missiles(int n)
{
printf("Launching %d missilesn", n);
// TODO: implement this function
}
void authenticate_and_launch(void)
{
int n_missiles = 2;
bool allowaccess = false;
char response[8];
printf("Secret: ");
gets(response);
if (strcmp(response, "Joshua") == 0)
allowaccess = true;
if (allowaccess) {
puts("Access granted");
launch_missiles(n_missiles);
}
if (!allowaccess)
puts("Access denied");
}
int main(void)
{
puts("WarGames MissileLauncher v0.1");
authenticate_and_launch();
puts("Operation complete");
}
The first statement in main() is to call
puts() with a string.
return address, next intruction in _start
pointer to stack frame for _start
high address
low address
A pointer to the string is pushed on the stack,
this is the argument to puts()
Then we push the return address, a memory
address pointing to the next instruction in
main()
pointer to string "WarGames..."
return address, next intruction in main
The puts() function will do whatever it needs
to do, just making sure that the base pointer is
restored before using the return address to
jump back to the next instruction in main()
(whatever puts() needs to do)
void launch_missiles(int n)
{
printf("Launching %d missilesn", n);
// TODO: implement this function
}
void authenticate_and_launch(void)
{
int n_missiles = 2;
bool allowaccess = false;
char response[8];
printf("Secret: ");
gets(response);
if (strcmp(response, "Joshua") == 0)
allowaccess = true;
if (allowaccess) {
puts("Access granted");
launch_missiles(n_missiles);
}
if (!allowaccess)
puts("Access denied");
}
int main(void)
{
puts("WarGames MissileLauncher v0.1");
authenticate_and_launch();
puts("Operation complete");
} return address, next intruction in _start
pointer to stack frame for _start
high address
low address
pointer to string "WarGames..."
return address, next intruction in main
void launch_missiles(int n)
{
printf("Launching %d missilesn", n);
// TODO: implement this function
}
void authenticate_and_launch(void)
{
int n_missiles = 2;
bool allowaccess = false;
char response[8];
printf("Secret: ");
gets(response);
if (strcmp(response, "Joshua") == 0)
allowaccess = true;
if (allowaccess) {
puts("Access granted");
launch_missiles(n_missiles);
}
if (!allowaccess)
puts("Access denied");
}
int main(void)
{
puts("WarGames MissileLauncher v0.1");
authenticate_and_launch();
puts("Operation complete");
} return address, next intruction in _start
pointer to stack frame for _start
high address
low address
pointer to string "WarGames..."
return address, next intruction in main
The stack is restored and the next statement
will be executed.
void launch_missiles(int n)
{
printf("Launching %d missilesn", n);
// TODO: implement this function
}
void authenticate_and_launch(void)
{
int n_missiles = 2;
bool allowaccess = false;
char response[8];
printf("Secret: ");
gets(response);
if (strcmp(response, "Joshua") == 0)
allowaccess = true;
if (allowaccess) {
puts("Access granted");
launch_missiles(n_missiles);
}
if (!allowaccess)
puts("Access denied");
}
int main(void)
{
puts("WarGames MissileLauncher v0.1");
authenticate_and_launch();
puts("Operation complete");
} return address, next intruction in _start
pointer to stack frame for _start
high address
low address
The stack is restored and the next statement
will be executed.
void launch_missiles(int n)
{
printf("Launching %d missilesn", n);
// TODO: implement this function
}
void authenticate_and_launch(void)
{
int n_missiles = 2;
bool allowaccess = false;
char response[8];
printf("Secret: ");
gets(response);
if (strcmp(response, "Joshua") == 0)
allowaccess = true;
if (allowaccess) {
puts("Access granted");
launch_missiles(n_missiles);
}
if (!allowaccess)
puts("Access denied");
}
int main(void)
{
puts("WarGames MissileLauncher v0.1");
authenticate_and_launch();
puts("Operation complete");
} return address, next intruction in _start
pointer to stack frame for _start
high address
low address
The stack is restored and the next statement
will be executed.
void launch_missiles(int n)
{
printf("Launching %d missilesn", n);
// TODO: implement this function
}
void authenticate_and_launch(void)
{
int n_missiles = 2;
bool allowaccess = false;
char response[8];
printf("Secret: ");
gets(response);
if (strcmp(response, "Joshua") == 0)
allowaccess = true;
if (allowaccess) {
puts("Access granted");
launch_missiles(n_missiles);
}
if (!allowaccess)
puts("Access denied");
}
int main(void)
{
puts("WarGames MissileLauncher v0.1");
authenticate_and_launch();
puts("Operation complete");
} return address, next intruction in _start
pointer to stack frame for _start
high address
low address
Now we prepare for calling
authenticate_and_launch()
by pushing the return address of the next
statement to be executed in main() , and then
we jump into authenticate_and_launch()
The stack is restored and the next statement
will be executed.
void launch_missiles(int n)
{
printf("Launching %d missilesn", n);
// TODO: implement this function
}
void authenticate_and_launch(void)
{
int n_missiles = 2;
bool allowaccess = false;
char response[8];
printf("Secret: ");
gets(response);
if (strcmp(response, "Joshua") == 0)
allowaccess = true;
if (allowaccess) {
puts("Access granted");
launch_missiles(n_missiles);
}
if (!allowaccess)
puts("Access denied");
}
int main(void)
{
puts("WarGames MissileLauncher v0.1");
authenticate_and_launch();
puts("Operation complete");
} return address, next intruction in _start
pointer to stack frame for _start
high address
low address
Now we prepare for calling
authenticate_and_launch()
by pushing the return address of the next
statement to be executed in main() , and then
we jump into authenticate_and_launch()
return address, next intruction in _main
The stack is restored and the next statement
will be executed.
void launch_missiles(int n)
{
printf("Launching %d missilesn", n);
// TODO: implement this function
}
void authenticate_and_launch(void)
{
int n_missiles = 2;
bool allowaccess = false;
char response[8];
printf("Secret: ");
gets(response);
if (strcmp(response, "Joshua") == 0)
allowaccess = true;
if (allowaccess) {
puts("Access granted");
launch_missiles(n_missiles);
}
if (!allowaccess)
puts("Access denied");
}
int main(void)
{
puts("WarGames MissileLauncher v0.1");
authenticate_and_launch();
puts("Operation complete");
} return address, next intruction in _start
pointer to stack frame for _start
high address
low address
Now we prepare for calling
authenticate_and_launch()
by pushing the return address of the next
statement to be executed in main() , and then
we jump into authenticate_and_launch()
return address, next intruction in _main
The stack is restored and the next statement
will be executed.
void launch_missiles(int n)
{
printf("Launching %d missilesn", n);
// TODO: implement this function
}
void authenticate_and_launch(void)
{
int n_missiles = 2;
bool allowaccess = false;
char response[8];
printf("Secret: ");
gets(response);
if (strcmp(response, "Joshua") == 0)
allowaccess = true;
if (allowaccess) {
puts("Access granted");
launch_missiles(n_missiles);
}
if (!allowaccess)
puts("Access denied");
}
int main(void)
{
puts("WarGames MissileLauncher v0.1");
authenticate_and_launch();
puts("Operation complete");
} return address, next intruction in _start
pointer to stack frame for _start
high address
low address
return address, next intruction in _main
void launch_missiles(int n)
{
printf("Launching %d missilesn", n);
// TODO: implement this function
}
void authenticate_and_launch(void)
{
int n_missiles = 2;
bool allowaccess = false;
char response[8];
printf("Secret: ");
gets(response);
if (strcmp(response, "Joshua") == 0)
allowaccess = true;
if (allowaccess) {
puts("Access granted");
launch_missiles(n_missiles);
}
if (!allowaccess)
puts("Access denied");
}
int main(void)
{
puts("WarGames MissileLauncher v0.1");
authenticate_and_launch();
puts("Operation complete");
} return address, next intruction in _start
pointer to stack frame for _start
high address
low address
Create a new stack frame, before allocating
space for the local variables on the stack.
return address, next intruction in _main
void launch_missiles(int n)
{
printf("Launching %d missilesn", n);
// TODO: implement this function
}
void authenticate_and_launch(void)
{
int n_missiles = 2;
bool allowaccess = false;
char response[8];
printf("Secret: ");
gets(response);
if (strcmp(response, "Joshua") == 0)
allowaccess = true;
if (allowaccess) {
puts("Access granted");
launch_missiles(n_missiles);
}
if (!allowaccess)
puts("Access denied");
}
int main(void)
{
puts("WarGames MissileLauncher v0.1");
authenticate_and_launch();
puts("Operation complete");
} return address, next intruction in _start
pointer to stack frame for _start
high address
low address
Create a new stack frame, before allocating
space for the local variables on the stack.
return address, next intruction in _main
pointer to stack frame for _main
void launch_missiles(int n)
{
printf("Launching %d missilesn", n);
// TODO: implement this function
}
void authenticate_and_launch(void)
{
int n_missiles = 2;
bool allowaccess = false;
char response[8];
printf("Secret: ");
gets(response);
if (strcmp(response, "Joshua") == 0)
allowaccess = true;
if (allowaccess) {
puts("Access granted");
launch_missiles(n_missiles);
}
if (!allowaccess)
puts("Access denied");
}
int main(void)
{
puts("WarGames MissileLauncher v0.1");
authenticate_and_launch();
puts("Operation complete");
} return address, next intruction in _start
pointer to stack frame for _start
high address
low address
return address, next intruction in _main
pointer to stack frame for _main
Create a new stack frame, before allocating
space for the local variables on the stack.
void launch_missiles(int n)
{
printf("Launching %d missilesn", n);
// TODO: implement this function
}
void authenticate_and_launch(void)
{
int n_missiles = 2;
bool allowaccess = false;
char response[8];
printf("Secret: ");
gets(response);
if (strcmp(response, "Joshua") == 0)
allowaccess = true;
if (allowaccess) {
puts("Access granted");
launch_missiles(n_missiles);
}
if (!allowaccess)
puts("Access denied");
}
int main(void)
{
puts("WarGames MissileLauncher v0.1");
authenticate_and_launch();
puts("Operation complete");
} return address, next intruction in _start
pointer to stack frame for _start
high address
low address
return address, next intruction in _main
pointer to stack frame for _main
allowaccess (1 byte)
Create a new stack frame, before allocating
space for the local variables on the stack.
void launch_missiles(int n)
{
printf("Launching %d missilesn", n);
// TODO: implement this function
}
void authenticate_and_launch(void)
{
int n_missiles = 2;
bool allowaccess = false;
char response[8];
printf("Secret: ");
gets(response);
if (strcmp(response, "Joshua") == 0)
allowaccess = true;
if (allowaccess) {
puts("Access granted");
launch_missiles(n_missiles);
}
if (!allowaccess)
puts("Access denied");
}
int main(void)
{
puts("WarGames MissileLauncher v0.1");
authenticate_and_launch();
puts("Operation complete");
} return address, next intruction in _start
pointer to stack frame for _start
high address
low address
return address, next intruction in _main
pointer to stack frame for _main
allowaccess (1 byte)
n_missiles (4 bytes)
Create a new stack frame, before allocating
space for the local variables on the stack.
void launch_missiles(int n)
{
printf("Launching %d missilesn", n);
// TODO: implement this function
}
void authenticate_and_launch(void)
{
int n_missiles = 2;
bool allowaccess = false;
char response[8];
printf("Secret: ");
gets(response);
if (strcmp(response, "Joshua") == 0)
allowaccess = true;
if (allowaccess) {
puts("Access granted");
launch_missiles(n_missiles);
}
if (!allowaccess)
puts("Access denied");
}
int main(void)
{
puts("WarGames MissileLauncher v0.1");
authenticate_and_launch();
puts("Operation complete");
} return address, next intruction in _start
pointer to stack frame for _start
high address
low address
return address, next intruction in _main
pointer to stack frame for _main
allowaccess (1 byte)
n_missiles (4 bytes)
response (8 bytes)
Create a new stack frame, before allocating
space for the local variables on the stack.
void launch_missiles(int n)
{
printf("Launching %d missilesn", n);
// TODO: implement this function
}
void authenticate_and_launch(void)
{
int n_missiles = 2;
bool allowaccess = false;
char response[8];
printf("Secret: ");
gets(response);
if (strcmp(response, "Joshua") == 0)
allowaccess = true;
if (allowaccess) {
puts("Access granted");
launch_missiles(n_missiles);
}
if (!allowaccess)
puts("Access denied");
}
int main(void)
{
puts("WarGames MissileLauncher v0.1");
authenticate_and_launch();
puts("Operation complete");
} return address, next intruction in _start
pointer to stack frame for _start
high address
low address
return address, next intruction in _main
pointer to stack frame for _main
allowaccess (1 byte)
n_missiles (4 bytes)
response (8 bytes)
Hey, wait a minute... should not
the stack variables be allocated in
correct order?
Create a new stack frame, before allocating
space for the local variables on the stack.
void launch_missiles(int n)
{
printf("Launching %d missilesn", n);
// TODO: implement this function
}
void authenticate_and_launch(void)
{
int n_missiles = 2;
bool allowaccess = false;
char response[8];
printf("Secret: ");
gets(response);
if (strcmp(response, "Joshua") == 0)
allowaccess = true;
if (allowaccess) {
puts("Access granted");
launch_missiles(n_missiles);
}
if (!allowaccess)
puts("Access denied");
}
int main(void)
{
puts("WarGames MissileLauncher v0.1");
authenticate_and_launch();
puts("Operation complete");
} return address, next intruction in _start
pointer to stack frame for _start
high address
low address
return address, next intruction in _main
pointer to stack frame for _main
allowaccess (1 byte)
n_missiles (4 bytes)
response (8 bytes)
There is no "correct order" here. In this case,
the compiler is free to store objects of
automatic storage duration (the correct name
for "stack variables") in any order. Indeed, it can
keep all of them in registers or ignore them
completely as long as the external behavior of
the program is the same.
Hey, wait a minute... should not
the stack variables be allocated in
correct order?
Create a new stack frame, before allocating
space for the local variables on the stack.
void launch_missiles(int n)
{
printf("Launching %d missilesn", n);
// TODO: implement this function
}
void authenticate_and_launch(void)
{
int n_missiles = 2;
bool allowaccess = false;
char response[8];
printf("Secret: ");
gets(response);
if (strcmp(response, "Joshua") == 0)
allowaccess = true;
if (allowaccess) {
puts("Access granted");
launch_missiles(n_missiles);
}
if (!allowaccess)
puts("Access denied");
}
int main(void)
{
puts("WarGames MissileLauncher v0.1");
authenticate_and_launch();
puts("Operation complete");
} return address, next intruction in _start
pointer to stack frame for _start
high address
low address
return address, next intruction in _main
pointer to stack frame for _main
allowaccess (1 byte)
n_missiles (4 bytes)
response (8 bytes)
void launch_missiles(int n)
{
printf("Launching %d missilesn", n);
// TODO: implement this function
}
void authenticate_and_launch(void)
{
int n_missiles = 2;
bool allowaccess = false;
char response[8];
printf("Secret: ");
gets(response);
if (strcmp(response, "Joshua") == 0)
allowaccess = true;
if (allowaccess) {
puts("Access granted");
launch_missiles(n_missiles);
}
if (!allowaccess)
puts("Access denied");
}
int main(void)
{
puts("WarGames MissileLauncher v0.1");
authenticate_and_launch();
puts("Operation complete");
} return address, next intruction in _start
pointer to stack frame for _start
high address
low address
return address, next intruction in _main
pointer to stack frame for _main
allowaccess (1 byte)
n_missiles (4 bytes)
response (8 bytes)
void launch_missiles(int n)
{
printf("Launching %d missilesn", n);
// TODO: implement this function
}
void authenticate_and_launch(void)
{
int n_missiles = 2;
bool allowaccess = false;
char response[8];
printf("Secret: ");
gets(response);
if (strcmp(response, "Joshua") == 0)
allowaccess = true;
if (allowaccess) {
puts("Access granted");
launch_missiles(n_missiles);
}
if (!allowaccess)
puts("Access denied");
}
int main(void)
{
puts("WarGames MissileLauncher v0.1");
authenticate_and_launch();
puts("Operation complete");
} return address, next intruction in _start
pointer to stack frame for _start
high address
low address
Then we call printf() with an argument.
return address, next intruction in _main
pointer to stack frame for _main
allowaccess (1 byte)
n_missiles (4 bytes)
response (8 bytes)
void launch_missiles(int n)
{
printf("Launching %d missilesn", n);
// TODO: implement this function
}
void authenticate_and_launch(void)
{
int n_missiles = 2;
bool allowaccess = false;
char response[8];
printf("Secret: ");
gets(response);
if (strcmp(response, "Joshua") == 0)
allowaccess = true;
if (allowaccess) {
puts("Access granted");
launch_missiles(n_missiles);
}
if (!allowaccess)
puts("Access denied");
}
int main(void)
{
puts("WarGames MissileLauncher v0.1");
authenticate_and_launch();
puts("Operation complete");
} return address, next intruction in _start
pointer to stack frame for _start
high address
low address
Then we call printf() with an argument.
return address, next intruction in _main
pointer to stack frame for _main
pointer to string "Secret: "
allowaccess (1 byte)
n_missiles (4 bytes)
response (8 bytes)
void launch_missiles(int n)
{
printf("Launching %d missilesn", n);
// TODO: implement this function
}
void authenticate_and_launch(void)
{
int n_missiles = 2;
bool allowaccess = false;
char response[8];
printf("Secret: ");
gets(response);
if (strcmp(response, "Joshua") == 0)
allowaccess = true;
if (allowaccess) {
puts("Access granted");
launch_missiles(n_missiles);
}
if (!allowaccess)
puts("Access denied");
}
int main(void)
{
puts("WarGames MissileLauncher v0.1");
authenticate_and_launch();
puts("Operation complete");
} return address, next intruction in _start
pointer to stack frame for _start
high address
low address
Then we call printf() with an argument.
return address, next intruction in _main
pointer to stack frame for _main
return address, authenticate_and_launch()
pointer to string "Secret: "
allowaccess (1 byte)
n_missiles (4 bytes)
response (8 bytes)
void launch_missiles(int n)
{
printf("Launching %d missilesn", n);
// TODO: implement this function
}
void authenticate_and_launch(void)
{
int n_missiles = 2;
bool allowaccess = false;
char response[8];
printf("Secret: ");
gets(response);
if (strcmp(response, "Joshua") == 0)
allowaccess = true;
if (allowaccess) {
puts("Access granted");
launch_missiles(n_missiles);
}
if (!allowaccess)
puts("Access denied");
}
int main(void)
{
puts("WarGames MissileLauncher v0.1");
authenticate_and_launch();
puts("Operation complete");
} return address, next intruction in _start
pointer to stack frame for _start
high address
low address
Then we call printf() with an argument.
return address, next intruction in _main
pointer to stack frame for _main
return address, authenticate_and_launch()
pointer to string "Secret: "
(whatever printf() needs to do)
allowaccess (1 byte)
n_missiles (4 bytes)
response (8 bytes)
void launch_missiles(int n)
{
printf("Launching %d missilesn", n);
// TODO: implement this function
}
void authenticate_and_launch(void)
{
int n_missiles = 2;
bool allowaccess = false;
char response[8];
printf("Secret: ");
gets(response);
if (strcmp(response, "Joshua") == 0)
allowaccess = true;
if (allowaccess) {
puts("Access granted");
launch_missiles(n_missiles);
}
if (!allowaccess)
puts("Access denied");
}
int main(void)
{
puts("WarGames MissileLauncher v0.1");
authenticate_and_launch();
puts("Operation complete");
} return address, next intruction in _start
pointer to stack frame for _start
high address
low address
Then we call printf() with an argument.
return address, next intruction in _main
pointer to stack frame for _main
return address, authenticate_and_launch()
pointer to string "Secret: "
(whatever printf() needs to do)
After the prompt has been written to the
standard output stream.The stack is cleaned up
and we get ready to execute the next
statement.
allowaccess (1 byte)
n_missiles (4 bytes)
response (8 bytes)
void launch_missiles(int n)
{
printf("Launching %d missilesn", n);
// TODO: implement this function
}
void authenticate_and_launch(void)
{
int n_missiles = 2;
bool allowaccess = false;
char response[8];
printf("Secret: ");
gets(response);
if (strcmp(response, "Joshua") == 0)
allowaccess = true;
if (allowaccess) {
puts("Access granted");
launch_missiles(n_missiles);
}
if (!allowaccess)
puts("Access denied");
}
int main(void)
{
puts("WarGames MissileLauncher v0.1");
authenticate_and_launch();
puts("Operation complete");
} return address, next intruction in _start
pointer to stack frame for _start
high address
low address
return address, next intruction in _main
pointer to stack frame for _main
allowaccess (1 byte)
n_missiles (4 bytes)
response (8 bytes)
return address, authenticate_and_launch()
pointer to string "Secret: "
(whatever printf() needs to do)
void launch_missiles(int n)
{
printf("Launching %d missilesn", n);
// TODO: implement this function
}
void authenticate_and_launch(void)
{
int n_missiles = 2;
bool allowaccess = false;
char response[8];
printf("Secret: ");
gets(response);
if (strcmp(response, "Joshua") == 0)
allowaccess = true;
if (allowaccess) {
puts("Access granted");
launch_missiles(n_missiles);
}
if (!allowaccess)
puts("Access denied");
}
int main(void)
{
puts("WarGames MissileLauncher v0.1");
authenticate_and_launch();
puts("Operation complete");
} return address, next intruction in _start
pointer to stack frame for _start
high address
low address
return address, next intruction in _main
pointer to stack frame for _main
allowaccess (1 byte)
n_missiles (4 bytes)
response (8 bytes)
void launch_missiles(int n)
{
printf("Launching %d missilesn", n);
// TODO: implement this function
}
void authenticate_and_launch(void)
{
int n_missiles = 2;
bool allowaccess = false;
char response[8];
printf("Secret: ");
gets(response);
if (strcmp(response, "Joshua") == 0)
allowaccess = true;
if (allowaccess) {
puts("Access granted");
launch_missiles(n_missiles);
}
if (!allowaccess)
puts("Access denied");
}
int main(void)
{
puts("WarGames MissileLauncher v0.1");
authenticate_and_launch();
puts("Operation complete");
} return address, next intruction in _start
pointer to stack frame for _start
high address
low address
First the pointer to the response buffer is
pushed on stack.
return address, next intruction in _main
pointer to stack frame for _main
allowaccess (1 byte)
n_missiles (4 bytes)
response (8 bytes)
void launch_missiles(int n)
{
printf("Launching %d missilesn", n);
// TODO: implement this function
}
void authenticate_and_launch(void)
{
int n_missiles = 2;
bool allowaccess = false;
char response[8];
printf("Secret: ");
gets(response);
if (strcmp(response, "Joshua") == 0)
allowaccess = true;
if (allowaccess) {
puts("Access granted");
launch_missiles(n_missiles);
}
if (!allowaccess)
puts("Access denied");
}
int main(void)
{
puts("WarGames MissileLauncher v0.1");
authenticate_and_launch();
puts("Operation complete");
} return address, next intruction in _start
pointer to stack frame for _start
high address
low address
First the pointer to the response buffer is
pushed on stack.
return address, next intruction in _main
pointer to stack frame for _main
pointer to the response buffer
allowaccess (1 byte)
n_missiles (4 bytes)
response (8 bytes)
void launch_missiles(int n)
{
printf("Launching %d missilesn", n);
// TODO: implement this function
}
void authenticate_and_launch(void)
{
int n_missiles = 2;
bool allowaccess = false;
char response[8];
printf("Secret: ");
gets(response);
if (strcmp(response, "Joshua") == 0)
allowaccess = true;
if (allowaccess) {
puts("Access granted");
launch_missiles(n_missiles);
}
if (!allowaccess)
puts("Access denied");
}
int main(void)
{
puts("WarGames MissileLauncher v0.1");
authenticate_and_launch();
puts("Operation complete");
} return address, next intruction in _start
pointer to stack frame for _start
high address
low address
First the pointer to the response buffer is
pushed on stack.
return address, next intruction in _main
pointer to stack frame for _main
pointer to the response buffer
allowaccess (1 byte)
n_missiles (4 bytes)
response (8 bytes)
Then the return address. Before jumping into
gets()
void launch_missiles(int n)
{
printf("Launching %d missilesn", n);
// TODO: implement this function
}
void authenticate_and_launch(void)
{
int n_missiles = 2;
bool allowaccess = false;
char response[8];
printf("Secret: ");
gets(response);
if (strcmp(response, "Joshua") == 0)
allowaccess = true;
if (allowaccess) {
puts("Access granted");
launch_missiles(n_missiles);
}
if (!allowaccess)
puts("Access denied");
}
int main(void)
{
puts("WarGames MissileLauncher v0.1");
authenticate_and_launch();
puts("Operation complete");
} return address, next intruction in _start
pointer to stack frame for _start
high address
low address
First the pointer to the response buffer is
pushed on stack.
return address, next intruction in _main
pointer to stack frame for _main
pointer to the response buffer
return address, authenticate_and_launch()
allowaccess (1 byte)
n_missiles (4 bytes)
response (8 bytes)
Then the return address. Before jumping into
gets()
void launch_missiles(int n)
{
printf("Launching %d missilesn", n);
// TODO: implement this function
}
void authenticate_and_launch(void)
{
int n_missiles = 2;
bool allowaccess = false;
char response[8];
printf("Secret: ");
gets(response);
if (strcmp(response, "Joshua") == 0)
allowaccess = true;
if (allowaccess) {
puts("Access granted");
launch_missiles(n_missiles);
}
if (!allowaccess)
puts("Access denied");
}
int main(void)
{
puts("WarGames MissileLauncher v0.1");
authenticate_and_launch();
puts("Operation complete");
} return address, next intruction in _start
pointer to stack frame for _start
high address
low address
First the pointer to the response buffer is
pushed on stack.
return address, next intruction in _main
pointer to stack frame for _main
pointer to the response buffer
return address, authenticate_and_launch()
(whatever gets() needs to do)
allowaccess (1 byte)
n_missiles (4 bytes)
response (8 bytes)
Then the return address. Before jumping into
gets()
void launch_missiles(int n)
{
printf("Launching %d missilesn", n);
// TODO: implement this function
}
void authenticate_and_launch(void)
{
int n_missiles = 2;
bool allowaccess = false;
char response[8];
printf("Secret: ");
gets(response);
if (strcmp(response, "Joshua") == 0)
allowaccess = true;
if (allowaccess) {
puts("Access granted");
launch_missiles(n_missiles);
}
if (!allowaccess)
puts("Access denied");
}
int main(void)
{
puts("WarGames MissileLauncher v0.1");
authenticate_and_launch();
puts("Operation complete");
} return address, next intruction in _start
pointer to stack frame for _start
high address
low address
First the pointer to the response buffer is
pushed on stack.
return address, next intruction in _main
pointer to stack frame for _main
gets() will wait for input from the standard
input stream. Each character will be poked
sequentally into the response buffer until a
newline character, end-of-line or some kind of
error occurs.Then, before returning it will
append a '0' character to the buffer.
pointer to the response buffer
return address, authenticate_and_launch()
(whatever gets() needs to do)
allowaccess (1 byte)
n_missiles (4 bytes)
response (8 bytes)
Then the return address. Before jumping into
gets()
void launch_missiles(int n)
{
printf("Launching %d missilesn", n);
// TODO: implement this function
}
void authenticate_and_launch(void)
{
int n_missiles = 2;
bool allowaccess = false;
char response[8];
printf("Secret: ");
gets(response);
if (strcmp(response, "Joshua") == 0)
allowaccess = true;
if (allowaccess) {
puts("Access granted");
launch_missiles(n_missiles);
}
if (!allowaccess)
puts("Access denied");
}
int main(void)
{
puts("WarGames MissileLauncher v0.1");
authenticate_and_launch();
puts("Operation complete");
} return address, next intruction in _start
pointer to stack frame for _start
high address
low address
First the pointer to the response buffer is
pushed on stack.
return address, next intruction in _main
pointer to stack frame for _main
gets() will wait for input from the standard
input stream. Each character will be poked
sequentally into the response buffer until a
newline character, end-of-line or some kind of
error occurs.Then, before returning it will
append a '0' character to the buffer.
pointer to the response buffer
return address, authenticate_and_launch()
(whatever gets() needs to do)
If the input is 8 characters or more, then the
response buffer allocated on the stack is not big
enough, and in this case the data storage of the
other variables will be overwritten.
allowaccess (1 byte)
n_missiles (4 bytes)
response (8 bytes)
Then the return address. Before jumping into
gets()
void launch_missiles(int n)
{
printf("Launching %d missilesn", n);
// TODO: implement this function
}
void authenticate_and_launch(void)
{
int n_missiles = 2;
bool allowaccess = false;
char response[8];
printf("Secret: ");
gets(response);
if (strcmp(response, "Joshua") == 0)
allowaccess = true;
if (allowaccess) {
puts("Access granted");
launch_missiles(n_missiles);
}
if (!allowaccess)
puts("Access denied");
}
int main(void)
{
puts("WarGames MissileLauncher v0.1");
authenticate_and_launch();
puts("Operation complete");
}
allowaccess (1 byte)
response (8 bytes)
n_missiles (4 bytes)
return address, next intruction in _start
pointer to stack frame for _start
high address
low address
return address, next intruction in _main
pointer to stack frame for _main
pointer to the response buffer
return address, authenticate_and_launch()
(whatever gets() needs to do)
void launch_missiles(int n)
{
printf("Launching %d missilesn", n);
// TODO: implement this function
}
void authenticate_and_launch(void)
{
int n_missiles = 2;
bool allowaccess = false;
char response[8];
printf("Secret: ");
gets(response);
if (strcmp(response, "Joshua") == 0)
allowaccess = true;
if (allowaccess) {
puts("Access granted");
launch_missiles(n_missiles);
}
if (!allowaccess)
puts("Access denied");
}
int main(void)
{
puts("WarGames MissileLauncher v0.1");
authenticate_and_launch();
puts("Operation complete");
}
allowaccess (1 byte)
response (8 bytes)
n_missiles (4 bytes)
return address, next intruction in _start
pointer to stack frame for _start
high address
low address
return address, next intruction in _main
pointer to stack frame for _main
pointer to the response buffer
return address, authenticate_and_launch()
(whatever gets() needs to do)
Here is the exact stack data I got one time
I executed the code on my machine.
void launch_missiles(int n)
{
printf("Launching %d missilesn", n);
// TODO: implement this function
}
void authenticate_and_launch(void)
{
int n_missiles = 2;
bool allowaccess = false;
char response[8];
printf("Secret: ");
gets(response);
if (strcmp(response, "Joshua") == 0)
allowaccess = true;
if (allowaccess) {
puts("Access granted");
launch_missiles(n_missiles);
}
if (!allowaccess)
puts("Access denied");
}
int main(void)
{
puts("WarGames MissileLauncher v0.1");
authenticate_and_launch();
puts("Operation complete");
}
allowaccess (1 byte)
response (8 bytes)
n_missiles (4 bytes)
return address, next intruction in _start
pointer to stack frame for _start
high address
low address
return address, next intruction in _main
pointer to stack frame for _main
pointer to the response buffer
return address, authenticate_and_launch()
(whatever gets() needs to do)
0x50 0xfa 0xff 0xbf
0x00 0x40 0xfc 0xb7
0x00 0x00 0x00 0x00
0x00 0x39 0xe1 0xb7
0x88 0xfa 0xff 0xbf
0xa0 0x29 0xff 0xb7
0x02 0x00 0x00 0x00
0x00 0x40 0xfc 0x00
0x00 0x00 0x00 0x00
0x00 0x00 0x00 0x00
0x88 0xfa 0xff 0xbf
0x5b 0x85 0x04 0x08
0xbffffa40
0xbffffa6c
Here is the exact stack data I got one time
I executed the code on my machine.
void launch_missiles(int n)
{
printf("Launching %d missilesn", n);
// TODO: implement this function
}
void authenticate_and_launch(void)
{
int n_missiles = 2;
bool allowaccess = false;
char response[8];
printf("Secret: ");
gets(response);
if (strcmp(response, "Joshua") == 0)
allowaccess = true;
if (allowaccess) {
puts("Access granted");
launch_missiles(n_missiles);
}
if (!allowaccess)
puts("Access denied");
}
int main(void)
{
puts("WarGames MissileLauncher v0.1");
authenticate_and_launch();
puts("Operation complete");
}
allowaccess (1 byte)
response (8 bytes)
n_missiles (4 bytes)
return address, next intruction in _start
pointer to stack frame for _start
high address
low address
return address, next intruction in _main
pointer to stack frame for _main
pointer to the response buffer
return address, authenticate_and_launch()
(whatever gets() needs to do)
0x50 0xfa 0xff 0xbf
0x00 0x40 0xfc 0xb7
0x00 0x00 0x00 0x00
0x00 0x39 0xe1 0xb7
0x88 0xfa 0xff 0xbf
0xa0 0x29 0xff 0xb7
0x02 0x00 0x00 0x00
0x00 0x40 0xfc 0x00
0x00 0x00 0x00 0x00
0x00 0x00 0x00 0x00
0x88 0xfa 0xff 0xbf
0x5b 0x85 0x04 0x08
0xbffffa40
0xbffffa6c
Here is the exact stack data I got one time
I executed the code on my machine.
A lot of this is just padding due to
alignment issues.
void launch_missiles(int n)
{
printf("Launching %d missilesn", n);
// TODO: implement this function
}
void authenticate_and_launch(void)
{
int n_missiles = 2;
bool allowaccess = false;
char response[8];
printf("Secret: ");
gets(response);
if (strcmp(response, "Joshua") == 0)
allowaccess = true;
if (allowaccess) {
puts("Access granted");
launch_missiles(n_missiles);
}
if (!allowaccess)
puts("Access denied");
}
int main(void)
{
puts("WarGames MissileLauncher v0.1");
authenticate_and_launch();
puts("Operation complete");
}
allowaccess (1 byte)
response (8 bytes)
n_missiles (4 bytes)
return address, next intruction in _start
pointer to stack frame for _start
high address
low address
return address, next intruction in _main
pointer to stack frame for _main
pointer to the response buffer
return address, authenticate_and_launch()
(whatever gets() needs to do)
0x50 0xfa 0xff 0xbf
0x00 0x40 0xfc 0xb7
0x00 0x00 0x00 0x00
0x00 0x39 0xe1 0xb7
0x88 0xfa 0xff 0xbf
0xa0 0x29 0xff 0xb7
0x02 0x00 0x00 0x00
0x00 0x40 0xfc 0x00
0x00 0x00 0x00 0x00
0x00 0x00 0x00 0x00
0x88 0xfa 0xff 0xbf
0x5b 0x85 0x04 0x08
0xbffffa40
0xbffffa6c
A lot of this is just padding due to
alignment issues.
Here is the exact stack data I got one time
I executed the code on my machine.
void launch_missiles(int n)
{
printf("Launching %d missilesn", n);
// TODO: implement this function
}
void authenticate_and_launch(void)
{
int n_missiles = 2;
bool allowaccess = false;
char response[8];
printf("Secret: ");
gets(response);
if (strcmp(response, "Joshua") == 0)
allowaccess = true;
if (allowaccess) {
puts("Access granted");
launch_missiles(n_missiles);
}
if (!allowaccess)
puts("Access denied");
}
int main(void)
{
puts("WarGames MissileLauncher v0.1");
authenticate_and_launch();
puts("Operation complete");
}
allowaccess (1 byte)
response (8 bytes)
n_missiles (4 bytes)
return address, next intruction in _start
pointer to stack frame for _start
high address
low address
return address, next intruction in _main
pointer to stack frame for _main
pointer to the response buffer
return address, authenticate_and_launch()
(whatever gets() needs to do)
0x50 0xfa 0xff 0xbf
0x00 0x40 0xfc 0xb7
0x00 0x00 0x00 0x00
0x00 0x39 0xe1 0xb7
0x88 0xfa 0xff 0xbf
0xa0 0x29 0xff 0xb7
0x02 0x00 0x00 0x00
0x00 0x40 0xfc 0x00
0x00 0x00 0x00 0x00
0x00 0x00 0x00 0x00
0x88 0xfa 0xff 0xbf
0x5b 0x85 0x04 0x08
0xbffffa40
0xbffffa6c
void launch_missiles(int n)
{
printf("Launching %d missilesn", n);
// TODO: implement this function
}
void authenticate_and_launch(void)
{
int n_missiles = 2;
bool allowaccess = false;
char response[8];
printf("Secret: ");
gets(response);
if (strcmp(response, "Joshua") == 0)
allowaccess = true;
if (allowaccess) {
puts("Access granted");
launch_missiles(n_missiles);
}
if (!allowaccess)
puts("Access denied");
}
int main(void)
{
puts("WarGames MissileLauncher v0.1");
authenticate_and_launch();
puts("Operation complete");
}
allowaccess (1 byte)
response (8 bytes)
n_missiles (4 bytes)
return address, next intruction in _start
pointer to stack frame for _start
high address
low address
return address, next intruction in _main
pointer to stack frame for _main
pointer to the response buffer
return address, authenticate_and_launch()
(whatever gets() needs to do)
0x50 0xfa 0xff 0xbf
0x00 0x40 0xfc 0xb7
0x00 0x00 0x00 0x00
0x00 0x39 0xe1 0xb7
0x88 0xfa 0xff 0xbf
0xa0 0x29 0xff 0xb7
0x02 0x00 0x00 0x00
0x00 0x40 0xfc 0x00
0x00 0x00 0x00 0x00
0x00 0x00 0x00 0x00
0x88 0xfa 0xff 0xbf
0x5b 0x85 0x04 0x08
0xbffffa40
0xbffffa6c
void launch_missiles(int n)
{
printf("Launching %d missilesn", n);
// TODO: implement this function
}
void authenticate_and_launch(void)
{
int n_missiles = 2;
bool allowaccess = false;
char response[8];
printf("Secret: ");
gets(response);
if (strcmp(response, "Joshua") == 0)
allowaccess = true;
if (allowaccess) {
puts("Access granted");
launch_missiles(n_missiles);
}
if (!allowaccess)
puts("Access denied");
}
int main(void)
{
puts("WarGames MissileLauncher v0.1");
authenticate_and_launch();
puts("Operation complete");
}
allowaccess (1 byte)
response (8 bytes)
n_missiles (4 bytes)
return address, next intruction in _start
pointer to stack frame for _start
high address
low address
return address, next intruction in _main
pointer to stack frame for _main
pointer to the response buffer
return address, authenticate_and_launch()
(whatever gets() needs to do)
0x50 0xfa 0xff 0xbf
0x00 0x40 0xfc 0xb7
0x00 0x00 0x00 0x00
0x00 0x39 0xe1 0xb7
0x88 0xfa 0xff 0xbf
0xa0 0x29 0xff 0xb7
0x02 0x00 0x00 0x00
0x00 0x40 0xfc 0x00
0x00 0x00 0x00 0x00
0x00 0x00 0x00 0x00
0x88 0xfa 0xff 0xbf
0x5b 0x85 0x04 0x08
0xbffffa40
0xbffffa6c
void launch_missiles(int n)
{
printf("Launching %d missilesn", n);
// TODO: implement this function
}
void authenticate_and_launch(void)
{
int n_missiles = 2;
bool allowaccess = false;
char response[8];
printf("Secret: ");
gets(response);
if (strcmp(response, "Joshua") == 0)
allowaccess = true;
if (allowaccess) {
puts("Access granted");
launch_missiles(n_missiles);
}
if (!allowaccess)
puts("Access denied");
}
int main(void)
{
puts("WarGames MissileLauncher v0.1");
authenticate_and_launch();
puts("Operation complete");
}
allowaccess (1 byte)
response (8 bytes)
n_missiles (4 bytes)
return address, next intruction in _start
pointer to stack frame for _start
high address
low address
return address, next intruction in _main
pointer to stack frame for _main
pointer to the response buffer
return address, authenticate_and_launch()
(whatever gets() needs to do)
0x50 0xfa 0xff 0xbf
0x00 0x40 0xfc 0xb7
0x00 0x00 0x00 0x00
0x00 0x39 0xe1 0xb7
0x88 0xfa 0xff 0xbf
0xa0 0x29 0xff 0xb7
0x02 0x00 0x00 0x00
0x00 0x40 0xfc 0x00
0x00 0x00 0x00 0x00
0x00 0x00 0x00 0x00
0x88 0xfa 0xff 0xbf
0x5b 0x85 0x04 0x08
0xbffffa40
0xbffffa6c
void launch_missiles(int n)
{
printf("Launching %d missilesn", n);
// TODO: implement this function
}
void authenticate_and_launch(void)
{
int n_missiles = 2;
bool allowaccess = false;
char response[8];
printf("Secret: ");
gets(response);
if (strcmp(response, "Joshua") == 0)
allowaccess = true;
if (allowaccess) {
puts("Access granted");
launch_missiles(n_missiles);
}
if (!allowaccess)
puts("Access denied");
}
int main(void)
{
puts("WarGames MissileLauncher v0.1");
authenticate_and_launch();
puts("Operation complete");
}
allowaccess (1 byte)
response (8 bytes)
n_missiles (4 bytes)
return address, next intruction in _start
pointer to stack frame for _start
high address
low address
return address, next intruction in _main
pointer to stack frame for _main
pointer to the response buffer
return address, authenticate_and_launch()
(whatever gets() needs to do)
0x50 0xfa 0xff 0xbf
0x00 0x40 0xfc 0xb7
0x00 0x00 0x00 0x00
0x00 0x39 0xe1 0xb7
0x88 0xfa 0xff 0xbf
0xa0 0x29 0xff 0xb7
0x02 0x00 0x00 0x00
0x00 0x40 0xfc 0x00
0x00 0x00 0x00 0x00
0x00 0x00 0x00 0x00
0x88 0xfa 0xff 0xbf
0x5b 0x85 0x04 0x08
0xbffffa40
0xbffffa6c
Insecure coding in C (and C++)
Insecure coding in C (and C++)
Insecure coding in C (and C++)
Insecure coding in C (and C++)
Insecure coding in C (and C++)
Insecure coding in C (and C++)
Insecure coding in C (and C++)
Insecure coding in C (and C++)
Insecure coding in C (and C++)
Insecure coding in C (and C++)
Insecure coding in C (and C++)
Insecure coding in C (and C++)
Insecure coding in C (and C++)
Insecure coding in C (and C++)
Insecure coding in C (and C++)
Insecure coding in C (and C++)
Insecure coding in C (and C++)
Insecure coding in C (and C++)
Insecure coding in C (and C++)
Insecure coding in C (and C++)
Insecure coding in C (and C++)
Insecure coding in C (and C++)
Insecure coding in C (and C++)
Insecure coding in C (and C++)
Insecure coding in C (and C++)
Insecure coding in C (and C++)
Insecure coding in C (and C++)
Insecure coding in C (and C++)
Insecure coding in C (and C++)
Insecure coding in C (and C++)
Insecure coding in C (and C++)
Insecure coding in C (and C++)
Insecure coding in C (and C++)
Insecure coding in C (and C++)
Insecure coding in C (and C++)
Insecure coding in C (and C++)
Insecure coding in C (and C++)
Insecure coding in C (and C++)
Insecure coding in C (and C++)
Insecure coding in C (and C++)
Insecure coding in C (and C++)
Insecure coding in C (and C++)
Insecure coding in C (and C++)
Insecure coding in C (and C++)
Insecure coding in C (and C++)
Insecure coding in C (and C++)
Insecure coding in C (and C++)
Insecure coding in C (and C++)
Insecure coding in C (and C++)
Insecure coding in C (and C++)
Insecure coding in C (and C++)
Insecure coding in C (and C++)
Insecure coding in C (and C++)
Insecure coding in C (and C++)
Insecure coding in C (and C++)
Insecure coding in C (and C++)
Insecure coding in C (and C++)
Insecure coding in C (and C++)
Insecure coding in C (and C++)
Insecure coding in C (and C++)
Insecure coding in C (and C++)
Insecure coding in C (and C++)
Insecure coding in C (and C++)
Insecure coding in C (and C++)
Insecure coding in C (and C++)
Insecure coding in C (and C++)
Insecure coding in C (and C++)
Insecure coding in C (and C++)
Insecure coding in C (and C++)
Insecure coding in C (and C++)
Insecure coding in C (and C++)
Insecure coding in C (and C++)
Insecure coding in C (and C++)
Insecure coding in C (and C++)
Insecure coding in C (and C++)
Insecure coding in C (and C++)
Insecure coding in C (and C++)
Insecure coding in C (and C++)
Insecure coding in C (and C++)
Insecure coding in C (and C++)
Insecure coding in C (and C++)
Insecure coding in C (and C++)
Insecure coding in C (and C++)
Insecure coding in C (and C++)
Insecure coding in C (and C++)
Insecure coding in C (and C++)
Insecure coding in C (and C++)
Insecure coding in C (and C++)
Insecure coding in C (and C++)
Insecure coding in C (and C++)
Insecure coding in C (and C++)
Insecure coding in C (and C++)
Insecure coding in C (and C++)
Insecure coding in C (and C++)
Insecure coding in C (and C++)
Insecure coding in C (and C++)
Insecure coding in C (and C++)
Insecure coding in C (and C++)
Insecure coding in C (and C++)
Insecure coding in C (and C++)
Insecure coding in C (and C++)
Insecure coding in C (and C++)
Insecure coding in C (and C++)
Insecure coding in C (and C++)
Insecure coding in C (and C++)
Insecure coding in C (and C++)
Insecure coding in C (and C++)
Insecure coding in C (and C++)
Insecure coding in C (and C++)
Insecure coding in C (and C++)
Insecure coding in C (and C++)
Insecure coding in C (and C++)
Insecure coding in C (and C++)
Insecure coding in C (and C++)
Insecure coding in C (and C++)
Insecure coding in C (and C++)
Insecure coding in C (and C++)
Insecure coding in C (and C++)
Insecure coding in C (and C++)
Insecure coding in C (and C++)
Insecure coding in C (and C++)
Insecure coding in C (and C++)
Insecure coding in C (and C++)
Insecure coding in C (and C++)
Insecure coding in C (and C++)
Insecure coding in C (and C++)
Insecure coding in C (and C++)
Insecure coding in C (and C++)
Insecure coding in C (and C++)
Insecure coding in C (and C++)
Insecure coding in C (and C++)
Insecure coding in C (and C++)
Insecure coding in C (and C++)
Insecure coding in C (and C++)
Insecure coding in C (and C++)
Insecure coding in C (and C++)
Insecure coding in C (and C++)
Insecure coding in C (and C++)
Insecure coding in C (and C++)
Insecure coding in C (and C++)
Insecure coding in C (and C++)
Insecure coding in C (and C++)
Insecure coding in C (and C++)
Insecure coding in C (and C++)
Insecure coding in C (and C++)
Insecure coding in C (and C++)
Insecure coding in C (and C++)
Insecure coding in C (and C++)
Insecure coding in C (and C++)
Insecure coding in C (and C++)
Insecure coding in C (and C++)
Insecure coding in C (and C++)
Insecure coding in C (and C++)
Insecure coding in C (and C++)
Insecure coding in C (and C++)
Insecure coding in C (and C++)
Insecure coding in C (and C++)
Insecure coding in C (and C++)
Insecure coding in C (and C++)
Insecure coding in C (and C++)
Insecure coding in C (and C++)
Insecure coding in C (and C++)
Insecure coding in C (and C++)
Insecure coding in C (and C++)
Insecure coding in C (and C++)
Insecure coding in C (and C++)
Insecure coding in C (and C++)
Insecure coding in C (and C++)
Insecure coding in C (and C++)
Insecure coding in C (and C++)
Insecure coding in C (and C++)
Insecure coding in C (and C++)
Insecure coding in C (and C++)
Insecure coding in C (and C++)
Insecure coding in C (and C++)
Insecure coding in C (and C++)
Insecure coding in C (and C++)
Insecure coding in C (and C++)
Insecure coding in C (and C++)
Insecure coding in C (and C++)
Insecure coding in C (and C++)
Insecure coding in C (and C++)
Insecure coding in C (and C++)
Insecure coding in C (and C++)
Insecure coding in C (and C++)
Insecure coding in C (and C++)
Insecure coding in C (and C++)
Insecure coding in C (and C++)
Insecure coding in C (and C++)
Insecure coding in C (and C++)
Insecure coding in C (and C++)
Insecure coding in C (and C++)
Insecure coding in C (and C++)
Insecure coding in C (and C++)
Insecure coding in C (and C++)
Insecure coding in C (and C++)
Insecure coding in C (and C++)
Insecure coding in C (and C++)
Insecure coding in C (and C++)
Insecure coding in C (and C++)
Insecure coding in C (and C++)
Insecure coding in C (and C++)
Insecure coding in C (and C++)
Insecure coding in C (and C++)
Insecure coding in C (and C++)
Insecure coding in C (and C++)
Insecure coding in C (and C++)
Insecure coding in C (and C++)
Insecure coding in C (and C++)
Insecure coding in C (and C++)
Insecure coding in C (and C++)
Insecure coding in C (and C++)
Insecure coding in C (and C++)
Insecure coding in C (and C++)
Insecure coding in C (and C++)
Insecure coding in C (and C++)
Insecure coding in C (and C++)
Insecure coding in C (and C++)
Insecure coding in C (and C++)
Insecure coding in C (and C++)
Insecure coding in C (and C++)
Insecure coding in C (and C++)
Insecure coding in C (and C++)
Insecure coding in C (and C++)
Insecure coding in C (and C++)
Insecure coding in C (and C++)
Insecure coding in C (and C++)
Insecure coding in C (and C++)
Insecure coding in C (and C++)
Insecure coding in C (and C++)
Insecure coding in C (and C++)
Insecure coding in C (and C++)
Insecure coding in C (and C++)
Insecure coding in C (and C++)
Insecure coding in C (and C++)
Insecure coding in C (and C++)
Insecure coding in C (and C++)
Insecure coding in C (and C++)
Insecure coding in C (and C++)
Insecure coding in C (and C++)
Insecure coding in C (and C++)
Insecure coding in C (and C++)
Insecure coding in C (and C++)
Insecure coding in C (and C++)
Insecure coding in C (and C++)
Insecure coding in C (and C++)
Insecure coding in C (and C++)
Insecure coding in C (and C++)

More Related Content

What's hot

Introduction to gdb
Introduction to gdbIntroduction to gdb
Introduction to gdbOwen Hsu
 
The Microkernel Mach Under NeXTSTEP
The Microkernel Mach Under NeXTSTEPThe Microkernel Mach Under NeXTSTEP
The Microkernel Mach Under NeXTSTEPGregor Schmidt
 
C++ Programming Course
C++ Programming CourseC++ Programming Course
C++ Programming CourseDennis Chang
 
Module 05 Preprocessor and Macros in C
Module 05 Preprocessor and Macros in CModule 05 Preprocessor and Macros in C
Module 05 Preprocessor and Macros in CTushar B Kute
 
C++ questions And Answer
C++ questions And AnswerC++ questions And Answer
C++ questions And Answerlavparmar007
 
How it's made: C++ compilers (GCC)
How it's made: C++ compilers (GCC)How it's made: C++ compilers (GCC)
How it's made: C++ compilers (GCC)Sławomir Zborowski
 
C programming interview questions
C programming interview questionsC programming interview questions
C programming interview questionsadarshynl
 
C Programming Storage classes, Recursion
C Programming Storage classes, RecursionC Programming Storage classes, Recursion
C Programming Storage classes, RecursionSreedhar Chowdam
 
Debugging Applications with GNU Debugger
Debugging Applications with GNU DebuggerDebugging Applications with GNU Debugger
Debugging Applications with GNU DebuggerPriyank Kapadia
 
Working Remotely (via SSH) Rocks!
Working Remotely (via SSH) Rocks!Working Remotely (via SSH) Rocks!
Working Remotely (via SSH) Rocks!Kent Chen
 
How to implement a simple dalvik virtual machine
How to implement a simple dalvik virtual machineHow to implement a simple dalvik virtual machine
How to implement a simple dalvik virtual machineChun-Yu Wang
 
Introduction to cpp
Introduction to cppIntroduction to cpp
Introduction to cppNilesh Dalvi
 
Kernel_Crash_Dump_Analysis
Kernel_Crash_Dump_AnalysisKernel_Crash_Dump_Analysis
Kernel_Crash_Dump_AnalysisBuland Singh
 

What's hot (20)

Introduction to gdb
Introduction to gdbIntroduction to gdb
Introduction to gdb
 
The Internals of "Hello World" Program
The Internals of "Hello World" ProgramThe Internals of "Hello World" Program
The Internals of "Hello World" Program
 
The Microkernel Mach Under NeXTSTEP
The Microkernel Mach Under NeXTSTEPThe Microkernel Mach Under NeXTSTEP
The Microkernel Mach Under NeXTSTEP
 
淺談探索 Linux 系統設計之道
淺談探索 Linux 系統設計之道 淺談探索 Linux 系統設計之道
淺談探索 Linux 系統設計之道
 
Unix v6 Internals
Unix v6 InternalsUnix v6 Internals
Unix v6 Internals
 
88 c-programs
88 c-programs88 c-programs
88 c-programs
 
C++ Programming Course
C++ Programming CourseC++ Programming Course
C++ Programming Course
 
Module 05 Preprocessor and Macros in C
Module 05 Preprocessor and Macros in CModule 05 Preprocessor and Macros in C
Module 05 Preprocessor and Macros in C
 
C++ questions And Answer
C++ questions And AnswerC++ questions And Answer
C++ questions And Answer
 
How it's made: C++ compilers (GCC)
How it's made: C++ compilers (GCC)How it's made: C++ compilers (GCC)
How it's made: C++ compilers (GCC)
 
Interpreter, Compiler, JIT from scratch
Interpreter, Compiler, JIT from scratchInterpreter, Compiler, JIT from scratch
Interpreter, Compiler, JIT from scratch
 
C programming interview questions
C programming interview questionsC programming interview questions
C programming interview questions
 
Vim Rocks!
Vim Rocks!Vim Rocks!
Vim Rocks!
 
ARM and SoC Traning Part I -- Overview
ARM and SoC Traning Part I -- OverviewARM and SoC Traning Part I -- Overview
ARM and SoC Traning Part I -- Overview
 
C Programming Storage classes, Recursion
C Programming Storage classes, RecursionC Programming Storage classes, Recursion
C Programming Storage classes, Recursion
 
Debugging Applications with GNU Debugger
Debugging Applications with GNU DebuggerDebugging Applications with GNU Debugger
Debugging Applications with GNU Debugger
 
Working Remotely (via SSH) Rocks!
Working Remotely (via SSH) Rocks!Working Remotely (via SSH) Rocks!
Working Remotely (via SSH) Rocks!
 
How to implement a simple dalvik virtual machine
How to implement a simple dalvik virtual machineHow to implement a simple dalvik virtual machine
How to implement a simple dalvik virtual machine
 
Introduction to cpp
Introduction to cppIntroduction to cpp
Introduction to cpp
 
Kernel_Crash_Dump_Analysis
Kernel_Crash_Dump_AnalysisKernel_Crash_Dump_Analysis
Kernel_Crash_Dump_Analysis
 

Similar to Insecure coding in C (and C++)

Mind your language(s), A Discussion about Languages and Security
Mind your language(s), A Discussion about Languages and SecurityMind your language(s), A Discussion about Languages and Security
Mind your language(s), A Discussion about Languages and SecurityAdaCore
 
Analysis of Godot Engine's Source Code
Analysis of Godot Engine's Source CodeAnalysis of Godot Engine's Source Code
Analysis of Godot Engine's Source CodePVS-Studio
 
SSL Failing, Sharing, and Scheduling
SSL Failing, Sharing, and SchedulingSSL Failing, Sharing, and Scheduling
SSL Failing, Sharing, and SchedulingDavid Evans
 
The First C# Project Analyzed
The First C# Project AnalyzedThe First C# Project Analyzed
The First C# Project AnalyzedPVS-Studio
 
stackconf 2021 | Fuzzing: Finding Your Own Bugs and 0days!
stackconf 2021 | Fuzzing: Finding Your Own Bugs and 0days!stackconf 2021 | Fuzzing: Finding Your Own Bugs and 0days!
stackconf 2021 | Fuzzing: Finding Your Own Bugs and 0days!NETWAYS
 
A few words about OpenSSL
A few words about OpenSSLA few words about OpenSSL
A few words about OpenSSLPVS-Studio
 
A Boring Article About a Check of the OpenSSL Project
A Boring Article About a Check of the OpenSSL ProjectA Boring Article About a Check of the OpenSSL Project
A Boring Article About a Check of the OpenSSL ProjectAndrey Karpov
 
How to find 56 potential vulnerabilities in FreeBSD code in one evening
How to find 56 potential vulnerabilities in FreeBSD code in one eveningHow to find 56 potential vulnerabilities in FreeBSD code in one evening
How to find 56 potential vulnerabilities in FreeBSD code in one eveningPVS-Studio
 
.NET Foundation, Future of .NET and C#
.NET Foundation, Future of .NET and C#.NET Foundation, Future of .NET and C#
.NET Foundation, Future of .NET and C#Bertrand Le Roy
 
Fuzzing: Finding Your Own Bugs and 0days! 2.0
Fuzzing: Finding Your Own Bugs and 0days! 2.0Fuzzing: Finding Your Own Bugs and 0days! 2.0
Fuzzing: Finding Your Own Bugs and 0days! 2.0Rodolpho Concurde
 
OWASP Poland Day 2018 - Pedro Fortuna - Are your Java Script based protection...
OWASP Poland Day 2018 - Pedro Fortuna - Are your Java Script based protection...OWASP Poland Day 2018 - Pedro Fortuna - Are your Java Script based protection...
OWASP Poland Day 2018 - Pedro Fortuna - Are your Java Script based protection...OWASP
 
Search for Vulnerabilities Using Static Code Analysis
Search for Vulnerabilities Using Static Code AnalysisSearch for Vulnerabilities Using Static Code Analysis
Search for Vulnerabilities Using Static Code AnalysisAndrey Karpov
 
Serial Killer - Silently Pwning your Java Endpoints // OWASP BeNeLux Day 2016
Serial Killer - Silently Pwning your Java Endpoints // OWASP BeNeLux Day 2016Serial Killer - Silently Pwning your Java Endpoints // OWASP BeNeLux Day 2016
Serial Killer - Silently Pwning your Java Endpoints // OWASP BeNeLux Day 2016Christian Schneider
 
Clean & Typechecked JS
Clean & Typechecked JSClean & Typechecked JS
Clean & Typechecked JSArthur Puthin
 
Finding 0days at Arab Security Conference
Finding 0days at Arab Security ConferenceFinding 0days at Arab Security Conference
Finding 0days at Arab Security ConferenceRodolpho Concurde
 
Why Rust? - Matthias Endler - Codemotion Amsterdam 2016
Why Rust? - Matthias Endler - Codemotion Amsterdam 2016Why Rust? - Matthias Endler - Codemotion Amsterdam 2016
Why Rust? - Matthias Endler - Codemotion Amsterdam 2016Codemotion
 
How to reverse engineer Android applications
How to reverse engineer Android applicationsHow to reverse engineer Android applications
How to reverse engineer Android applicationshubx
 

Similar to Insecure coding in C (and C++) (20)

Mind your language(s), A Discussion about Languages and Security
Mind your language(s), A Discussion about Languages and SecurityMind your language(s), A Discussion about Languages and Security
Mind your language(s), A Discussion about Languages and Security
 
Analysis of Godot Engine's Source Code
Analysis of Godot Engine's Source CodeAnalysis of Godot Engine's Source Code
Analysis of Godot Engine's Source Code
 
SSL Failing, Sharing, and Scheduling
SSL Failing, Sharing, and SchedulingSSL Failing, Sharing, and Scheduling
SSL Failing, Sharing, and Scheduling
 
The First C# Project Analyzed
The First C# Project AnalyzedThe First C# Project Analyzed
The First C# Project Analyzed
 
stackconf 2021 | Fuzzing: Finding Your Own Bugs and 0days!
stackconf 2021 | Fuzzing: Finding Your Own Bugs and 0days!stackconf 2021 | Fuzzing: Finding Your Own Bugs and 0days!
stackconf 2021 | Fuzzing: Finding Your Own Bugs and 0days!
 
A few words about OpenSSL
A few words about OpenSSLA few words about OpenSSL
A few words about OpenSSL
 
A Boring Article About a Check of the OpenSSL Project
A Boring Article About a Check of the OpenSSL ProjectA Boring Article About a Check of the OpenSSL Project
A Boring Article About a Check of the OpenSSL Project
 
How to find 56 potential vulnerabilities in FreeBSD code in one evening
How to find 56 potential vulnerabilities in FreeBSD code in one eveningHow to find 56 potential vulnerabilities in FreeBSD code in one evening
How to find 56 potential vulnerabilities in FreeBSD code in one evening
 
.NET Foundation, Future of .NET and C#
.NET Foundation, Future of .NET and C#.NET Foundation, Future of .NET and C#
.NET Foundation, Future of .NET and C#
 
Fuzzing: Finding Your Own Bugs and 0days! 2.0
Fuzzing: Finding Your Own Bugs and 0days! 2.0Fuzzing: Finding Your Own Bugs and 0days! 2.0
Fuzzing: Finding Your Own Bugs and 0days! 2.0
 
OWASP Poland Day 2018 - Pedro Fortuna - Are your Java Script based protection...
OWASP Poland Day 2018 - Pedro Fortuna - Are your Java Script based protection...OWASP Poland Day 2018 - Pedro Fortuna - Are your Java Script based protection...
OWASP Poland Day 2018 - Pedro Fortuna - Are your Java Script based protection...
 
Search for Vulnerabilities Using Static Code Analysis
Search for Vulnerabilities Using Static Code AnalysisSearch for Vulnerabilities Using Static Code Analysis
Search for Vulnerabilities Using Static Code Analysis
 
Serial Killer - Silently Pwning your Java Endpoints // OWASP BeNeLux Day 2016
Serial Killer - Silently Pwning your Java Endpoints // OWASP BeNeLux Day 2016Serial Killer - Silently Pwning your Java Endpoints // OWASP BeNeLux Day 2016
Serial Killer - Silently Pwning your Java Endpoints // OWASP BeNeLux Day 2016
 
null Pune meet - Application Security: Code injection
null Pune meet - Application Security: Code injectionnull Pune meet - Application Security: Code injection
null Pune meet - Application Security: Code injection
 
Rust Hack
Rust HackRust Hack
Rust Hack
 
Thinking In Swift
Thinking In SwiftThinking In Swift
Thinking In Swift
 
Clean & Typechecked JS
Clean & Typechecked JSClean & Typechecked JS
Clean & Typechecked JS
 
Finding 0days at Arab Security Conference
Finding 0days at Arab Security ConferenceFinding 0days at Arab Security Conference
Finding 0days at Arab Security Conference
 
Why Rust? - Matthias Endler - Codemotion Amsterdam 2016
Why Rust? - Matthias Endler - Codemotion Amsterdam 2016Why Rust? - Matthias Endler - Codemotion Amsterdam 2016
Why Rust? - Matthias Endler - Codemotion Amsterdam 2016
 
How to reverse engineer Android applications
How to reverse engineer Android applicationsHow to reverse engineer Android applications
How to reverse engineer Android applications
 

Recently uploaded

Tech Tuesday Slides - Introduction to Project Management with OnePlan's Work ...
Tech Tuesday Slides - Introduction to Project Management with OnePlan's Work ...Tech Tuesday Slides - Introduction to Project Management with OnePlan's Work ...
Tech Tuesday Slides - Introduction to Project Management with OnePlan's Work ...OnePlan Solutions
 
Patterns for automating API delivery. API conference
Patterns for automating API delivery. API conferencePatterns for automating API delivery. API conference
Patterns for automating API delivery. API conferencessuser9e7c64
 
How to submit a standout Adobe Champion Application
How to submit a standout Adobe Champion ApplicationHow to submit a standout Adobe Champion Application
How to submit a standout Adobe Champion ApplicationBradBedford3
 
SAM Training Session - How to use EXCEL ?
SAM Training Session - How to use EXCEL ?SAM Training Session - How to use EXCEL ?
SAM Training Session - How to use EXCEL ?Alexandre Beguel
 
UI5ers live - Custom Controls wrapping 3rd-party libs.pptx
UI5ers live - Custom Controls wrapping 3rd-party libs.pptxUI5ers live - Custom Controls wrapping 3rd-party libs.pptx
UI5ers live - Custom Controls wrapping 3rd-party libs.pptxAndreas Kunz
 
Best Angular 17 Classroom & Online training - Naresh IT
Best Angular 17 Classroom & Online training - Naresh ITBest Angular 17 Classroom & Online training - Naresh IT
Best Angular 17 Classroom & Online training - Naresh ITmanoharjgpsolutions
 
SpotFlow: Tracking Method Calls and States at Runtime
SpotFlow: Tracking Method Calls and States at RuntimeSpotFlow: Tracking Method Calls and States at Runtime
SpotFlow: Tracking Method Calls and States at Runtimeandrehoraa
 
Keeping your build tool updated in a multi repository world
Keeping your build tool updated in a multi repository worldKeeping your build tool updated in a multi repository world
Keeping your build tool updated in a multi repository worldRoberto Pérez Alcolea
 
Machine Learning Software Engineering Patterns and Their Engineering
Machine Learning Software Engineering Patterns and Their EngineeringMachine Learning Software Engineering Patterns and Their Engineering
Machine Learning Software Engineering Patterns and Their EngineeringHironori Washizaki
 
Sending Calendar Invites on SES and Calendarsnack.pdf
Sending Calendar Invites on SES and Calendarsnack.pdfSending Calendar Invites on SES and Calendarsnack.pdf
Sending Calendar Invites on SES and Calendarsnack.pdf31events.com
 
Exploring Selenium_Appium Frameworks for Seamless Integration with HeadSpin.pdf
Exploring Selenium_Appium Frameworks for Seamless Integration with HeadSpin.pdfExploring Selenium_Appium Frameworks for Seamless Integration with HeadSpin.pdf
Exploring Selenium_Appium Frameworks for Seamless Integration with HeadSpin.pdfkalichargn70th171
 
Effectively Troubleshoot 9 Types of OutOfMemoryError
Effectively Troubleshoot 9 Types of OutOfMemoryErrorEffectively Troubleshoot 9 Types of OutOfMemoryError
Effectively Troubleshoot 9 Types of OutOfMemoryErrorTier1 app
 
Strategies for using alternative queries to mitigate zero results
Strategies for using alternative queries to mitigate zero resultsStrategies for using alternative queries to mitigate zero results
Strategies for using alternative queries to mitigate zero resultsJean Silva
 
The Role of IoT and Sensor Technology in Cargo Cloud Solutions.pptx
The Role of IoT and Sensor Technology in Cargo Cloud Solutions.pptxThe Role of IoT and Sensor Technology in Cargo Cloud Solutions.pptx
The Role of IoT and Sensor Technology in Cargo Cloud Solutions.pptxRTS corp
 
Catch the Wave: SAP Event-Driven and Data Streaming for the Intelligence Ente...
Catch the Wave: SAP Event-Driven and Data Streaming for the Intelligence Ente...Catch the Wave: SAP Event-Driven and Data Streaming for the Intelligence Ente...
Catch the Wave: SAP Event-Driven and Data Streaming for the Intelligence Ente...confluent
 
JavaLand 2024 - Going serverless with Quarkus GraalVM native images and AWS L...
JavaLand 2024 - Going serverless with Quarkus GraalVM native images and AWS L...JavaLand 2024 - Going serverless with Quarkus GraalVM native images and AWS L...
JavaLand 2024 - Going serverless with Quarkus GraalVM native images and AWS L...Bert Jan Schrijver
 
VictoriaMetrics Anomaly Detection Updates: Q1 2024
VictoriaMetrics Anomaly Detection Updates: Q1 2024VictoriaMetrics Anomaly Detection Updates: Q1 2024
VictoriaMetrics Anomaly Detection Updates: Q1 2024VictoriaMetrics
 
Simplifying Microservices & Apps - The art of effortless development - Meetup...
Simplifying Microservices & Apps - The art of effortless development - Meetup...Simplifying Microservices & Apps - The art of effortless development - Meetup...
Simplifying Microservices & Apps - The art of effortless development - Meetup...Rob Geurden
 
Amazon Bedrock in Action - presentation of the Bedrock's capabilities
Amazon Bedrock in Action - presentation of the Bedrock's capabilitiesAmazon Bedrock in Action - presentation of the Bedrock's capabilities
Amazon Bedrock in Action - presentation of the Bedrock's capabilitiesKrzysztofKkol1
 
Enhancing Supply Chain Visibility with Cargo Cloud Solutions.pdf
Enhancing Supply Chain Visibility with Cargo Cloud Solutions.pdfEnhancing Supply Chain Visibility with Cargo Cloud Solutions.pdf
Enhancing Supply Chain Visibility with Cargo Cloud Solutions.pdfRTS corp
 

Recently uploaded (20)

Tech Tuesday Slides - Introduction to Project Management with OnePlan's Work ...
Tech Tuesday Slides - Introduction to Project Management with OnePlan's Work ...Tech Tuesday Slides - Introduction to Project Management with OnePlan's Work ...
Tech Tuesday Slides - Introduction to Project Management with OnePlan's Work ...
 
Patterns for automating API delivery. API conference
Patterns for automating API delivery. API conferencePatterns for automating API delivery. API conference
Patterns for automating API delivery. API conference
 
How to submit a standout Adobe Champion Application
How to submit a standout Adobe Champion ApplicationHow to submit a standout Adobe Champion Application
How to submit a standout Adobe Champion Application
 
SAM Training Session - How to use EXCEL ?
SAM Training Session - How to use EXCEL ?SAM Training Session - How to use EXCEL ?
SAM Training Session - How to use EXCEL ?
 
UI5ers live - Custom Controls wrapping 3rd-party libs.pptx
UI5ers live - Custom Controls wrapping 3rd-party libs.pptxUI5ers live - Custom Controls wrapping 3rd-party libs.pptx
UI5ers live - Custom Controls wrapping 3rd-party libs.pptx
 
Best Angular 17 Classroom & Online training - Naresh IT
Best Angular 17 Classroom & Online training - Naresh ITBest Angular 17 Classroom & Online training - Naresh IT
Best Angular 17 Classroom & Online training - Naresh IT
 
SpotFlow: Tracking Method Calls and States at Runtime
SpotFlow: Tracking Method Calls and States at RuntimeSpotFlow: Tracking Method Calls and States at Runtime
SpotFlow: Tracking Method Calls and States at Runtime
 
Keeping your build tool updated in a multi repository world
Keeping your build tool updated in a multi repository worldKeeping your build tool updated in a multi repository world
Keeping your build tool updated in a multi repository world
 
Machine Learning Software Engineering Patterns and Their Engineering
Machine Learning Software Engineering Patterns and Their EngineeringMachine Learning Software Engineering Patterns and Their Engineering
Machine Learning Software Engineering Patterns and Their Engineering
 
Sending Calendar Invites on SES and Calendarsnack.pdf
Sending Calendar Invites on SES and Calendarsnack.pdfSending Calendar Invites on SES and Calendarsnack.pdf
Sending Calendar Invites on SES and Calendarsnack.pdf
 
Exploring Selenium_Appium Frameworks for Seamless Integration with HeadSpin.pdf
Exploring Selenium_Appium Frameworks for Seamless Integration with HeadSpin.pdfExploring Selenium_Appium Frameworks for Seamless Integration with HeadSpin.pdf
Exploring Selenium_Appium Frameworks for Seamless Integration with HeadSpin.pdf
 
Effectively Troubleshoot 9 Types of OutOfMemoryError
Effectively Troubleshoot 9 Types of OutOfMemoryErrorEffectively Troubleshoot 9 Types of OutOfMemoryError
Effectively Troubleshoot 9 Types of OutOfMemoryError
 
Strategies for using alternative queries to mitigate zero results
Strategies for using alternative queries to mitigate zero resultsStrategies for using alternative queries to mitigate zero results
Strategies for using alternative queries to mitigate zero results
 
The Role of IoT and Sensor Technology in Cargo Cloud Solutions.pptx
The Role of IoT and Sensor Technology in Cargo Cloud Solutions.pptxThe Role of IoT and Sensor Technology in Cargo Cloud Solutions.pptx
The Role of IoT and Sensor Technology in Cargo Cloud Solutions.pptx
 
Catch the Wave: SAP Event-Driven and Data Streaming for the Intelligence Ente...
Catch the Wave: SAP Event-Driven and Data Streaming for the Intelligence Ente...Catch the Wave: SAP Event-Driven and Data Streaming for the Intelligence Ente...
Catch the Wave: SAP Event-Driven and Data Streaming for the Intelligence Ente...
 
JavaLand 2024 - Going serverless with Quarkus GraalVM native images and AWS L...
JavaLand 2024 - Going serverless with Quarkus GraalVM native images and AWS L...JavaLand 2024 - Going serverless with Quarkus GraalVM native images and AWS L...
JavaLand 2024 - Going serverless with Quarkus GraalVM native images and AWS L...
 
VictoriaMetrics Anomaly Detection Updates: Q1 2024
VictoriaMetrics Anomaly Detection Updates: Q1 2024VictoriaMetrics Anomaly Detection Updates: Q1 2024
VictoriaMetrics Anomaly Detection Updates: Q1 2024
 
Simplifying Microservices & Apps - The art of effortless development - Meetup...
Simplifying Microservices & Apps - The art of effortless development - Meetup...Simplifying Microservices & Apps - The art of effortless development - Meetup...
Simplifying Microservices & Apps - The art of effortless development - Meetup...
 
Amazon Bedrock in Action - presentation of the Bedrock's capabilities
Amazon Bedrock in Action - presentation of the Bedrock's capabilitiesAmazon Bedrock in Action - presentation of the Bedrock's capabilities
Amazon Bedrock in Action - presentation of the Bedrock's capabilities
 
Enhancing Supply Chain Visibility with Cargo Cloud Solutions.pdf
Enhancing Supply Chain Visibility with Cargo Cloud Solutions.pdfEnhancing Supply Chain Visibility with Cargo Cloud Solutions.pdf
Enhancing Supply Chain Visibility with Cargo Cloud Solutions.pdf
 

Insecure coding in C (and C++)

  • 1. Insecure coding in C (and C++) Let's turn the table. Suppose your goal is to deliberately create buggy programs in C and C++ with serious security vulnerabilities that can be "easily" exploited.Then you need to know about things like stack smashing, shellcode, arc injection, return-oriented programming. You also need to know about annoying protection mechanisms such as address space layout randomization, stack canaries, data execution prevention, and more. This session will teach you the basics of how to deliberately write insecure programs in C and C++. a 60 minute presentation Norwegian Developer Conference Oslo, June 5 2014, 16:20-17:20 Olve Maudal Update:A recording of this talk is available at http://vimeo.com/channels/ndc2014/97505677
  • 2. Insecure coding in C (and C++) Let's turn the table. Suppose your goal is to deliberately create buggy programs in C and C++ with serious security vulnerabilities that can be "easily" exploited.Then you need to know about things like stack smashing, shellcode, arc injection, return-oriented programming. You also need to know about annoying protection mechanisms such as address space layout randomization, stack canaries, data execution prevention, and more. This session will teach you the basics of how to deliberately write insecure programs in C and C++. a 60 minute presentation Norwegian Developer Conference Oslo, June 5 2014, 16:20-17:20 Olve Maudal
  • 3. Insecure coding in C (and C++) Let's turn the table. Suppose your goal is to deliberately create buggy programs in C and C++ with serious security vulnerabilities that can be "easily" exploited.Then you need to know about things like stack smashing, shellcode, arc injection, return-oriented programming. You also need to know about annoying protection mechanisms such as address space layout randomization, stack canaries, data execution prevention, and more. This session will teach you the basics of how to deliberately write insecure programs in C and C++. a 60 minute presentation Norwegian Developer Conference Oslo, June 5 2014, 16:20-17:20 Olve Maudal Level: Introduction Advanced Expert
  • 4. Insecure coding in C (and C++) Let's turn the table. Suppose your goal is to deliberately create buggy programs in C and C++ with serious security vulnerabilities that can be "easily" exploited.Then you need to know about things like stack smashing, shellcode, arc injection, return-oriented programming. You also need to know about annoying protection mechanisms such as address space layout randomization, stack canaries, data execution prevention, and more. This session will teach you the basics of how to deliberately write insecure programs in C and C++. a 60 minute presentation Norwegian Developer Conference Oslo, June 5 2014, 16:20-17:20 Olve Maudal Level: Introduction Advanced Expert
  • 5. Insecure coding in C (and C++) Let's turn the table. Suppose your goal is to deliberately create buggy programs in C and C++ with serious security vulnerabilities that can be "easily" exploited.Then you need to know about things like stack smashing, shellcode, arc injection, return-oriented programming. You also need to know about annoying protection mechanisms such as address space layout randomization, stack canaries, data execution prevention, and more. This session will teach you the basics of how to deliberately write insecure programs in C and C++. a 60 minute presentation Norwegian Developer Conference Oslo, June 5 2014, 16:20-17:20 Olve Maudal Level: Introduction Advanced Expert
  • 6. Insecure coding in C (and C++) Let's turn the table. Suppose your goal is to deliberately create buggy programs in C and C++ with serious security vulnerabilities that can be "easily" exploited.Then you need to know about things like stack smashing, shellcode, arc injection, return-oriented programming. You also need to know about annoying protection mechanisms such as address space layout randomization, stack canaries, data execution prevention, and more. This session will teach you the basics of how to deliberately write insecure programs in C and C++. a 60 minute presentation Norwegian Developer Conference Oslo, June 5 2014, 16:20-17:20 Olve Maudal Level: Introduction Advanced Expert
  • 7.
  • 8.
  • 9. When I refer to "my machine" it is a fairly up-to-date Ubuntu distro (13.10) running inVirtualBox with x86-32 Linux kernel (3.11) and gcc (4.8.1) - there is nothing special here...
  • 10. I will briefly discuss the following topics: •stack buffer overflow (aka stack smashing) •call stack (aka activation frames) •writing exploits •arc injection (aka return to lib-c) •code injection (aka shell code) •data execution protection (aka DEP, PAE/NX,W^X) •address space layout randomization (ASLR) •stack protection (aka stack canaries) •return-oriented programming (ROP) •writing code with "surprising" behavior •layered security •information leakage •patching binaries •summary - a few tricks for insecure coding
  • 11. void launch_missiles(int n) { printf("Launching %d missilesn", n); // TODO: implement this function } void authenticate_and_launch(void) { int n_missiles = 2; bool allowaccess = false; char response[8]; printf("Secret: "); gets(response); if (strcmp(response, "Joshua") == 0) allowaccess = true; if (allowaccess) { puts("Access granted"); launch_missiles(n_missiles); } if (!allowaccess) puts("Access denied"); } int main(void) { puts("WarGames MissileLauncher v0.1"); authenticate_and_launch(); puts("Operation complete"); } Here is a classic example of exploitable code
  • 12. void launch_missiles(int n) { printf("Launching %d missilesn", n); // TODO: implement this function } void authenticate_and_launch(void) { int n_missiles = 2; bool allowaccess = false; char response[8]; printf("Secret: "); gets(response); if (strcmp(response, "Joshua") == 0) allowaccess = true; if (allowaccess) { puts("Access granted"); launch_missiles(n_missiles); } if (!allowaccess) puts("Access denied"); } int main(void) { puts("WarGames MissileLauncher v0.1"); authenticate_and_launch(); puts("Operation complete"); } Here is a classic example of exploitable code
  • 13. void launch_missiles(int n) { printf("Launching %d missilesn", n); // TODO: implement this function } void authenticate_and_launch(void) { int n_missiles = 2; bool allowaccess = false; char response[8]; printf("Secret: "); gets(response); if (strcmp(response, "Joshua") == 0) allowaccess = true; if (allowaccess) { puts("Access granted"); launch_missiles(n_missiles); } if (!allowaccess) puts("Access denied"); } int main(void) { puts("WarGames MissileLauncher v0.1"); authenticate_and_launch(); puts("Operation complete"); } Here is a classic example of exploitable code
  • 14. void launch_missiles(int n) { printf("Launching %d missilesn", n); // TODO: implement this function } void authenticate_and_launch(void) { int n_missiles = 2; bool allowaccess = false; char response[8]; printf("Secret: "); gets(response); if (strcmp(response, "Joshua") == 0) allowaccess = true; if (allowaccess) { puts("Access granted"); launch_missiles(n_missiles); } if (!allowaccess) puts("Access denied"); } int main(void) { puts("WarGames MissileLauncher v0.1"); authenticate_and_launch(); puts("Operation complete"); } This program is bad in so many ways, but the main weakness we are going to have fun with is of course the use of gets() Here is a classic example of exploitable code
  • 15. void launch_missiles(int n) { printf("Launching %d missilesn", n); // TODO: implement this function } void authenticate_and_launch(void) { int n_missiles = 2; bool allowaccess = false; char response[8]; printf("Secret: "); gets(response); if (strcmp(response, "Joshua") == 0) allowaccess = true; if (allowaccess) { puts("Access granted"); launch_missiles(n_missiles); } if (!allowaccess) puts("Access denied"); } int main(void) { puts("WarGames MissileLauncher v0.1"); authenticate_and_launch(); puts("Operation complete"); } This program is bad in so many ways, but the main weakness we are going to have fun with is of course the use of gets() gets() is a function that will read characters from stdin until a newline or end-of-file is reached, and then a null character is appended. In this case, any input of more than 7 characters will overwrite data outside of the allocated space for the buffer Here is a classic example of exploitable code
  • 16. void launch_missiles(int n) { printf("Launching %d missilesn", n); // TODO: implement this function } void authenticate_and_launch(void) { int n_missiles = 2; bool allowaccess = false; char response[8]; printf("Secret: "); gets(response); if (strcmp(response, "Joshua") == 0) allowaccess = true; if (allowaccess) { puts("Access granted"); launch_missiles(n_missiles); } if (!allowaccess) puts("Access denied"); } int main(void) { puts("WarGames MissileLauncher v0.1"); authenticate_and_launch(); puts("Operation complete"); } This program is bad in so many ways, but the main weakness we are going to have fun with is of course the use of gets() gets() is a function that will read characters from stdin until a newline or end-of-file is reached, and then a null character is appended. In this case, any input of more than 7 characters will overwrite data outside of the allocated space for the buffer I never use gets() Here is a classic example of exploitable code
  • 17. void launch_missiles(int n) { printf("Launching %d missilesn", n); // TODO: implement this function } void authenticate_and_launch(void) { int n_missiles = 2; bool allowaccess = false; char response[8]; printf("Secret: "); gets(response); if (strcmp(response, "Joshua") == 0) allowaccess = true; if (allowaccess) { puts("Access granted"); launch_missiles(n_missiles); } if (!allowaccess) puts("Access denied"); } int main(void) { puts("WarGames MissileLauncher v0.1"); authenticate_and_launch(); puts("Operation complete"); } This program is bad in so many ways, but the main weakness we are going to have fun with is of course the use of gets() gets() is a function that will read characters from stdin until a newline or end-of-file is reached, and then a null character is appended. In this case, any input of more than 7 characters will overwrite data outside of the allocated space for the buffer I never use gets() That's nice to hear, and gets() has actually been deprecated and removed from latest version of the language.We use it anyway here just to make it easier to illustrate the basics. In C and C++ there are plenty of ways to accidentally allow you to poke directly into memory - we will mention some of those later later. But for now... Here is a classic example of exploitable code
  • 18. void launch_missiles(int n) { printf("Launching %d missilesn", n); // TODO: implement this function } void authenticate_and_launch(void) { int n_missiles = 2; bool allowaccess = false; char response[8]; printf("Secret: "); gets(response); if (strcmp(response, "Joshua") == 0) allowaccess = true; if (allowaccess) { puts("Access granted"); launch_missiles(n_missiles); } if (!allowaccess) puts("Access denied"); } int main(void) { puts("WarGames MissileLauncher v0.1"); authenticate_and_launch(); puts("Operation complete"); }
  • 19. void launch_missiles(int n) { printf("Launching %d missilesn", n); // TODO: implement this function } void authenticate_and_launch(void) { int n_missiles = 2; bool allowaccess = false; char response[8]; printf("Secret: "); gets(response); if (strcmp(response, "Joshua") == 0) allowaccess = true; if (allowaccess) { puts("Access granted"); launch_missiles(n_missiles); } if (!allowaccess) puts("Access denied"); } int main(void) { puts("WarGames MissileLauncher v0.1"); authenticate_and_launch(); puts("Operation complete"); } Let's try executing the code and see what happens.
  • 20. $ ./launch void launch_missiles(int n) { printf("Launching %d missilesn", n); // TODO: implement this function } void authenticate_and_launch(void) { int n_missiles = 2; bool allowaccess = false; char response[8]; printf("Secret: "); gets(response); if (strcmp(response, "Joshua") == 0) allowaccess = true; if (allowaccess) { puts("Access granted"); launch_missiles(n_missiles); } if (!allowaccess) puts("Access denied"); } int main(void) { puts("WarGames MissileLauncher v0.1"); authenticate_and_launch(); puts("Operation complete"); } Let's try executing the code and see what happens.
  • 21. $ ./launch WarGames MissileLauncher v0.1 void launch_missiles(int n) { printf("Launching %d missilesn", n); // TODO: implement this function } void authenticate_and_launch(void) { int n_missiles = 2; bool allowaccess = false; char response[8]; printf("Secret: "); gets(response); if (strcmp(response, "Joshua") == 0) allowaccess = true; if (allowaccess) { puts("Access granted"); launch_missiles(n_missiles); } if (!allowaccess) puts("Access denied"); } int main(void) { puts("WarGames MissileLauncher v0.1"); authenticate_and_launch(); puts("Operation complete"); } Let's try executing the code and see what happens.
  • 22. $ ./launch WarGames MissileLauncher v0.1 Secret: void launch_missiles(int n) { printf("Launching %d missilesn", n); // TODO: implement this function } void authenticate_and_launch(void) { int n_missiles = 2; bool allowaccess = false; char response[8]; printf("Secret: "); gets(response); if (strcmp(response, "Joshua") == 0) allowaccess = true; if (allowaccess) { puts("Access granted"); launch_missiles(n_missiles); } if (!allowaccess) puts("Access denied"); } int main(void) { puts("WarGames MissileLauncher v0.1"); authenticate_and_launch(); puts("Operation complete"); } Let's try executing the code and see what happens.
  • 23. $ ./launch WarGames MissileLauncher v0.1 Secret: void launch_missiles(int n) { printf("Launching %d missilesn", n); // TODO: implement this function } void authenticate_and_launch(void) { int n_missiles = 2; bool allowaccess = false; char response[8]; printf("Secret: "); gets(response); if (strcmp(response, "Joshua") == 0) allowaccess = true; if (allowaccess) { puts("Access granted"); launch_missiles(n_missiles); } if (!allowaccess) puts("Access denied"); } int main(void) { puts("WarGames MissileLauncher v0.1"); authenticate_and_launch(); puts("Operation complete"); } David Let's try executing the code and see what happens.
  • 24. $ ./launch WarGames MissileLauncher v0.1 Secret: void launch_missiles(int n) { printf("Launching %d missilesn", n); // TODO: implement this function } void authenticate_and_launch(void) { int n_missiles = 2; bool allowaccess = false; char response[8]; printf("Secret: "); gets(response); if (strcmp(response, "Joshua") == 0) allowaccess = true; if (allowaccess) { puts("Access granted"); launch_missiles(n_missiles); } if (!allowaccess) puts("Access denied"); } int main(void) { puts("WarGames MissileLauncher v0.1"); authenticate_and_launch(); puts("Operation complete"); } Access denied David Let's try executing the code and see what happens.
  • 25. $ ./launch WarGames MissileLauncher v0.1 Secret: void launch_missiles(int n) { printf("Launching %d missilesn", n); // TODO: implement this function } void authenticate_and_launch(void) { int n_missiles = 2; bool allowaccess = false; char response[8]; printf("Secret: "); gets(response); if (strcmp(response, "Joshua") == 0) allowaccess = true; if (allowaccess) { puts("Access granted"); launch_missiles(n_missiles); } if (!allowaccess) puts("Access denied"); } int main(void) { puts("WarGames MissileLauncher v0.1"); authenticate_and_launch(); puts("Operation complete"); } Access denied Operation complete David Let's try executing the code and see what happens.
  • 26. $ ./launch WarGames MissileLauncher v0.1 Secret: void launch_missiles(int n) { printf("Launching %d missilesn", n); // TODO: implement this function } void authenticate_and_launch(void) { int n_missiles = 2; bool allowaccess = false; char response[8]; printf("Secret: "); gets(response); if (strcmp(response, "Joshua") == 0) allowaccess = true; if (allowaccess) { puts("Access granted"); launch_missiles(n_missiles); } if (!allowaccess) puts("Access denied"); } int main(void) { puts("WarGames MissileLauncher v0.1"); authenticate_and_launch(); puts("Operation complete"); } Access denied Operation complete $ ./launch David Let's try executing the code and see what happens.
  • 27. $ ./launch WarGames MissileLauncher v0.1 Secret: void launch_missiles(int n) { printf("Launching %d missilesn", n); // TODO: implement this function } void authenticate_and_launch(void) { int n_missiles = 2; bool allowaccess = false; char response[8]; printf("Secret: "); gets(response); if (strcmp(response, "Joshua") == 0) allowaccess = true; if (allowaccess) { puts("Access granted"); launch_missiles(n_missiles); } if (!allowaccess) puts("Access denied"); } int main(void) { puts("WarGames MissileLauncher v0.1"); authenticate_and_launch(); puts("Operation complete"); } Access denied Operation complete $ ./launch WarGames MissileLauncher v0.1 David Let's try executing the code and see what happens.
  • 28. $ ./launch WarGames MissileLauncher v0.1 Secret: void launch_missiles(int n) { printf("Launching %d missilesn", n); // TODO: implement this function } void authenticate_and_launch(void) { int n_missiles = 2; bool allowaccess = false; char response[8]; printf("Secret: "); gets(response); if (strcmp(response, "Joshua") == 0) allowaccess = true; if (allowaccess) { puts("Access granted"); launch_missiles(n_missiles); } if (!allowaccess) puts("Access denied"); } int main(void) { puts("WarGames MissileLauncher v0.1"); authenticate_and_launch(); puts("Operation complete"); } Access denied Operation complete $ ./launch WarGames MissileLauncher v0.1 Secret: David Let's try executing the code and see what happens.
  • 29. $ ./launch WarGames MissileLauncher v0.1 Secret: void launch_missiles(int n) { printf("Launching %d missilesn", n); // TODO: implement this function } void authenticate_and_launch(void) { int n_missiles = 2; bool allowaccess = false; char response[8]; printf("Secret: "); gets(response); if (strcmp(response, "Joshua") == 0) allowaccess = true; if (allowaccess) { puts("Access granted"); launch_missiles(n_missiles); } if (!allowaccess) puts("Access denied"); } int main(void) { puts("WarGames MissileLauncher v0.1"); authenticate_and_launch(); puts("Operation complete"); } Access denied Operation complete $ ./launch WarGames MissileLauncher v0.1 Secret: Joshua David Let's try executing the code and see what happens.
  • 30. $ ./launch WarGames MissileLauncher v0.1 Secret: void launch_missiles(int n) { printf("Launching %d missilesn", n); // TODO: implement this function } void authenticate_and_launch(void) { int n_missiles = 2; bool allowaccess = false; char response[8]; printf("Secret: "); gets(response); if (strcmp(response, "Joshua") == 0) allowaccess = true; if (allowaccess) { puts("Access granted"); launch_missiles(n_missiles); } if (!allowaccess) puts("Access denied"); } int main(void) { puts("WarGames MissileLauncher v0.1"); authenticate_and_launch(); puts("Operation complete"); } Access granted Access denied Operation complete $ ./launch WarGames MissileLauncher v0.1 Secret: Joshua David Let's try executing the code and see what happens.
  • 31. $ ./launch WarGames MissileLauncher v0.1 Secret: void launch_missiles(int n) { printf("Launching %d missilesn", n); // TODO: implement this function } void authenticate_and_launch(void) { int n_missiles = 2; bool allowaccess = false; char response[8]; printf("Secret: "); gets(response); if (strcmp(response, "Joshua") == 0) allowaccess = true; if (allowaccess) { puts("Access granted"); launch_missiles(n_missiles); } if (!allowaccess) puts("Access denied"); } int main(void) { puts("WarGames MissileLauncher v0.1"); authenticate_and_launch(); puts("Operation complete"); } Access granted Launching 2 missiles Access denied Operation complete $ ./launch WarGames MissileLauncher v0.1 Secret: Joshua David Let's try executing the code and see what happens.
  • 32. $ ./launch WarGames MissileLauncher v0.1 Secret: void launch_missiles(int n) { printf("Launching %d missilesn", n); // TODO: implement this function } void authenticate_and_launch(void) { int n_missiles = 2; bool allowaccess = false; char response[8]; printf("Secret: "); gets(response); if (strcmp(response, "Joshua") == 0) allowaccess = true; if (allowaccess) { puts("Access granted"); launch_missiles(n_missiles); } if (!allowaccess) puts("Access denied"); } int main(void) { puts("WarGames MissileLauncher v0.1"); authenticate_and_launch(); puts("Operation complete"); } Access granted Launching 2 missiles Operation complete Access denied Operation complete $ ./launch WarGames MissileLauncher v0.1 Secret: Joshua David Let's try executing the code and see what happens.
  • 33. $ ./launch WarGames MissileLauncher v0.1 Secret: void launch_missiles(int n) { printf("Launching %d missilesn", n); // TODO: implement this function } void authenticate_and_launch(void) { int n_missiles = 2; bool allowaccess = false; char response[8]; printf("Secret: "); gets(response); if (strcmp(response, "Joshua") == 0) allowaccess = true; if (allowaccess) { puts("Access granted"); launch_missiles(n_missiles); } if (!allowaccess) puts("Access denied"); } int main(void) { puts("WarGames MissileLauncher v0.1"); authenticate_and_launch(); puts("Operation complete"); } Access granted Launching 2 missiles Operation complete $ ./launch Access denied Operation complete $ ./launch WarGames MissileLauncher v0.1 Secret: Joshua David Let's try executing the code and see what happens.
  • 34. $ ./launch WarGames MissileLauncher v0.1 Secret: void launch_missiles(int n) { printf("Launching %d missilesn", n); // TODO: implement this function } void authenticate_and_launch(void) { int n_missiles = 2; bool allowaccess = false; char response[8]; printf("Secret: "); gets(response); if (strcmp(response, "Joshua") == 0) allowaccess = true; if (allowaccess) { puts("Access granted"); launch_missiles(n_missiles); } if (!allowaccess) puts("Access denied"); } int main(void) { puts("WarGames MissileLauncher v0.1"); authenticate_and_launch(); puts("Operation complete"); } Access granted Launching 2 missiles Operation complete $ ./launch WarGames MissileLauncher v0.1 Access denied Operation complete $ ./launch WarGames MissileLauncher v0.1 Secret: Joshua David Let's try executing the code and see what happens.
  • 35. $ ./launch WarGames MissileLauncher v0.1 Secret: void launch_missiles(int n) { printf("Launching %d missilesn", n); // TODO: implement this function } void authenticate_and_launch(void) { int n_missiles = 2; bool allowaccess = false; char response[8]; printf("Secret: "); gets(response); if (strcmp(response, "Joshua") == 0) allowaccess = true; if (allowaccess) { puts("Access granted"); launch_missiles(n_missiles); } if (!allowaccess) puts("Access denied"); } int main(void) { puts("WarGames MissileLauncher v0.1"); authenticate_and_launch(); puts("Operation complete"); } Access granted Launching 2 missiles Operation complete $ ./launch WarGames MissileLauncher v0.1 Secret: Access denied Operation complete $ ./launch WarGames MissileLauncher v0.1 Secret: Joshua David Let's try executing the code and see what happens.
  • 36. $ ./launch WarGames MissileLauncher v0.1 Secret: void launch_missiles(int n) { printf("Launching %d missilesn", n); // TODO: implement this function } void authenticate_and_launch(void) { int n_missiles = 2; bool allowaccess = false; char response[8]; printf("Secret: "); gets(response); if (strcmp(response, "Joshua") == 0) allowaccess = true; if (allowaccess) { puts("Access granted"); launch_missiles(n_missiles); } if (!allowaccess) puts("Access denied"); } int main(void) { puts("WarGames MissileLauncher v0.1"); authenticate_and_launch(); puts("Operation complete"); } Access granted Launching 2 missiles Operation complete $ ./launch WarGames MissileLauncher v0.1 Secret: globalthermonuclearwar Access denied Operation complete $ ./launch WarGames MissileLauncher v0.1 Secret: Joshua David Let's try executing the code and see what happens.
  • 37. $ ./launch WarGames MissileLauncher v0.1 Secret: void launch_missiles(int n) { printf("Launching %d missilesn", n); // TODO: implement this function } void authenticate_and_launch(void) { int n_missiles = 2; bool allowaccess = false; char response[8]; printf("Secret: "); gets(response); if (strcmp(response, "Joshua") == 0) allowaccess = true; if (allowaccess) { puts("Access granted"); launch_missiles(n_missiles); } if (!allowaccess) puts("Access denied"); } int main(void) { puts("WarGames MissileLauncher v0.1"); authenticate_and_launch(); puts("Operation complete"); } Access granted Launching 2 missiles Operation complete $ ./launch WarGames MissileLauncher v0.1 Secret: globalthermonuclearwar Access denied Operation complete $ ./launch WarGames MissileLauncher v0.1 Secret: Joshua David Access granted Let's try executing the code and see what happens.
  • 38. $ ./launch WarGames MissileLauncher v0.1 Secret: void launch_missiles(int n) { printf("Launching %d missilesn", n); // TODO: implement this function } void authenticate_and_launch(void) { int n_missiles = 2; bool allowaccess = false; char response[8]; printf("Secret: "); gets(response); if (strcmp(response, "Joshua") == 0) allowaccess = true; if (allowaccess) { puts("Access granted"); launch_missiles(n_missiles); } if (!allowaccess) puts("Access denied"); } int main(void) { puts("WarGames MissileLauncher v0.1"); authenticate_and_launch(); puts("Operation complete"); } Access granted Launching 2 missiles Operation complete $ ./launch WarGames MissileLauncher v0.1 Secret: globalthermonuclearwar Access denied Operation complete $ ./launch WarGames MissileLauncher v0.1 Secret: Joshua David Access granted Launching 1869443685 missiles Let's try executing the code and see what happens.
  • 39. $ ./launch WarGames MissileLauncher v0.1 Secret: void launch_missiles(int n) { printf("Launching %d missilesn", n); // TODO: implement this function } void authenticate_and_launch(void) { int n_missiles = 2; bool allowaccess = false; char response[8]; printf("Secret: "); gets(response); if (strcmp(response, "Joshua") == 0) allowaccess = true; if (allowaccess) { puts("Access granted"); launch_missiles(n_missiles); } if (!allowaccess) puts("Access denied"); } int main(void) { puts("WarGames MissileLauncher v0.1"); authenticate_and_launch(); puts("Operation complete"); } Access granted Launching 2 missiles Operation complete $ ./launch WarGames MissileLauncher v0.1 Secret: globalthermonuclearwar Access denied Operation complete $ ./launch WarGames MissileLauncher v0.1 Secret: Joshua David Access granted Launching 1869443685 missiles Access denied Let's try executing the code and see what happens.
  • 40. $ ./launch WarGames MissileLauncher v0.1 Secret: void launch_missiles(int n) { printf("Launching %d missilesn", n); // TODO: implement this function } void authenticate_and_launch(void) { int n_missiles = 2; bool allowaccess = false; char response[8]; printf("Secret: "); gets(response); if (strcmp(response, "Joshua") == 0) allowaccess = true; if (allowaccess) { puts("Access granted"); launch_missiles(n_missiles); } if (!allowaccess) puts("Access denied"); } int main(void) { puts("WarGames MissileLauncher v0.1"); authenticate_and_launch(); puts("Operation complete"); } Operation complete Access granted Launching 2 missiles Operation complete $ ./launch WarGames MissileLauncher v0.1 Secret: globalthermonuclearwar Access denied Operation complete $ ./launch WarGames MissileLauncher v0.1 Secret: Joshua David Access granted Launching 1869443685 missiles Access denied Let's try executing the code and see what happens.
  • 41. $ ./launch WarGames MissileLauncher v0.1 Secret: void launch_missiles(int n) { printf("Launching %d missilesn", n); // TODO: implement this function } void authenticate_and_launch(void) { int n_missiles = 2; bool allowaccess = false; char response[8]; printf("Secret: "); gets(response); if (strcmp(response, "Joshua") == 0) allowaccess = true; if (allowaccess) { puts("Access granted"); launch_missiles(n_missiles); } if (!allowaccess) puts("Access denied"); } int main(void) { puts("WarGames MissileLauncher v0.1"); authenticate_and_launch(); puts("Operation complete"); } Operation complete $ Access granted Launching 2 missiles Operation complete $ ./launch WarGames MissileLauncher v0.1 Secret: globalthermonuclearwar Access denied Operation complete $ ./launch WarGames MissileLauncher v0.1 Secret: Joshua David Access granted Launching 1869443685 missiles Access denied Let's try executing the code and see what happens.
  • 42. $ ./launch WarGames MissileLauncher v0.1 Secret: void launch_missiles(int n) { printf("Launching %d missilesn", n); // TODO: implement this function } void authenticate_and_launch(void) { int n_missiles = 2; bool allowaccess = false; char response[8]; printf("Secret: "); gets(response); if (strcmp(response, "Joshua") == 0) allowaccess = true; if (allowaccess) { puts("Access granted"); launch_missiles(n_missiles); } if (!allowaccess) puts("Access denied"); } int main(void) { puts("WarGames MissileLauncher v0.1"); authenticate_and_launch(); puts("Operation complete"); } Operation complete $ Access granted Launching 2 missiles Operation complete $ ./launch WarGames MissileLauncher v0.1 Secret: globalthermonuclearwar Access denied Operation complete $ ./launch WarGames MissileLauncher v0.1 Secret: Joshua David Access granted Launching 1869443685 missiles Access denied Let's try executing the code and see what happens. Due to an overflow we seem to have changed the value of allowaccess and the value of n_missiles. Interesting!
  • 43. $ ./launch WarGames MissileLauncher v0.1 Secret: void launch_missiles(int n) { printf("Launching %d missilesn", n); // TODO: implement this function } void authenticate_and_launch(void) { int n_missiles = 2; bool allowaccess = false; char response[8]; printf("Secret: "); gets(response); if (strcmp(response, "Joshua") == 0) allowaccess = true; if (allowaccess) { puts("Access granted"); launch_missiles(n_missiles); } if (!allowaccess) puts("Access denied"); } int main(void) { puts("WarGames MissileLauncher v0.1"); authenticate_and_launch(); puts("Operation complete"); } Operation complete $ Access granted Launching 2 missiles Operation complete $ ./launch WarGames MissileLauncher v0.1 Secret: globalthermonuclearwar Access denied Operation complete $ ./launch WarGames MissileLauncher v0.1 Secret: Joshua David Access granted Launching 1869443685 missiles Access denied Huh? Let's try executing the code and see what happens. Due to an overflow we seem to have changed the value of allowaccess and the value of n_missiles. Interesting!
  • 44. $ ./launch WarGames MissileLauncher v0.1 Secret: void launch_missiles(int n) { printf("Launching %d missilesn", n); // TODO: implement this function } void authenticate_and_launch(void) { int n_missiles = 2; bool allowaccess = false; char response[8]; printf("Secret: "); gets(response); if (strcmp(response, "Joshua") == 0) allowaccess = true; if (allowaccess) { puts("Access granted"); launch_missiles(n_missiles); } if (!allowaccess) puts("Access denied"); } int main(void) { puts("WarGames MissileLauncher v0.1"); authenticate_and_launch(); puts("Operation complete"); } Operation complete $ Access granted Launching 2 missiles Operation complete $ ./launch WarGames MissileLauncher v0.1 Secret: globalthermonuclearwar Access denied Operation complete $ ./launch WarGames MissileLauncher v0.1 Secret: Joshua David Access granted Launching 1869443685 missiles Access denied Huh? Let's try executing the code and see what happens. Due to an overflow we seem to have changed the value of allowaccess and the value of n_missiles. Interesting! ... but why did it also print Access denied?
  • 45. void launch_missiles(int n) { printf("Launching %d missilesn", n); // TODO: implement this function } void authenticate_and_launch(void) { int n_missiles = 2; bool allowaccess = false; char response[8]; printf("Secret: "); gets(response); if (strcmp(response, "Joshua") == 0) allowaccess = true; if (allowaccess) { puts("Access granted"); launch_missiles(n_missiles); } if (!allowaccess) puts("Access denied"); } int main(void) { puts("WarGames MissileLauncher v0.1"); authenticate_and_launch(); puts("Operation complete"); } $ ./launch WarGames MissileLauncher v0.1 Secret: David Access denied Operation complete $ ./launch WarGames MissileLauncher v0.1 Secret: Joshua Access granted Launching 2 missiles Operation complete $ ./launch WarGames MissileLauncher v0.1 Secret: globalthermonuclearwar Access granted Launching 1869443685 missiles Access denied Operation complete $
  • 46. void launch_missiles(int n) { printf("Launching %d missilesn", n); // TODO: implement this function } void authenticate_and_launch(void) { int n_missiles = 2; bool allowaccess = false; char response[8]; printf("Secret: "); gets(response); if (strcmp(response, "Joshua") == 0) allowaccess = true; if (allowaccess) { puts("Access granted"); launch_missiles(n_missiles); } if (!allowaccess) puts("Access denied"); } int main(void) { puts("WarGames MissileLauncher v0.1"); authenticate_and_launch(); puts("Operation complete"); } $ ./launch WarGames MissileLauncher v0.1 Secret: David Access denied Operation complete $ ./launch WarGames MissileLauncher v0.1 Secret: Joshua Access granted Launching 2 missiles Operation complete $ ./launch WarGames MissileLauncher v0.1 Secret: globalthermonuclearwar Access granted Launching 1869443685 missiles Access denied Operation complete $ What we just saw was an example of stack buffer overflow, aka stack smashing.When overwriting the response buffer we also changed the memory location used by variable allowaccess and n_missiles
  • 47. void launch_missiles(int n) { printf("Launching %d missilesn", n); // TODO: implement this function } void authenticate_and_launch(void) { int n_missiles = 2; bool allowaccess = false; char response[8]; printf("Secret: "); gets(response); if (strcmp(response, "Joshua") == 0) allowaccess = true; if (allowaccess) { puts("Access granted"); launch_missiles(n_missiles); } if (!allowaccess) puts("Access denied"); } int main(void) { puts("WarGames MissileLauncher v0.1"); authenticate_and_launch(); puts("Operation complete"); } $ ./launch WarGames MissileLauncher v0.1 Secret: David Access denied Operation complete $ ./launch WarGames MissileLauncher v0.1 Secret: Joshua Access granted Launching 2 missiles Operation complete $ ./launch WarGames MissileLauncher v0.1 Secret: globalthermonuclearwar Access granted Launching 1869443685 missiles Access denied Operation complete $ C and C++ are languages that are mostly defined by its behavior.The standards says very little about how things should be implemented. Indeed, while it is common to hear discussions about call stack when talking about C and C++, it is worth noting that the standards does not mention the concept at all. What we just saw was an example of stack buffer overflow, aka stack smashing.When overwriting the response buffer we also changed the memory location used by variable allowaccess and n_missiles
  • 48. void launch_missiles(int n) { printf("Launching %d missilesn", n); // TODO: implement this function } void authenticate_and_launch(void) { int n_missiles = 2; bool allowaccess = false; char response[8]; printf("Secret: "); gets(response); if (strcmp(response, "Joshua") == 0) allowaccess = true; if (allowaccess) { puts("Access granted"); launch_missiles(n_missiles); } if (!allowaccess) puts("Access denied"); } int main(void) { puts("WarGames MissileLauncher v0.1"); authenticate_and_launch(); puts("Operation complete"); } $ ./launch WarGames MissileLauncher v0.1 Secret: David Access denied Operation complete $ ./launch WarGames MissileLauncher v0.1 Secret: Joshua Access granted Launching 2 missiles Operation complete $ ./launch WarGames MissileLauncher v0.1 Secret: globalthermonuclearwar Access granted Launching 1869443685 missiles Access denied Operation complete $ C and C++ are languages that are mostly defined by its behavior.The standards says very little about how things should be implemented. Indeed, while it is common to hear discussions about call stack when talking about C and C++, it is worth noting that the standards does not mention the concept at all. We can learn a lot about C and C++ by studying what happens when it executes. Here is a detailed explanation about what actually happened on my machine. Let's start from the beginning... What we just saw was an example of stack buffer overflow, aka stack smashing.When overwriting the response buffer we also changed the memory location used by variable allowaccess and n_missiles
  • 49. void launch_missiles(int n) { printf("Launching %d missilesn", n); // TODO: implement this function } void authenticate_and_launch(void) { int n_missiles = 2; bool allowaccess = false; char response[8]; printf("Secret: "); gets(response); if (strcmp(response, "Joshua") == 0) allowaccess = true; if (allowaccess) { puts("Access granted"); launch_missiles(n_missiles); } if (!allowaccess) puts("Access denied"); } int main(void) { puts("WarGames MissileLauncher v0.1"); authenticate_and_launch(); puts("Operation complete"); }
  • 50. void launch_missiles(int n) { printf("Launching %d missilesn", n); // TODO: implement this function } void authenticate_and_launch(void) { int n_missiles = 2; bool allowaccess = false; char response[8]; printf("Secret: "); gets(response); if (strcmp(response, "Joshua") == 0) allowaccess = true; if (allowaccess) { puts("Access granted"); launch_missiles(n_missiles); } if (!allowaccess) puts("Access denied"); } int main(void) { puts("WarGames MissileLauncher v0.1"); authenticate_and_launch(); puts("Operation complete"); } main() is the entry point for the program.
  • 51. void launch_missiles(int n) { printf("Launching %d missilesn", n); // TODO: implement this function } void authenticate_and_launch(void) { int n_missiles = 2; bool allowaccess = false; char response[8]; printf("Secret: "); gets(response); if (strcmp(response, "Joshua") == 0) allowaccess = true; if (allowaccess) { puts("Access granted"); launch_missiles(n_missiles); } if (!allowaccess) puts("Access denied"); } int main(void) { puts("WarGames MissileLauncher v0.1"); authenticate_and_launch(); puts("Operation complete"); } main() is the entry point for the program.
  • 52. void launch_missiles(int n) { printf("Launching %d missilesn", n); // TODO: implement this function } void authenticate_and_launch(void) { int n_missiles = 2; bool allowaccess = false; char response[8]; printf("Secret: "); gets(response); if (strcmp(response, "Joshua") == 0) allowaccess = true; if (allowaccess) { puts("Access granted"); launch_missiles(n_missiles); } if (!allowaccess) puts("Access denied"); } int main(void) { puts("WarGames MissileLauncher v0.1"); authenticate_and_launch(); puts("Operation complete"); } main() is the entry point for the program. At this point, a call stack has been set up for us.
  • 53. void launch_missiles(int n) { printf("Launching %d missilesn", n); // TODO: implement this function } void authenticate_and_launch(void) { int n_missiles = 2; bool allowaccess = false; char response[8]; printf("Secret: "); gets(response); if (strcmp(response, "Joshua") == 0) allowaccess = true; if (allowaccess) { puts("Access granted"); launch_missiles(n_missiles); } if (!allowaccess) puts("Access denied"); } int main(void) { puts("WarGames MissileLauncher v0.1"); authenticate_and_launch(); puts("Operation complete"); } main() is the entry point for the program. At this point, a call stack has been set up for us. high address low address
  • 54. void launch_missiles(int n) { printf("Launching %d missilesn", n); // TODO: implement this function } void authenticate_and_launch(void) { int n_missiles = 2; bool allowaccess = false; char response[8]; printf("Secret: "); gets(response); if (strcmp(response, "Joshua") == 0) allowaccess = true; if (allowaccess) { puts("Access granted"); launch_missiles(n_missiles); } if (!allowaccess) puts("Access denied"); } int main(void) { puts("WarGames MissileLauncher v0.1"); authenticate_and_launch(); puts("Operation complete"); } main() is the entry point for the program. At this point, a call stack has been set up for us. high address low address The calling function has pushed the address of its next instruction to be executed on the stack, just before it made a jmp into main()
  • 55. void launch_missiles(int n) { printf("Launching %d missilesn", n); // TODO: implement this function } void authenticate_and_launch(void) { int n_missiles = 2; bool allowaccess = false; char response[8]; printf("Secret: "); gets(response); if (strcmp(response, "Joshua") == 0) allowaccess = true; if (allowaccess) { puts("Access granted"); launch_missiles(n_missiles); } if (!allowaccess) puts("Access denied"); } int main(void) { puts("WarGames MissileLauncher v0.1"); authenticate_and_launch(); puts("Operation complete"); } main() is the entry point for the program. At this point, a call stack has been set up for us. return address, next intruction in _starthigh address low address The calling function has pushed the address of its next instruction to be executed on the stack, just before it made a jmp into main()
  • 56. void launch_missiles(int n) { printf("Launching %d missilesn", n); // TODO: implement this function } void authenticate_and_launch(void) { int n_missiles = 2; bool allowaccess = false; char response[8]; printf("Secret: "); gets(response); if (strcmp(response, "Joshua") == 0) allowaccess = true; if (allowaccess) { puts("Access granted"); launch_missiles(n_missiles); } if (!allowaccess) puts("Access denied"); } int main(void) { puts("WarGames MissileLauncher v0.1"); authenticate_and_launch(); puts("Operation complete"); } main() is the entry point for the program. At this point, a call stack has been set up for us. return address, next intruction in _starthigh address low address The calling function has pushed the address of its next instruction to be executed on the stack, just before it made a jmp into main() The first thing that happens when entering main(), is that the current base pointer is pushed on to the stack.
  • 57. void launch_missiles(int n) { printf("Launching %d missilesn", n); // TODO: implement this function } void authenticate_and_launch(void) { int n_missiles = 2; bool allowaccess = false; char response[8]; printf("Secret: "); gets(response); if (strcmp(response, "Joshua") == 0) allowaccess = true; if (allowaccess) { puts("Access granted"); launch_missiles(n_missiles); } if (!allowaccess) puts("Access denied"); } int main(void) { puts("WarGames MissileLauncher v0.1"); authenticate_and_launch(); puts("Operation complete"); } main() is the entry point for the program. At this point, a call stack has been set up for us. return address, next intruction in _starthigh address low address The calling function has pushed the address of its next instruction to be executed on the stack, just before it made a jmp into main() The first thing that happens when entering main(), is that the current base pointer is pushed on to the stack. Then the base pointer and stack pointer is changed so main() get's it's own activation frame.
  • 58. void launch_missiles(int n) { printf("Launching %d missilesn", n); // TODO: implement this function } void authenticate_and_launch(void) { int n_missiles = 2; bool allowaccess = false; char response[8]; printf("Secret: "); gets(response); if (strcmp(response, "Joshua") == 0) allowaccess = true; if (allowaccess) { puts("Access granted"); launch_missiles(n_missiles); } if (!allowaccess) puts("Access denied"); } int main(void) { puts("WarGames MissileLauncher v0.1"); authenticate_and_launch(); puts("Operation complete"); } main() is the entry point for the program. At this point, a call stack has been set up for us. return address, next intruction in _start pointer to stack frame for _start high address low address The calling function has pushed the address of its next instruction to be executed on the stack, just before it made a jmp into main() The first thing that happens when entering main(), is that the current base pointer is pushed on to the stack. Then the base pointer and stack pointer is changed so main() get's it's own activation frame.
  • 59. void launch_missiles(int n) { printf("Launching %d missilesn", n); // TODO: implement this function } void authenticate_and_launch(void) { int n_missiles = 2; bool allowaccess = false; char response[8]; printf("Secret: "); gets(response); if (strcmp(response, "Joshua") == 0) allowaccess = true; if (allowaccess) { puts("Access granted"); launch_missiles(n_missiles); } if (!allowaccess) puts("Access denied"); } int main(void) { puts("WarGames MissileLauncher v0.1"); authenticate_and_launch(); puts("Operation complete"); } return address, next intruction in _start pointer to stack frame for _start high address low address
  • 60. void launch_missiles(int n) { printf("Launching %d missilesn", n); // TODO: implement this function } void authenticate_and_launch(void) { int n_missiles = 2; bool allowaccess = false; char response[8]; printf("Secret: "); gets(response); if (strcmp(response, "Joshua") == 0) allowaccess = true; if (allowaccess) { puts("Access granted"); launch_missiles(n_missiles); } if (!allowaccess) puts("Access denied"); } int main(void) { puts("WarGames MissileLauncher v0.1"); authenticate_and_launch(); puts("Operation complete"); } return address, next intruction in _start pointer to stack frame for _start high address low address
  • 61. void launch_missiles(int n) { printf("Launching %d missilesn", n); // TODO: implement this function } void authenticate_and_launch(void) { int n_missiles = 2; bool allowaccess = false; char response[8]; printf("Secret: "); gets(response); if (strcmp(response, "Joshua") == 0) allowaccess = true; if (allowaccess) { puts("Access granted"); launch_missiles(n_missiles); } if (!allowaccess) puts("Access denied"); } int main(void) { puts("WarGames MissileLauncher v0.1"); authenticate_and_launch(); puts("Operation complete"); } The first statement in main() is to call puts() with a string. return address, next intruction in _start pointer to stack frame for _start high address low address
  • 62. void launch_missiles(int n) { printf("Launching %d missilesn", n); // TODO: implement this function } void authenticate_and_launch(void) { int n_missiles = 2; bool allowaccess = false; char response[8]; printf("Secret: "); gets(response); if (strcmp(response, "Joshua") == 0) allowaccess = true; if (allowaccess) { puts("Access granted"); launch_missiles(n_missiles); } if (!allowaccess) puts("Access denied"); } int main(void) { puts("WarGames MissileLauncher v0.1"); authenticate_and_launch(); puts("Operation complete"); } The first statement in main() is to call puts() with a string. return address, next intruction in _start pointer to stack frame for _start high address low address A pointer to the string is pushed on the stack, this is the argument to puts()
  • 63. void launch_missiles(int n) { printf("Launching %d missilesn", n); // TODO: implement this function } void authenticate_and_launch(void) { int n_missiles = 2; bool allowaccess = false; char response[8]; printf("Secret: "); gets(response); if (strcmp(response, "Joshua") == 0) allowaccess = true; if (allowaccess) { puts("Access granted"); launch_missiles(n_missiles); } if (!allowaccess) puts("Access denied"); } int main(void) { puts("WarGames MissileLauncher v0.1"); authenticate_and_launch(); puts("Operation complete"); } The first statement in main() is to call puts() with a string. return address, next intruction in _start pointer to stack frame for _start high address low address A pointer to the string is pushed on the stack, this is the argument to puts() pointer to string "WarGames..."
  • 64. void launch_missiles(int n) { printf("Launching %d missilesn", n); // TODO: implement this function } void authenticate_and_launch(void) { int n_missiles = 2; bool allowaccess = false; char response[8]; printf("Secret: "); gets(response); if (strcmp(response, "Joshua") == 0) allowaccess = true; if (allowaccess) { puts("Access granted"); launch_missiles(n_missiles); } if (!allowaccess) puts("Access denied"); } int main(void) { puts("WarGames MissileLauncher v0.1"); authenticate_and_launch(); puts("Operation complete"); } The first statement in main() is to call puts() with a string. return address, next intruction in _start pointer to stack frame for _start high address low address A pointer to the string is pushed on the stack, this is the argument to puts() Then we push the return address, a memory address pointing to the next instruction in main() pointer to string "WarGames..."
  • 65. void launch_missiles(int n) { printf("Launching %d missilesn", n); // TODO: implement this function } void authenticate_and_launch(void) { int n_missiles = 2; bool allowaccess = false; char response[8]; printf("Secret: "); gets(response); if (strcmp(response, "Joshua") == 0) allowaccess = true; if (allowaccess) { puts("Access granted"); launch_missiles(n_missiles); } if (!allowaccess) puts("Access denied"); } int main(void) { puts("WarGames MissileLauncher v0.1"); authenticate_and_launch(); puts("Operation complete"); } The first statement in main() is to call puts() with a string. return address, next intruction in _start pointer to stack frame for _start high address low address A pointer to the string is pushed on the stack, this is the argument to puts() Then we push the return address, a memory address pointing to the next instruction in main() pointer to string "WarGames..." return address, next intruction in main
  • 66. void launch_missiles(int n) { printf("Launching %d missilesn", n); // TODO: implement this function } void authenticate_and_launch(void) { int n_missiles = 2; bool allowaccess = false; char response[8]; printf("Secret: "); gets(response); if (strcmp(response, "Joshua") == 0) allowaccess = true; if (allowaccess) { puts("Access granted"); launch_missiles(n_missiles); } if (!allowaccess) puts("Access denied"); } int main(void) { puts("WarGames MissileLauncher v0.1"); authenticate_and_launch(); puts("Operation complete"); } The first statement in main() is to call puts() with a string. return address, next intruction in _start pointer to stack frame for _start high address low address A pointer to the string is pushed on the stack, this is the argument to puts() Then we push the return address, a memory address pointing to the next instruction in main() pointer to string "WarGames..." return address, next intruction in main The puts() function will do whatever it needs to do, just making sure that the base pointer is restored before using the return address to jump back to the next instruction in main()
  • 67. void launch_missiles(int n) { printf("Launching %d missilesn", n); // TODO: implement this function } void authenticate_and_launch(void) { int n_missiles = 2; bool allowaccess = false; char response[8]; printf("Secret: "); gets(response); if (strcmp(response, "Joshua") == 0) allowaccess = true; if (allowaccess) { puts("Access granted"); launch_missiles(n_missiles); } if (!allowaccess) puts("Access denied"); } int main(void) { puts("WarGames MissileLauncher v0.1"); authenticate_and_launch(); puts("Operation complete"); } The first statement in main() is to call puts() with a string. return address, next intruction in _start pointer to stack frame for _start high address low address A pointer to the string is pushed on the stack, this is the argument to puts() Then we push the return address, a memory address pointing to the next instruction in main() pointer to string "WarGames..." return address, next intruction in main The puts() function will do whatever it needs to do, just making sure that the base pointer is restored before using the return address to jump back to the next instruction in main() (whatever puts() needs to do)
  • 68. void launch_missiles(int n) { printf("Launching %d missilesn", n); // TODO: implement this function } void authenticate_and_launch(void) { int n_missiles = 2; bool allowaccess = false; char response[8]; printf("Secret: "); gets(response); if (strcmp(response, "Joshua") == 0) allowaccess = true; if (allowaccess) { puts("Access granted"); launch_missiles(n_missiles); } if (!allowaccess) puts("Access denied"); } int main(void) { puts("WarGames MissileLauncher v0.1"); authenticate_and_launch(); puts("Operation complete"); } return address, next intruction in _start pointer to stack frame for _start high address low address pointer to string "WarGames..." return address, next intruction in main
  • 69. void launch_missiles(int n) { printf("Launching %d missilesn", n); // TODO: implement this function } void authenticate_and_launch(void) { int n_missiles = 2; bool allowaccess = false; char response[8]; printf("Secret: "); gets(response); if (strcmp(response, "Joshua") == 0) allowaccess = true; if (allowaccess) { puts("Access granted"); launch_missiles(n_missiles); } if (!allowaccess) puts("Access denied"); } int main(void) { puts("WarGames MissileLauncher v0.1"); authenticate_and_launch(); puts("Operation complete"); } return address, next intruction in _start pointer to stack frame for _start high address low address pointer to string "WarGames..." return address, next intruction in main The stack is restored and the next statement will be executed.
  • 70. void launch_missiles(int n) { printf("Launching %d missilesn", n); // TODO: implement this function } void authenticate_and_launch(void) { int n_missiles = 2; bool allowaccess = false; char response[8]; printf("Secret: "); gets(response); if (strcmp(response, "Joshua") == 0) allowaccess = true; if (allowaccess) { puts("Access granted"); launch_missiles(n_missiles); } if (!allowaccess) puts("Access denied"); } int main(void) { puts("WarGames MissileLauncher v0.1"); authenticate_and_launch(); puts("Operation complete"); } return address, next intruction in _start pointer to stack frame for _start high address low address The stack is restored and the next statement will be executed.
  • 71. void launch_missiles(int n) { printf("Launching %d missilesn", n); // TODO: implement this function } void authenticate_and_launch(void) { int n_missiles = 2; bool allowaccess = false; char response[8]; printf("Secret: "); gets(response); if (strcmp(response, "Joshua") == 0) allowaccess = true; if (allowaccess) { puts("Access granted"); launch_missiles(n_missiles); } if (!allowaccess) puts("Access denied"); } int main(void) { puts("WarGames MissileLauncher v0.1"); authenticate_and_launch(); puts("Operation complete"); } return address, next intruction in _start pointer to stack frame for _start high address low address The stack is restored and the next statement will be executed.
  • 72. void launch_missiles(int n) { printf("Launching %d missilesn", n); // TODO: implement this function } void authenticate_and_launch(void) { int n_missiles = 2; bool allowaccess = false; char response[8]; printf("Secret: "); gets(response); if (strcmp(response, "Joshua") == 0) allowaccess = true; if (allowaccess) { puts("Access granted"); launch_missiles(n_missiles); } if (!allowaccess) puts("Access denied"); } int main(void) { puts("WarGames MissileLauncher v0.1"); authenticate_and_launch(); puts("Operation complete"); } return address, next intruction in _start pointer to stack frame for _start high address low address Now we prepare for calling authenticate_and_launch() by pushing the return address of the next statement to be executed in main() , and then we jump into authenticate_and_launch() The stack is restored and the next statement will be executed.
  • 73. void launch_missiles(int n) { printf("Launching %d missilesn", n); // TODO: implement this function } void authenticate_and_launch(void) { int n_missiles = 2; bool allowaccess = false; char response[8]; printf("Secret: "); gets(response); if (strcmp(response, "Joshua") == 0) allowaccess = true; if (allowaccess) { puts("Access granted"); launch_missiles(n_missiles); } if (!allowaccess) puts("Access denied"); } int main(void) { puts("WarGames MissileLauncher v0.1"); authenticate_and_launch(); puts("Operation complete"); } return address, next intruction in _start pointer to stack frame for _start high address low address Now we prepare for calling authenticate_and_launch() by pushing the return address of the next statement to be executed in main() , and then we jump into authenticate_and_launch() return address, next intruction in _main The stack is restored and the next statement will be executed.
  • 74. void launch_missiles(int n) { printf("Launching %d missilesn", n); // TODO: implement this function } void authenticate_and_launch(void) { int n_missiles = 2; bool allowaccess = false; char response[8]; printf("Secret: "); gets(response); if (strcmp(response, "Joshua") == 0) allowaccess = true; if (allowaccess) { puts("Access granted"); launch_missiles(n_missiles); } if (!allowaccess) puts("Access denied"); } int main(void) { puts("WarGames MissileLauncher v0.1"); authenticate_and_launch(); puts("Operation complete"); } return address, next intruction in _start pointer to stack frame for _start high address low address Now we prepare for calling authenticate_and_launch() by pushing the return address of the next statement to be executed in main() , and then we jump into authenticate_and_launch() return address, next intruction in _main The stack is restored and the next statement will be executed.
  • 75. void launch_missiles(int n) { printf("Launching %d missilesn", n); // TODO: implement this function } void authenticate_and_launch(void) { int n_missiles = 2; bool allowaccess = false; char response[8]; printf("Secret: "); gets(response); if (strcmp(response, "Joshua") == 0) allowaccess = true; if (allowaccess) { puts("Access granted"); launch_missiles(n_missiles); } if (!allowaccess) puts("Access denied"); } int main(void) { puts("WarGames MissileLauncher v0.1"); authenticate_and_launch(); puts("Operation complete"); } return address, next intruction in _start pointer to stack frame for _start high address low address return address, next intruction in _main
  • 76. void launch_missiles(int n) { printf("Launching %d missilesn", n); // TODO: implement this function } void authenticate_and_launch(void) { int n_missiles = 2; bool allowaccess = false; char response[8]; printf("Secret: "); gets(response); if (strcmp(response, "Joshua") == 0) allowaccess = true; if (allowaccess) { puts("Access granted"); launch_missiles(n_missiles); } if (!allowaccess) puts("Access denied"); } int main(void) { puts("WarGames MissileLauncher v0.1"); authenticate_and_launch(); puts("Operation complete"); } return address, next intruction in _start pointer to stack frame for _start high address low address Create a new stack frame, before allocating space for the local variables on the stack. return address, next intruction in _main
  • 77. void launch_missiles(int n) { printf("Launching %d missilesn", n); // TODO: implement this function } void authenticate_and_launch(void) { int n_missiles = 2; bool allowaccess = false; char response[8]; printf("Secret: "); gets(response); if (strcmp(response, "Joshua") == 0) allowaccess = true; if (allowaccess) { puts("Access granted"); launch_missiles(n_missiles); } if (!allowaccess) puts("Access denied"); } int main(void) { puts("WarGames MissileLauncher v0.1"); authenticate_and_launch(); puts("Operation complete"); } return address, next intruction in _start pointer to stack frame for _start high address low address Create a new stack frame, before allocating space for the local variables on the stack. return address, next intruction in _main pointer to stack frame for _main
  • 78. void launch_missiles(int n) { printf("Launching %d missilesn", n); // TODO: implement this function } void authenticate_and_launch(void) { int n_missiles = 2; bool allowaccess = false; char response[8]; printf("Secret: "); gets(response); if (strcmp(response, "Joshua") == 0) allowaccess = true; if (allowaccess) { puts("Access granted"); launch_missiles(n_missiles); } if (!allowaccess) puts("Access denied"); } int main(void) { puts("WarGames MissileLauncher v0.1"); authenticate_and_launch(); puts("Operation complete"); } return address, next intruction in _start pointer to stack frame for _start high address low address return address, next intruction in _main pointer to stack frame for _main Create a new stack frame, before allocating space for the local variables on the stack.
  • 79. void launch_missiles(int n) { printf("Launching %d missilesn", n); // TODO: implement this function } void authenticate_and_launch(void) { int n_missiles = 2; bool allowaccess = false; char response[8]; printf("Secret: "); gets(response); if (strcmp(response, "Joshua") == 0) allowaccess = true; if (allowaccess) { puts("Access granted"); launch_missiles(n_missiles); } if (!allowaccess) puts("Access denied"); } int main(void) { puts("WarGames MissileLauncher v0.1"); authenticate_and_launch(); puts("Operation complete"); } return address, next intruction in _start pointer to stack frame for _start high address low address return address, next intruction in _main pointer to stack frame for _main allowaccess (1 byte) Create a new stack frame, before allocating space for the local variables on the stack.
  • 80. void launch_missiles(int n) { printf("Launching %d missilesn", n); // TODO: implement this function } void authenticate_and_launch(void) { int n_missiles = 2; bool allowaccess = false; char response[8]; printf("Secret: "); gets(response); if (strcmp(response, "Joshua") == 0) allowaccess = true; if (allowaccess) { puts("Access granted"); launch_missiles(n_missiles); } if (!allowaccess) puts("Access denied"); } int main(void) { puts("WarGames MissileLauncher v0.1"); authenticate_and_launch(); puts("Operation complete"); } return address, next intruction in _start pointer to stack frame for _start high address low address return address, next intruction in _main pointer to stack frame for _main allowaccess (1 byte) n_missiles (4 bytes) Create a new stack frame, before allocating space for the local variables on the stack.
  • 81. void launch_missiles(int n) { printf("Launching %d missilesn", n); // TODO: implement this function } void authenticate_and_launch(void) { int n_missiles = 2; bool allowaccess = false; char response[8]; printf("Secret: "); gets(response); if (strcmp(response, "Joshua") == 0) allowaccess = true; if (allowaccess) { puts("Access granted"); launch_missiles(n_missiles); } if (!allowaccess) puts("Access denied"); } int main(void) { puts("WarGames MissileLauncher v0.1"); authenticate_and_launch(); puts("Operation complete"); } return address, next intruction in _start pointer to stack frame for _start high address low address return address, next intruction in _main pointer to stack frame for _main allowaccess (1 byte) n_missiles (4 bytes) response (8 bytes) Create a new stack frame, before allocating space for the local variables on the stack.
  • 82. void launch_missiles(int n) { printf("Launching %d missilesn", n); // TODO: implement this function } void authenticate_and_launch(void) { int n_missiles = 2; bool allowaccess = false; char response[8]; printf("Secret: "); gets(response); if (strcmp(response, "Joshua") == 0) allowaccess = true; if (allowaccess) { puts("Access granted"); launch_missiles(n_missiles); } if (!allowaccess) puts("Access denied"); } int main(void) { puts("WarGames MissileLauncher v0.1"); authenticate_and_launch(); puts("Operation complete"); } return address, next intruction in _start pointer to stack frame for _start high address low address return address, next intruction in _main pointer to stack frame for _main allowaccess (1 byte) n_missiles (4 bytes) response (8 bytes) Hey, wait a minute... should not the stack variables be allocated in correct order? Create a new stack frame, before allocating space for the local variables on the stack.
  • 83. void launch_missiles(int n) { printf("Launching %d missilesn", n); // TODO: implement this function } void authenticate_and_launch(void) { int n_missiles = 2; bool allowaccess = false; char response[8]; printf("Secret: "); gets(response); if (strcmp(response, "Joshua") == 0) allowaccess = true; if (allowaccess) { puts("Access granted"); launch_missiles(n_missiles); } if (!allowaccess) puts("Access denied"); } int main(void) { puts("WarGames MissileLauncher v0.1"); authenticate_and_launch(); puts("Operation complete"); } return address, next intruction in _start pointer to stack frame for _start high address low address return address, next intruction in _main pointer to stack frame for _main allowaccess (1 byte) n_missiles (4 bytes) response (8 bytes) There is no "correct order" here. In this case, the compiler is free to store objects of automatic storage duration (the correct name for "stack variables") in any order. Indeed, it can keep all of them in registers or ignore them completely as long as the external behavior of the program is the same. Hey, wait a minute... should not the stack variables be allocated in correct order? Create a new stack frame, before allocating space for the local variables on the stack.
  • 84. void launch_missiles(int n) { printf("Launching %d missilesn", n); // TODO: implement this function } void authenticate_and_launch(void) { int n_missiles = 2; bool allowaccess = false; char response[8]; printf("Secret: "); gets(response); if (strcmp(response, "Joshua") == 0) allowaccess = true; if (allowaccess) { puts("Access granted"); launch_missiles(n_missiles); } if (!allowaccess) puts("Access denied"); } int main(void) { puts("WarGames MissileLauncher v0.1"); authenticate_and_launch(); puts("Operation complete"); } return address, next intruction in _start pointer to stack frame for _start high address low address return address, next intruction in _main pointer to stack frame for _main allowaccess (1 byte) n_missiles (4 bytes) response (8 bytes)
  • 85. void launch_missiles(int n) { printf("Launching %d missilesn", n); // TODO: implement this function } void authenticate_and_launch(void) { int n_missiles = 2; bool allowaccess = false; char response[8]; printf("Secret: "); gets(response); if (strcmp(response, "Joshua") == 0) allowaccess = true; if (allowaccess) { puts("Access granted"); launch_missiles(n_missiles); } if (!allowaccess) puts("Access denied"); } int main(void) { puts("WarGames MissileLauncher v0.1"); authenticate_and_launch(); puts("Operation complete"); } return address, next intruction in _start pointer to stack frame for _start high address low address return address, next intruction in _main pointer to stack frame for _main allowaccess (1 byte) n_missiles (4 bytes) response (8 bytes)
  • 86. void launch_missiles(int n) { printf("Launching %d missilesn", n); // TODO: implement this function } void authenticate_and_launch(void) { int n_missiles = 2; bool allowaccess = false; char response[8]; printf("Secret: "); gets(response); if (strcmp(response, "Joshua") == 0) allowaccess = true; if (allowaccess) { puts("Access granted"); launch_missiles(n_missiles); } if (!allowaccess) puts("Access denied"); } int main(void) { puts("WarGames MissileLauncher v0.1"); authenticate_and_launch(); puts("Operation complete"); } return address, next intruction in _start pointer to stack frame for _start high address low address Then we call printf() with an argument. return address, next intruction in _main pointer to stack frame for _main allowaccess (1 byte) n_missiles (4 bytes) response (8 bytes)
  • 87. void launch_missiles(int n) { printf("Launching %d missilesn", n); // TODO: implement this function } void authenticate_and_launch(void) { int n_missiles = 2; bool allowaccess = false; char response[8]; printf("Secret: "); gets(response); if (strcmp(response, "Joshua") == 0) allowaccess = true; if (allowaccess) { puts("Access granted"); launch_missiles(n_missiles); } if (!allowaccess) puts("Access denied"); } int main(void) { puts("WarGames MissileLauncher v0.1"); authenticate_and_launch(); puts("Operation complete"); } return address, next intruction in _start pointer to stack frame for _start high address low address Then we call printf() with an argument. return address, next intruction in _main pointer to stack frame for _main pointer to string "Secret: " allowaccess (1 byte) n_missiles (4 bytes) response (8 bytes)
  • 88. void launch_missiles(int n) { printf("Launching %d missilesn", n); // TODO: implement this function } void authenticate_and_launch(void) { int n_missiles = 2; bool allowaccess = false; char response[8]; printf("Secret: "); gets(response); if (strcmp(response, "Joshua") == 0) allowaccess = true; if (allowaccess) { puts("Access granted"); launch_missiles(n_missiles); } if (!allowaccess) puts("Access denied"); } int main(void) { puts("WarGames MissileLauncher v0.1"); authenticate_and_launch(); puts("Operation complete"); } return address, next intruction in _start pointer to stack frame for _start high address low address Then we call printf() with an argument. return address, next intruction in _main pointer to stack frame for _main return address, authenticate_and_launch() pointer to string "Secret: " allowaccess (1 byte) n_missiles (4 bytes) response (8 bytes)
  • 89. void launch_missiles(int n) { printf("Launching %d missilesn", n); // TODO: implement this function } void authenticate_and_launch(void) { int n_missiles = 2; bool allowaccess = false; char response[8]; printf("Secret: "); gets(response); if (strcmp(response, "Joshua") == 0) allowaccess = true; if (allowaccess) { puts("Access granted"); launch_missiles(n_missiles); } if (!allowaccess) puts("Access denied"); } int main(void) { puts("WarGames MissileLauncher v0.1"); authenticate_and_launch(); puts("Operation complete"); } return address, next intruction in _start pointer to stack frame for _start high address low address Then we call printf() with an argument. return address, next intruction in _main pointer to stack frame for _main return address, authenticate_and_launch() pointer to string "Secret: " (whatever printf() needs to do) allowaccess (1 byte) n_missiles (4 bytes) response (8 bytes)
  • 90. void launch_missiles(int n) { printf("Launching %d missilesn", n); // TODO: implement this function } void authenticate_and_launch(void) { int n_missiles = 2; bool allowaccess = false; char response[8]; printf("Secret: "); gets(response); if (strcmp(response, "Joshua") == 0) allowaccess = true; if (allowaccess) { puts("Access granted"); launch_missiles(n_missiles); } if (!allowaccess) puts("Access denied"); } int main(void) { puts("WarGames MissileLauncher v0.1"); authenticate_and_launch(); puts("Operation complete"); } return address, next intruction in _start pointer to stack frame for _start high address low address Then we call printf() with an argument. return address, next intruction in _main pointer to stack frame for _main return address, authenticate_and_launch() pointer to string "Secret: " (whatever printf() needs to do) After the prompt has been written to the standard output stream.The stack is cleaned up and we get ready to execute the next statement. allowaccess (1 byte) n_missiles (4 bytes) response (8 bytes)
  • 91. void launch_missiles(int n) { printf("Launching %d missilesn", n); // TODO: implement this function } void authenticate_and_launch(void) { int n_missiles = 2; bool allowaccess = false; char response[8]; printf("Secret: "); gets(response); if (strcmp(response, "Joshua") == 0) allowaccess = true; if (allowaccess) { puts("Access granted"); launch_missiles(n_missiles); } if (!allowaccess) puts("Access denied"); } int main(void) { puts("WarGames MissileLauncher v0.1"); authenticate_and_launch(); puts("Operation complete"); } return address, next intruction in _start pointer to stack frame for _start high address low address return address, next intruction in _main pointer to stack frame for _main allowaccess (1 byte) n_missiles (4 bytes) response (8 bytes) return address, authenticate_and_launch() pointer to string "Secret: " (whatever printf() needs to do)
  • 92. void launch_missiles(int n) { printf("Launching %d missilesn", n); // TODO: implement this function } void authenticate_and_launch(void) { int n_missiles = 2; bool allowaccess = false; char response[8]; printf("Secret: "); gets(response); if (strcmp(response, "Joshua") == 0) allowaccess = true; if (allowaccess) { puts("Access granted"); launch_missiles(n_missiles); } if (!allowaccess) puts("Access denied"); } int main(void) { puts("WarGames MissileLauncher v0.1"); authenticate_and_launch(); puts("Operation complete"); } return address, next intruction in _start pointer to stack frame for _start high address low address return address, next intruction in _main pointer to stack frame for _main allowaccess (1 byte) n_missiles (4 bytes) response (8 bytes)
  • 93. void launch_missiles(int n) { printf("Launching %d missilesn", n); // TODO: implement this function } void authenticate_and_launch(void) { int n_missiles = 2; bool allowaccess = false; char response[8]; printf("Secret: "); gets(response); if (strcmp(response, "Joshua") == 0) allowaccess = true; if (allowaccess) { puts("Access granted"); launch_missiles(n_missiles); } if (!allowaccess) puts("Access denied"); } int main(void) { puts("WarGames MissileLauncher v0.1"); authenticate_and_launch(); puts("Operation complete"); } return address, next intruction in _start pointer to stack frame for _start high address low address First the pointer to the response buffer is pushed on stack. return address, next intruction in _main pointer to stack frame for _main allowaccess (1 byte) n_missiles (4 bytes) response (8 bytes)
  • 94. void launch_missiles(int n) { printf("Launching %d missilesn", n); // TODO: implement this function } void authenticate_and_launch(void) { int n_missiles = 2; bool allowaccess = false; char response[8]; printf("Secret: "); gets(response); if (strcmp(response, "Joshua") == 0) allowaccess = true; if (allowaccess) { puts("Access granted"); launch_missiles(n_missiles); } if (!allowaccess) puts("Access denied"); } int main(void) { puts("WarGames MissileLauncher v0.1"); authenticate_and_launch(); puts("Operation complete"); } return address, next intruction in _start pointer to stack frame for _start high address low address First the pointer to the response buffer is pushed on stack. return address, next intruction in _main pointer to stack frame for _main pointer to the response buffer allowaccess (1 byte) n_missiles (4 bytes) response (8 bytes)
  • 95. void launch_missiles(int n) { printf("Launching %d missilesn", n); // TODO: implement this function } void authenticate_and_launch(void) { int n_missiles = 2; bool allowaccess = false; char response[8]; printf("Secret: "); gets(response); if (strcmp(response, "Joshua") == 0) allowaccess = true; if (allowaccess) { puts("Access granted"); launch_missiles(n_missiles); } if (!allowaccess) puts("Access denied"); } int main(void) { puts("WarGames MissileLauncher v0.1"); authenticate_and_launch(); puts("Operation complete"); } return address, next intruction in _start pointer to stack frame for _start high address low address First the pointer to the response buffer is pushed on stack. return address, next intruction in _main pointer to stack frame for _main pointer to the response buffer allowaccess (1 byte) n_missiles (4 bytes) response (8 bytes) Then the return address. Before jumping into gets()
  • 96. void launch_missiles(int n) { printf("Launching %d missilesn", n); // TODO: implement this function } void authenticate_and_launch(void) { int n_missiles = 2; bool allowaccess = false; char response[8]; printf("Secret: "); gets(response); if (strcmp(response, "Joshua") == 0) allowaccess = true; if (allowaccess) { puts("Access granted"); launch_missiles(n_missiles); } if (!allowaccess) puts("Access denied"); } int main(void) { puts("WarGames MissileLauncher v0.1"); authenticate_and_launch(); puts("Operation complete"); } return address, next intruction in _start pointer to stack frame for _start high address low address First the pointer to the response buffer is pushed on stack. return address, next intruction in _main pointer to stack frame for _main pointer to the response buffer return address, authenticate_and_launch() allowaccess (1 byte) n_missiles (4 bytes) response (8 bytes) Then the return address. Before jumping into gets()
  • 97. void launch_missiles(int n) { printf("Launching %d missilesn", n); // TODO: implement this function } void authenticate_and_launch(void) { int n_missiles = 2; bool allowaccess = false; char response[8]; printf("Secret: "); gets(response); if (strcmp(response, "Joshua") == 0) allowaccess = true; if (allowaccess) { puts("Access granted"); launch_missiles(n_missiles); } if (!allowaccess) puts("Access denied"); } int main(void) { puts("WarGames MissileLauncher v0.1"); authenticate_and_launch(); puts("Operation complete"); } return address, next intruction in _start pointer to stack frame for _start high address low address First the pointer to the response buffer is pushed on stack. return address, next intruction in _main pointer to stack frame for _main pointer to the response buffer return address, authenticate_and_launch() (whatever gets() needs to do) allowaccess (1 byte) n_missiles (4 bytes) response (8 bytes) Then the return address. Before jumping into gets()
  • 98. void launch_missiles(int n) { printf("Launching %d missilesn", n); // TODO: implement this function } void authenticate_and_launch(void) { int n_missiles = 2; bool allowaccess = false; char response[8]; printf("Secret: "); gets(response); if (strcmp(response, "Joshua") == 0) allowaccess = true; if (allowaccess) { puts("Access granted"); launch_missiles(n_missiles); } if (!allowaccess) puts("Access denied"); } int main(void) { puts("WarGames MissileLauncher v0.1"); authenticate_and_launch(); puts("Operation complete"); } return address, next intruction in _start pointer to stack frame for _start high address low address First the pointer to the response buffer is pushed on stack. return address, next intruction in _main pointer to stack frame for _main gets() will wait for input from the standard input stream. Each character will be poked sequentally into the response buffer until a newline character, end-of-line or some kind of error occurs.Then, before returning it will append a '0' character to the buffer. pointer to the response buffer return address, authenticate_and_launch() (whatever gets() needs to do) allowaccess (1 byte) n_missiles (4 bytes) response (8 bytes) Then the return address. Before jumping into gets()
  • 99. void launch_missiles(int n) { printf("Launching %d missilesn", n); // TODO: implement this function } void authenticate_and_launch(void) { int n_missiles = 2; bool allowaccess = false; char response[8]; printf("Secret: "); gets(response); if (strcmp(response, "Joshua") == 0) allowaccess = true; if (allowaccess) { puts("Access granted"); launch_missiles(n_missiles); } if (!allowaccess) puts("Access denied"); } int main(void) { puts("WarGames MissileLauncher v0.1"); authenticate_and_launch(); puts("Operation complete"); } return address, next intruction in _start pointer to stack frame for _start high address low address First the pointer to the response buffer is pushed on stack. return address, next intruction in _main pointer to stack frame for _main gets() will wait for input from the standard input stream. Each character will be poked sequentally into the response buffer until a newline character, end-of-line or some kind of error occurs.Then, before returning it will append a '0' character to the buffer. pointer to the response buffer return address, authenticate_and_launch() (whatever gets() needs to do) If the input is 8 characters or more, then the response buffer allocated on the stack is not big enough, and in this case the data storage of the other variables will be overwritten. allowaccess (1 byte) n_missiles (4 bytes) response (8 bytes) Then the return address. Before jumping into gets()
  • 100. void launch_missiles(int n) { printf("Launching %d missilesn", n); // TODO: implement this function } void authenticate_and_launch(void) { int n_missiles = 2; bool allowaccess = false; char response[8]; printf("Secret: "); gets(response); if (strcmp(response, "Joshua") == 0) allowaccess = true; if (allowaccess) { puts("Access granted"); launch_missiles(n_missiles); } if (!allowaccess) puts("Access denied"); } int main(void) { puts("WarGames MissileLauncher v0.1"); authenticate_and_launch(); puts("Operation complete"); } allowaccess (1 byte) response (8 bytes) n_missiles (4 bytes) return address, next intruction in _start pointer to stack frame for _start high address low address return address, next intruction in _main pointer to stack frame for _main pointer to the response buffer return address, authenticate_and_launch() (whatever gets() needs to do)
  • 101. void launch_missiles(int n) { printf("Launching %d missilesn", n); // TODO: implement this function } void authenticate_and_launch(void) { int n_missiles = 2; bool allowaccess = false; char response[8]; printf("Secret: "); gets(response); if (strcmp(response, "Joshua") == 0) allowaccess = true; if (allowaccess) { puts("Access granted"); launch_missiles(n_missiles); } if (!allowaccess) puts("Access denied"); } int main(void) { puts("WarGames MissileLauncher v0.1"); authenticate_and_launch(); puts("Operation complete"); } allowaccess (1 byte) response (8 bytes) n_missiles (4 bytes) return address, next intruction in _start pointer to stack frame for _start high address low address return address, next intruction in _main pointer to stack frame for _main pointer to the response buffer return address, authenticate_and_launch() (whatever gets() needs to do) Here is the exact stack data I got one time I executed the code on my machine.
  • 102. void launch_missiles(int n) { printf("Launching %d missilesn", n); // TODO: implement this function } void authenticate_and_launch(void) { int n_missiles = 2; bool allowaccess = false; char response[8]; printf("Secret: "); gets(response); if (strcmp(response, "Joshua") == 0) allowaccess = true; if (allowaccess) { puts("Access granted"); launch_missiles(n_missiles); } if (!allowaccess) puts("Access denied"); } int main(void) { puts("WarGames MissileLauncher v0.1"); authenticate_and_launch(); puts("Operation complete"); } allowaccess (1 byte) response (8 bytes) n_missiles (4 bytes) return address, next intruction in _start pointer to stack frame for _start high address low address return address, next intruction in _main pointer to stack frame for _main pointer to the response buffer return address, authenticate_and_launch() (whatever gets() needs to do) 0x50 0xfa 0xff 0xbf 0x00 0x40 0xfc 0xb7 0x00 0x00 0x00 0x00 0x00 0x39 0xe1 0xb7 0x88 0xfa 0xff 0xbf 0xa0 0x29 0xff 0xb7 0x02 0x00 0x00 0x00 0x00 0x40 0xfc 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x88 0xfa 0xff 0xbf 0x5b 0x85 0x04 0x08 0xbffffa40 0xbffffa6c Here is the exact stack data I got one time I executed the code on my machine.
  • 103. void launch_missiles(int n) { printf("Launching %d missilesn", n); // TODO: implement this function } void authenticate_and_launch(void) { int n_missiles = 2; bool allowaccess = false; char response[8]; printf("Secret: "); gets(response); if (strcmp(response, "Joshua") == 0) allowaccess = true; if (allowaccess) { puts("Access granted"); launch_missiles(n_missiles); } if (!allowaccess) puts("Access denied"); } int main(void) { puts("WarGames MissileLauncher v0.1"); authenticate_and_launch(); puts("Operation complete"); } allowaccess (1 byte) response (8 bytes) n_missiles (4 bytes) return address, next intruction in _start pointer to stack frame for _start high address low address return address, next intruction in _main pointer to stack frame for _main pointer to the response buffer return address, authenticate_and_launch() (whatever gets() needs to do) 0x50 0xfa 0xff 0xbf 0x00 0x40 0xfc 0xb7 0x00 0x00 0x00 0x00 0x00 0x39 0xe1 0xb7 0x88 0xfa 0xff 0xbf 0xa0 0x29 0xff 0xb7 0x02 0x00 0x00 0x00 0x00 0x40 0xfc 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x88 0xfa 0xff 0xbf 0x5b 0x85 0x04 0x08 0xbffffa40 0xbffffa6c Here is the exact stack data I got one time I executed the code on my machine. A lot of this is just padding due to alignment issues.
  • 104. void launch_missiles(int n) { printf("Launching %d missilesn", n); // TODO: implement this function } void authenticate_and_launch(void) { int n_missiles = 2; bool allowaccess = false; char response[8]; printf("Secret: "); gets(response); if (strcmp(response, "Joshua") == 0) allowaccess = true; if (allowaccess) { puts("Access granted"); launch_missiles(n_missiles); } if (!allowaccess) puts("Access denied"); } int main(void) { puts("WarGames MissileLauncher v0.1"); authenticate_and_launch(); puts("Operation complete"); } allowaccess (1 byte) response (8 bytes) n_missiles (4 bytes) return address, next intruction in _start pointer to stack frame for _start high address low address return address, next intruction in _main pointer to stack frame for _main pointer to the response buffer return address, authenticate_and_launch() (whatever gets() needs to do) 0x50 0xfa 0xff 0xbf 0x00 0x40 0xfc 0xb7 0x00 0x00 0x00 0x00 0x00 0x39 0xe1 0xb7 0x88 0xfa 0xff 0xbf 0xa0 0x29 0xff 0xb7 0x02 0x00 0x00 0x00 0x00 0x40 0xfc 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x88 0xfa 0xff 0xbf 0x5b 0x85 0x04 0x08 0xbffffa40 0xbffffa6c A lot of this is just padding due to alignment issues. Here is the exact stack data I got one time I executed the code on my machine.
  • 105. void launch_missiles(int n) { printf("Launching %d missilesn", n); // TODO: implement this function } void authenticate_and_launch(void) { int n_missiles = 2; bool allowaccess = false; char response[8]; printf("Secret: "); gets(response); if (strcmp(response, "Joshua") == 0) allowaccess = true; if (allowaccess) { puts("Access granted"); launch_missiles(n_missiles); } if (!allowaccess) puts("Access denied"); } int main(void) { puts("WarGames MissileLauncher v0.1"); authenticate_and_launch(); puts("Operation complete"); } allowaccess (1 byte) response (8 bytes) n_missiles (4 bytes) return address, next intruction in _start pointer to stack frame for _start high address low address return address, next intruction in _main pointer to stack frame for _main pointer to the response buffer return address, authenticate_and_launch() (whatever gets() needs to do) 0x50 0xfa 0xff 0xbf 0x00 0x40 0xfc 0xb7 0x00 0x00 0x00 0x00 0x00 0x39 0xe1 0xb7 0x88 0xfa 0xff 0xbf 0xa0 0x29 0xff 0xb7 0x02 0x00 0x00 0x00 0x00 0x40 0xfc 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x88 0xfa 0xff 0xbf 0x5b 0x85 0x04 0x08 0xbffffa40 0xbffffa6c
  • 106. void launch_missiles(int n) { printf("Launching %d missilesn", n); // TODO: implement this function } void authenticate_and_launch(void) { int n_missiles = 2; bool allowaccess = false; char response[8]; printf("Secret: "); gets(response); if (strcmp(response, "Joshua") == 0) allowaccess = true; if (allowaccess) { puts("Access granted"); launch_missiles(n_missiles); } if (!allowaccess) puts("Access denied"); } int main(void) { puts("WarGames MissileLauncher v0.1"); authenticate_and_launch(); puts("Operation complete"); } allowaccess (1 byte) response (8 bytes) n_missiles (4 bytes) return address, next intruction in _start pointer to stack frame for _start high address low address return address, next intruction in _main pointer to stack frame for _main pointer to the response buffer return address, authenticate_and_launch() (whatever gets() needs to do) 0x50 0xfa 0xff 0xbf 0x00 0x40 0xfc 0xb7 0x00 0x00 0x00 0x00 0x00 0x39 0xe1 0xb7 0x88 0xfa 0xff 0xbf 0xa0 0x29 0xff 0xb7 0x02 0x00 0x00 0x00 0x00 0x40 0xfc 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x88 0xfa 0xff 0xbf 0x5b 0x85 0x04 0x08 0xbffffa40 0xbffffa6c
  • 107. void launch_missiles(int n) { printf("Launching %d missilesn", n); // TODO: implement this function } void authenticate_and_launch(void) { int n_missiles = 2; bool allowaccess = false; char response[8]; printf("Secret: "); gets(response); if (strcmp(response, "Joshua") == 0) allowaccess = true; if (allowaccess) { puts("Access granted"); launch_missiles(n_missiles); } if (!allowaccess) puts("Access denied"); } int main(void) { puts("WarGames MissileLauncher v0.1"); authenticate_and_launch(); puts("Operation complete"); } allowaccess (1 byte) response (8 bytes) n_missiles (4 bytes) return address, next intruction in _start pointer to stack frame for _start high address low address return address, next intruction in _main pointer to stack frame for _main pointer to the response buffer return address, authenticate_and_launch() (whatever gets() needs to do) 0x50 0xfa 0xff 0xbf 0x00 0x40 0xfc 0xb7 0x00 0x00 0x00 0x00 0x00 0x39 0xe1 0xb7 0x88 0xfa 0xff 0xbf 0xa0 0x29 0xff 0xb7 0x02 0x00 0x00 0x00 0x00 0x40 0xfc 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x88 0xfa 0xff 0xbf 0x5b 0x85 0x04 0x08 0xbffffa40 0xbffffa6c
  • 108. void launch_missiles(int n) { printf("Launching %d missilesn", n); // TODO: implement this function } void authenticate_and_launch(void) { int n_missiles = 2; bool allowaccess = false; char response[8]; printf("Secret: "); gets(response); if (strcmp(response, "Joshua") == 0) allowaccess = true; if (allowaccess) { puts("Access granted"); launch_missiles(n_missiles); } if (!allowaccess) puts("Access denied"); } int main(void) { puts("WarGames MissileLauncher v0.1"); authenticate_and_launch(); puts("Operation complete"); } allowaccess (1 byte) response (8 bytes) n_missiles (4 bytes) return address, next intruction in _start pointer to stack frame for _start high address low address return address, next intruction in _main pointer to stack frame for _main pointer to the response buffer return address, authenticate_and_launch() (whatever gets() needs to do) 0x50 0xfa 0xff 0xbf 0x00 0x40 0xfc 0xb7 0x00 0x00 0x00 0x00 0x00 0x39 0xe1 0xb7 0x88 0xfa 0xff 0xbf 0xa0 0x29 0xff 0xb7 0x02 0x00 0x00 0x00 0x00 0x40 0xfc 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x88 0xfa 0xff 0xbf 0x5b 0x85 0x04 0x08 0xbffffa40 0xbffffa6c
  • 109. void launch_missiles(int n) { printf("Launching %d missilesn", n); // TODO: implement this function } void authenticate_and_launch(void) { int n_missiles = 2; bool allowaccess = false; char response[8]; printf("Secret: "); gets(response); if (strcmp(response, "Joshua") == 0) allowaccess = true; if (allowaccess) { puts("Access granted"); launch_missiles(n_missiles); } if (!allowaccess) puts("Access denied"); } int main(void) { puts("WarGames MissileLauncher v0.1"); authenticate_and_launch(); puts("Operation complete"); } allowaccess (1 byte) response (8 bytes) n_missiles (4 bytes) return address, next intruction in _start pointer to stack frame for _start high address low address return address, next intruction in _main pointer to stack frame for _main pointer to the response buffer return address, authenticate_and_launch() (whatever gets() needs to do) 0x50 0xfa 0xff 0xbf 0x00 0x40 0xfc 0xb7 0x00 0x00 0x00 0x00 0x00 0x39 0xe1 0xb7 0x88 0xfa 0xff 0xbf 0xa0 0x29 0xff 0xb7 0x02 0x00 0x00 0x00 0x00 0x40 0xfc 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x88 0xfa 0xff 0xbf 0x5b 0x85 0x04 0x08 0xbffffa40 0xbffffa6c