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

C++ idioms by example (Nov 2008)
C++ idioms by example (Nov 2008)C++ idioms by example (Nov 2008)
C++ idioms by example (Nov 2008)Olve Maudal
 
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
 
TDD in C - Recently Used List Kata
TDD in C - Recently Used List KataTDD in C - Recently Used List Kata
TDD in C - Recently Used List KataOlve Maudal
 
Modern c++ (C++ 11/14)
Modern c++ (C++ 11/14)Modern c++ (C++ 11/14)
Modern c++ (C++ 11/14)Geeks Anonymes
 
LLVM 總是打開你的心:從電玩模擬器看編譯器應用實例
LLVM 總是打開你的心:從電玩模擬器看編譯器應用實例LLVM 總是打開你的心:從電玩模擬器看編譯器應用實例
LLVM 總是打開你的心:從電玩模擬器看編譯器應用實例National Cheng Kung University
 
C#や.NET Frameworkがやっていること
C#や.NET FrameworkがやっていることC#や.NET Frameworkがやっていること
C#や.NET Frameworkがやっていること信之 岩永
 
Advanced Programming C++
Advanced Programming C++Advanced Programming C++
Advanced Programming C++guestf0562b
 
Fun with Lambdas: C++14 Style (part 1)
Fun with Lambdas: C++14 Style (part 1)Fun with Lambdas: C++14 Style (part 1)
Fun with Lambdas: C++14 Style (part 1)Sumant Tambe
 
OOP in C++
OOP in C++OOP in C++
OOP in C++ppd1961
 
用十分鐘 向jserv學習作業系統設計
用十分鐘  向jserv學習作業系統設計用十分鐘  向jserv學習作業系統設計
用十分鐘 向jserv學習作業系統設計鍾誠 陳鍾誠
 
組み込みでこそC++を使う10の理由
組み込みでこそC++を使う10の理由組み込みでこそC++を使う10の理由
組み込みでこそC++を使う10の理由kikairoya
 

What's hot (20)

C++ idioms by example (Nov 2008)
C++ idioms by example (Nov 2008)C++ idioms by example (Nov 2008)
C++ idioms by example (Nov 2008)
 
C programming language
C programming languageC programming language
C programming language
 
The Internals of "Hello World" Program
The Internals of "Hello World" ProgramThe Internals of "Hello World" Program
The Internals of "Hello World" Program
 
Interpreter, Compiler, JIT from scratch
Interpreter, Compiler, JIT from scratchInterpreter, Compiler, JIT from scratch
Interpreter, Compiler, JIT from scratch
 
The Microkernel Mach Under NeXTSTEP
The Microkernel Mach Under NeXTSTEPThe Microkernel Mach Under NeXTSTEP
The Microkernel Mach Under NeXTSTEP
 
GDB Rocks!
GDB Rocks!GDB Rocks!
GDB Rocks!
 
Embedded Virtualization applied in Mobile Devices
Embedded Virtualization applied in Mobile DevicesEmbedded Virtualization applied in Mobile Devices
Embedded Virtualization applied in Mobile Devices
 
C++ Programming Course
C++ Programming CourseC++ Programming Course
C++ Programming Course
 
TDD in C - Recently Used List Kata
TDD in C - Recently Used List KataTDD in C - Recently Used List Kata
TDD in C - Recently Used List Kata
 
What Can Compilers Do for Us?
What Can Compilers Do for Us?What Can Compilers Do for Us?
What Can Compilers Do for Us?
 
Learn C Programming Language by Using GDB
Learn C Programming Language by Using GDBLearn C Programming Language by Using GDB
Learn C Programming Language by Using GDB
 
Modern c++ (C++ 11/14)
Modern c++ (C++ 11/14)Modern c++ (C++ 11/14)
Modern c++ (C++ 11/14)
 
LLVM 總是打開你的心:從電玩模擬器看編譯器應用實例
LLVM 總是打開你的心:從電玩模擬器看編譯器應用實例LLVM 總是打開你的心:從電玩模擬器看編譯器應用實例
LLVM 總是打開你的心:從電玩模擬器看編譯器應用實例
 
C#や.NET Frameworkがやっていること
C#や.NET FrameworkがやっていることC#や.NET Frameworkがやっていること
C#や.NET Frameworkがやっていること
 
Advanced Programming C++
Advanced Programming C++Advanced Programming C++
Advanced Programming C++
 
Fun with Lambdas: C++14 Style (part 1)
Fun with Lambdas: C++14 Style (part 1)Fun with Lambdas: C++14 Style (part 1)
Fun with Lambdas: C++14 Style (part 1)
 
OOP in C++
OOP in C++OOP in C++
OOP in C++
 
Functions in C++
Functions in C++Functions in C++
Functions in C++
 
用十分鐘 向jserv學習作業系統設計
用十分鐘  向jserv學習作業系統設計用十分鐘  向jserv學習作業系統設計
用十分鐘 向jserv學習作業系統設計
 
組み込みでこそC++を使う10の理由
組み込みでこそC++を使う10の理由組み込みでこそC++を使う10の理由
組み込みでこそC++を使う10の理由
 

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

Generic or specific? Making sensible software design decisions
Generic or specific? Making sensible software design decisionsGeneric or specific? Making sensible software design decisions
Generic or specific? Making sensible software design decisionsBert Jan Schrijver
 
%in kaalfontein+277-882-255-28 abortion pills for sale in kaalfontein
%in kaalfontein+277-882-255-28 abortion pills for sale in kaalfontein%in kaalfontein+277-882-255-28 abortion pills for sale in kaalfontein
%in kaalfontein+277-882-255-28 abortion pills for sale in kaalfonteinmasabamasaba
 
%+27788225528 love spells in new york Psychic Readings, Attraction spells,Bri...
%+27788225528 love spells in new york Psychic Readings, Attraction spells,Bri...%+27788225528 love spells in new york Psychic Readings, Attraction spells,Bri...
%+27788225528 love spells in new york Psychic Readings, Attraction spells,Bri...masabamasaba
 
AI & Machine Learning Presentation Template
AI & Machine Learning Presentation TemplateAI & Machine Learning Presentation Template
AI & Machine Learning Presentation TemplatePresentation.STUDIO
 
%+27788225528 love spells in Atlanta Psychic Readings, Attraction spells,Brin...
%+27788225528 love spells in Atlanta Psychic Readings, Attraction spells,Brin...%+27788225528 love spells in Atlanta Psychic Readings, Attraction spells,Brin...
%+27788225528 love spells in Atlanta Psychic Readings, Attraction spells,Brin...masabamasaba
 
Introducing Microsoft’s new Enterprise Work Management (EWM) Solution
Introducing Microsoft’s new Enterprise Work Management (EWM) SolutionIntroducing Microsoft’s new Enterprise Work Management (EWM) Solution
Introducing Microsoft’s new Enterprise Work Management (EWM) SolutionOnePlan Solutions
 
VTU technical seminar 8Th Sem on Scikit-learn
VTU technical seminar 8Th Sem on Scikit-learnVTU technical seminar 8Th Sem on Scikit-learn
VTU technical seminar 8Th Sem on Scikit-learnAmarnathKambale
 
Announcing Codolex 2.0 from GDK Software
Announcing Codolex 2.0 from GDK SoftwareAnnouncing Codolex 2.0 from GDK Software
Announcing Codolex 2.0 from GDK SoftwareJim McKeeth
 
Exploring the Best Video Editing App.pdf
Exploring the Best Video Editing App.pdfExploring the Best Video Editing App.pdf
Exploring the Best Video Editing App.pdfproinshot.com
 
Shapes for Sharing between Graph Data Spaces - and Epistemic Querying of RDF-...
Shapes for Sharing between Graph Data Spaces - and Epistemic Querying of RDF-...Shapes for Sharing between Graph Data Spaces - and Epistemic Querying of RDF-...
Shapes for Sharing between Graph Data Spaces - and Epistemic Querying of RDF-...Steffen Staab
 
W01_panagenda_Navigating-the-Future-with-The-Hitchhikers-Guide-to-Notes-and-D...
W01_panagenda_Navigating-the-Future-with-The-Hitchhikers-Guide-to-Notes-and-D...W01_panagenda_Navigating-the-Future-with-The-Hitchhikers-Guide-to-Notes-and-D...
W01_panagenda_Navigating-the-Future-with-The-Hitchhikers-Guide-to-Notes-and-D...panagenda
 
Chinsurah Escorts ☎️8617697112 Starting From 5K to 15K High Profile Escorts ...
Chinsurah Escorts ☎️8617697112  Starting From 5K to 15K High Profile Escorts ...Chinsurah Escorts ☎️8617697112  Starting From 5K to 15K High Profile Escorts ...
Chinsurah Escorts ☎️8617697112 Starting From 5K to 15K High Profile Escorts ...Nitya salvi
 
%in Durban+277-882-255-28 abortion pills for sale in Durban
%in Durban+277-882-255-28 abortion pills for sale in Durban%in Durban+277-882-255-28 abortion pills for sale in Durban
%in Durban+277-882-255-28 abortion pills for sale in Durbanmasabamasaba
 
The Top App Development Trends Shaping the Industry in 2024-25 .pdf
The Top App Development Trends Shaping the Industry in 2024-25 .pdfThe Top App Development Trends Shaping the Industry in 2024-25 .pdf
The Top App Development Trends Shaping the Industry in 2024-25 .pdfayushiqss
 
%+27788225528 love spells in Colorado Springs Psychic Readings, Attraction sp...
%+27788225528 love spells in Colorado Springs Psychic Readings, Attraction sp...%+27788225528 love spells in Colorado Springs Psychic Readings, Attraction sp...
%+27788225528 love spells in Colorado Springs Psychic Readings, Attraction sp...masabamasaba
 
Right Money Management App For Your Financial Goals
Right Money Management App For Your Financial GoalsRight Money Management App For Your Financial Goals
Right Money Management App For Your Financial GoalsJhone kinadey
 
OpenChain - The Ramifications of ISO/IEC 5230 and ISO/IEC 18974 for Legal Pro...
OpenChain - The Ramifications of ISO/IEC 5230 and ISO/IEC 18974 for Legal Pro...OpenChain - The Ramifications of ISO/IEC 5230 and ISO/IEC 18974 for Legal Pro...
OpenChain - The Ramifications of ISO/IEC 5230 and ISO/IEC 18974 for Legal Pro...Shane Coughlan
 
%in Stilfontein+277-882-255-28 abortion pills for sale in Stilfontein
%in Stilfontein+277-882-255-28 abortion pills for sale in Stilfontein%in Stilfontein+277-882-255-28 abortion pills for sale in Stilfontein
%in Stilfontein+277-882-255-28 abortion pills for sale in Stilfonteinmasabamasaba
 
%in Bahrain+277-882-255-28 abortion pills for sale in Bahrain
%in Bahrain+277-882-255-28 abortion pills for sale in Bahrain%in Bahrain+277-882-255-28 abortion pills for sale in Bahrain
%in Bahrain+277-882-255-28 abortion pills for sale in Bahrainmasabamasaba
 

Recently uploaded (20)

Generic or specific? Making sensible software design decisions
Generic or specific? Making sensible software design decisionsGeneric or specific? Making sensible software design decisions
Generic or specific? Making sensible software design decisions
 
%in kaalfontein+277-882-255-28 abortion pills for sale in kaalfontein
%in kaalfontein+277-882-255-28 abortion pills for sale in kaalfontein%in kaalfontein+277-882-255-28 abortion pills for sale in kaalfontein
%in kaalfontein+277-882-255-28 abortion pills for sale in kaalfontein
 
%+27788225528 love spells in new york Psychic Readings, Attraction spells,Bri...
%+27788225528 love spells in new york Psychic Readings, Attraction spells,Bri...%+27788225528 love spells in new york Psychic Readings, Attraction spells,Bri...
%+27788225528 love spells in new york Psychic Readings, Attraction spells,Bri...
 
AI & Machine Learning Presentation Template
AI & Machine Learning Presentation TemplateAI & Machine Learning Presentation Template
AI & Machine Learning Presentation Template
 
%+27788225528 love spells in Atlanta Psychic Readings, Attraction spells,Brin...
%+27788225528 love spells in Atlanta Psychic Readings, Attraction spells,Brin...%+27788225528 love spells in Atlanta Psychic Readings, Attraction spells,Brin...
%+27788225528 love spells in Atlanta Psychic Readings, Attraction spells,Brin...
 
Introducing Microsoft’s new Enterprise Work Management (EWM) Solution
Introducing Microsoft’s new Enterprise Work Management (EWM) SolutionIntroducing Microsoft’s new Enterprise Work Management (EWM) Solution
Introducing Microsoft’s new Enterprise Work Management (EWM) Solution
 
VTU technical seminar 8Th Sem on Scikit-learn
VTU technical seminar 8Th Sem on Scikit-learnVTU technical seminar 8Th Sem on Scikit-learn
VTU technical seminar 8Th Sem on Scikit-learn
 
Announcing Codolex 2.0 from GDK Software
Announcing Codolex 2.0 from GDK SoftwareAnnouncing Codolex 2.0 from GDK Software
Announcing Codolex 2.0 from GDK Software
 
Exploring the Best Video Editing App.pdf
Exploring the Best Video Editing App.pdfExploring the Best Video Editing App.pdf
Exploring the Best Video Editing App.pdf
 
Shapes for Sharing between Graph Data Spaces - and Epistemic Querying of RDF-...
Shapes for Sharing between Graph Data Spaces - and Epistemic Querying of RDF-...Shapes for Sharing between Graph Data Spaces - and Epistemic Querying of RDF-...
Shapes for Sharing between Graph Data Spaces - and Epistemic Querying of RDF-...
 
W01_panagenda_Navigating-the-Future-with-The-Hitchhikers-Guide-to-Notes-and-D...
W01_panagenda_Navigating-the-Future-with-The-Hitchhikers-Guide-to-Notes-and-D...W01_panagenda_Navigating-the-Future-with-The-Hitchhikers-Guide-to-Notes-and-D...
W01_panagenda_Navigating-the-Future-with-The-Hitchhikers-Guide-to-Notes-and-D...
 
Chinsurah Escorts ☎️8617697112 Starting From 5K to 15K High Profile Escorts ...
Chinsurah Escorts ☎️8617697112  Starting From 5K to 15K High Profile Escorts ...Chinsurah Escorts ☎️8617697112  Starting From 5K to 15K High Profile Escorts ...
Chinsurah Escorts ☎️8617697112 Starting From 5K to 15K High Profile Escorts ...
 
%in Durban+277-882-255-28 abortion pills for sale in Durban
%in Durban+277-882-255-28 abortion pills for sale in Durban%in Durban+277-882-255-28 abortion pills for sale in Durban
%in Durban+277-882-255-28 abortion pills for sale in Durban
 
The Top App Development Trends Shaping the Industry in 2024-25 .pdf
The Top App Development Trends Shaping the Industry in 2024-25 .pdfThe Top App Development Trends Shaping the Industry in 2024-25 .pdf
The Top App Development Trends Shaping the Industry in 2024-25 .pdf
 
CHEAP Call Girls in Pushp Vihar (-DELHI )🔝 9953056974🔝(=)/CALL GIRLS SERVICE
CHEAP Call Girls in Pushp Vihar (-DELHI )🔝 9953056974🔝(=)/CALL GIRLS SERVICECHEAP Call Girls in Pushp Vihar (-DELHI )🔝 9953056974🔝(=)/CALL GIRLS SERVICE
CHEAP Call Girls in Pushp Vihar (-DELHI )🔝 9953056974🔝(=)/CALL GIRLS SERVICE
 
%+27788225528 love spells in Colorado Springs Psychic Readings, Attraction sp...
%+27788225528 love spells in Colorado Springs Psychic Readings, Attraction sp...%+27788225528 love spells in Colorado Springs Psychic Readings, Attraction sp...
%+27788225528 love spells in Colorado Springs Psychic Readings, Attraction sp...
 
Right Money Management App For Your Financial Goals
Right Money Management App For Your Financial GoalsRight Money Management App For Your Financial Goals
Right Money Management App For Your Financial Goals
 
OpenChain - The Ramifications of ISO/IEC 5230 and ISO/IEC 18974 for Legal Pro...
OpenChain - The Ramifications of ISO/IEC 5230 and ISO/IEC 18974 for Legal Pro...OpenChain - The Ramifications of ISO/IEC 5230 and ISO/IEC 18974 for Legal Pro...
OpenChain - The Ramifications of ISO/IEC 5230 and ISO/IEC 18974 for Legal Pro...
 
%in Stilfontein+277-882-255-28 abortion pills for sale in Stilfontein
%in Stilfontein+277-882-255-28 abortion pills for sale in Stilfontein%in Stilfontein+277-882-255-28 abortion pills for sale in Stilfontein
%in Stilfontein+277-882-255-28 abortion pills for sale in Stilfontein
 
%in Bahrain+277-882-255-28 abortion pills for sale in Bahrain
%in Bahrain+277-882-255-28 abortion pills for sale in Bahrain%in Bahrain+277-882-255-28 abortion pills for sale in Bahrain
%in Bahrain+277-882-255-28 abortion pills for sale in Bahrain
 

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