I'm trying to write a simple pong-type game. My question is, how do you output an integer?! I haven't found it in any documentation that I've seen so far, but maybe I'm not look hard enough..
Alternatively, you could also do this:
char msg[20];
sprintf(msg, "%-1d", some_int);
textout(screen, font, msg, x, y, color);
This is what I use, even though it's much messier than textprintf.
Just remember, never use printf(my_string), but always printf("%s", my_string);
Why, I wonder?
What happens if the user enters: %s%p%s
as input?
Well, i think printf(my_string) and printf("%s", my_string) is the same thing
#include <stdio.h> int main(int argc, char *argv[]) { char str[80] = "Olá"; printf("%s%p%s", str, str, str); return 0; }
In this code, you will print a string (%s), the address (%p) in memory of the same string and another string (%s) equal the first
^__^
dudaskank: Ok, now make str[80] an input from the user (or some file).
Now I can crash your program, or corrupt your system (*cough* Win9X), forcing you to reboot. If the program also has high priority (ie, has root or admin priviledges), then I have taken control of your computer, or perhaps used it to hack into someone else's computer, and putting the blame entirely on you.
Of course, all of this could have been avoided by not using printf(str) in the first place.







How I can reboot a computer with printf?
Printf not only write in stdout?
Now I'm confused:P
No ... I don't think printf can do that ... I think Bob is referring to inputting to str[80] ... presumably with a c input function ... such that you try to put too many characters in your buffer, and cause buffer-overrun.
Zaphos: no, I'm refering to both.
dudaskank: I suggest you pick up an assembly book and have a look at how your C/C++ code is really done by the machine.
The fact is, if you do something like printf(my_str), and my_str can be inputted by the user somehow (read from a file, input by the keyboard), you have a big hole there because I can overwrite the call stack, and more specifically, the return address on the stack. So after printf has completed printing junk, it will return not to your routine, but to my routine. After that, I can make your PC do whatever I want.
90% of all security holes that you are hearing about are due to printf, scanf and similar functions. This is a serious issue with C/C++, which needs to be fixed.
I think I understand what he's saying. Printf takes as it's first argument a char*. Now, this char* could be any number of things, including:
1: NULL.
2: A pointer to the stack.
3: A pointer to random memory.
4: A pointer to an actually valid char*.
If that pointer isn't valid, then printf is going to start trashing memory randomly, especially when it hits a %* character that will have it request an argument from the argument list.
Although I don't quite understand how it can kill Windows 9X. They do have some form of memory protection. It's not as robust as XP or 2000, but it's there.
And God help you if you do this on a Mac.
It'd be pretty difficult to actually force printf to do something so specific as write over the return address on the call stack with a particular value. You'd have to know a great deal about how printf is implemented to pull that one off.
When you call printf, variables get pushed on the stack, then printf reads them by poping them off.
If it reads a "%s" but no string was pushed on the stack, then printf pops up one argument too many - most likely the return address. So if you play correctly and your original string contains an address of some other procedure, then printf can end up returning to that procedure instead. It does require knowledge of how printf is implemented, but there are only so many compilers out there...
Win9X has basically no memory protection, since you can request and write to the <1 MB memory area. This is where you do the most damage since that's where all the important stuff is kept (DMA transfer, memory mapped registers, paging tables, etc).
Of course, doing the same with scanf is even easier - just push one argument too many...
Did I mention you can do the same in C++?
char str[80]; cin >> str; /* Boom */
I follow how the "printf" version works (although I claim that such things could be avoided simply by not having variable paramter arguments passed through the stack, but through the heap), but how does that "cin" die?
If it reads a "%s" but no string was pushed on the stack, then printf pops up one argument too many - most likely the return address.
Hey, that's the fault of a processor that has so few registers that it can't even store the return address in a register. Granted, other return addresses are still there on the stack, but you don't necessarily know where they are. God, I hate x86...
Win9X has basically no memory protection, since you can request and write to the <1 MB memory area. This is where you do the most damage since that's where all the important stuff is kept (DMA transfer, memory mapped registers, paging tables, etc).
It has some. You can't access outside of your virtual address space.
Just type in 81 characters at the input. You've now corrupted your stack (again).
Thanks Bob; now my code scares the shit outta me ....
Hey, that's the fault of a processor that has so few registers that it can't even store the return address in a register. Granted, other return addresses are still there on the stack, but you don't necessarily know where they are. God, I hate x86...
Well, even on CPUs that do store the return address in a register, they usually put it on the stack when they need to call a function, as to place the new return address in that register. So even on those nifty other CPUs out there, you have the same problem.
Thanks Bob; now my code scares the shit outta me ....
AFAIK the string class fixes most of those holes by being able to dynamically resize. So
string in; cin >> in;
Should work without any problems.
Good; I always use strings over c-strings anyway wipes sweat from brow
Right ... that's worse than I had previously thought ... 
How do you avoid it then? Just use <string>s (or equivalent) for any string data that the user can access? Is that the only way?
In C, you can use fgets(), or (f/s)scanf() with width paramters. You could also build your own string object in C.
I'll probably do that at some point, just because C strings are starting to be a pain in the arse
Another solution is to not use C/C++ :-)
Yes. Perl is nice
hmmm. perl and allegro
someone needs to finish that perl allegro module
I think Peter was refering to Lisp. But lisp is evil! Evil I tell you!
In a computer science course I took over the summer, we used a bit of lisp, and we also learned that lisp stands for "Lots of Irritating Stupid Parentheses." 8)
Yes, that should work.
No, I bet Peter was referring to Lua.
Lua's not bad. But Im addicted to perl.
maybe when there exists a language that is as powerfull as C and as powerfull/timtowtdi/easy as perl is i might switch.
Bob has heard my rants a little more :-) I was thinking of Scheme (a cleaned up dialect of Lisp). I like Lua too, which is getting to be more like Scheme (Pascal-like syntax for people who can't understand the beauty of brackets ;-)
But naming a specific language only detracts from what I wanted to say in my previous post. Don't use unnecessarily low level languages if you can avoid it.
And now I'm going to get flamed.
I'm trying to write a simple pong-type game.My question is,how do you output an integer?!
Printing a Score related to Perl?Lisp?:o
does that game will be run on a Web server?
it's not a security forum. Bob don't scare him(and me)!
All he said was:
>>Don't use printf(string), use printf("%s", string)<<
Which is absolutely correct. An even without the security implications (If I can enter the string in the game, I could also simply turn the power button... no need to screw the stack here) - you don't want to have gibberish on the screen.
And if I recall correctly, printf is defined to take a "format" string as 1st and then the output strings as second paramter. So, if you don't supply a format string, it's your fault.
And I think playing safe is something we all should do in all of our programs.
(Guess I should add some more return value checks to my programs, now)
Side note:
How do I: supply an function using the string and then push the address to that function onto the stack?
Sounds faszinating. Can I use this for scripting purposes?
spellcaster: no, the format string will be taken as the "string" parameter. You just won't have any params. This is equivalent to writting printf("hi!"); The problems come from you write printf("Hi%i!");...