Hi All,
Consider the following code snippet:
------------------------------------------
#include <stdio.h>
void change()
{
/* write something here so that the printf in main prints the value of
'i' as 10 */
}
int main(void)
{
int i=5;
change();
printf("%d\n",i);
return 0;
}
------------------------------------------
apart from the trivial pre-processor trick like this:
#define printf(a,i) printf(a,2*i)
is there any way to achieve it ?
No.
=====================================
but ...
tim@feynman:~/c$ gcc -Wall -ansi -pedantic -o x x.c
/tmp/ccca0IUM.o(.text+0x20): In function `change':
: warning: the `gets' function is dangerous and should not be used.
tim@feynman:~/c$ ./x
Please enter your password
11111111
Password OK
5
^ This is your i
tim@feynman:~/c$ ./x
Please enter your password
12345678
FAILED
^^^^^^ This is what supposed to happen if you give the wrong password.
tim@feynman:~/c$ ./x
Please enter your password
6666666666666666666666666666D
Password OK
10
^^ This is your i.
This is a very simple stack smashing attack. _Anything_ can happen, what
happens in practice is that an attacker crafts their attack so that the
"anything" becomes what the attacker wants.
===================== bad code follows =====================
The third example given above will probably _NOT_ work the same on your
system if you compile this code. That's what invoking undefined
behaviour means. (I have carefully "crafted" this code to make the
attack easy with my compiler on my system. I suspect that the "attack" is
possible on most systems but you may end up having to do a full stack
smash attack (see Smashing the Stack for Fun and Profit) rather than the
trivial special case I've got here.)
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
/* PASSWORDS are 8 characters plus null */
#define PASS_SZ 9
#define PASSWORD_HASH "66666666"
void change()
{
/* write something here so that the printf in main prints the value of
* 'i' as 10 */
int i = 0;
char buffer[PASS_SZ];
/*
printf("%p\n", (void*) buffer);
printf("%p\n", (void*) &i);
*/
printf("Please enter your password\n");
gets(buffer);
/*
printf("%d\n", i);
printf("%p\n", (void*) (buffer+i));
*/
/* Now "hash" the password */
do
buffer[i++] += 5;
while(i<PASS_SZ);
if(!memcmp(buffer, PASSWORD_HASH, strlen(PASSWORD_HASH)))
printf("Password OK\n");
else
{
printf("FAILED\n");
exit(EXIT_FAILURE);
}
}
int main(void)
{
int i=5;
/*
printf("%p\n", (void*) &i);
*/
change();
printf("%d\n",i);
return 0;
}