Allegro.cc - Online Community

Allegro.cc Forums » Programming Questions » Printing a score

This thread is locked; no one can reply to it. rss feed Print
 1   2 
Printing a score
IroNuckles
Member #1,988
March 2002
avatar

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..

Bob
Free Market Evangelist
September 2000
avatar

textprintf(screen, font, x, y, color, "%i", my_int);

I forgot to mention: the syntax to textprintf (if you click on it), it very similar to printf()'s, so you can use it to output anything.
Just remember, never use printf(my_string), but always printf("%s", my_string);

--
- Bob
[ -- All my signature links are 404 -- ]

kdevil
Member #1,075
March 2001
avatar

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.

-----
"I am the Black Mage! I casts the spells that makes the peoples fall down!"

Johan Peitz
Member #9
April 2000
avatar

Quote:

Just remember, never use printf(my_string), but always printf("%s", my_string);

Why, I wonder?

--
johan peitz :: things I made

Thomas Fjellstrom
Member #476
June 2000
avatar

What happens if the user enters: %s%p%s
as input? ;)

--
Thomas Fjellstrom - [website] - [email] - [Allegro Wiki] - [Allegro TODO]
"If you can't think of a better solution, don't try to make a better solution." -- weapon_S
"The less evidence we have for what we believe is certain, the more violently we defend beliefs against those who don't agree" -- https://twitter.com/neiltyson/status/592870205409353730

dudaskank
Member #561
July 2000
avatar

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

^__^

Toque a balada do amor inabalável, eterna love song de nós dois
Eduardo "Dudaskank"
[ Home Page (ptbr) | Blog (ptbr) | Tetris 1.1 (ptbr) | Resta Um (ptbr) | MJpgAlleg 2.3 ]

Bob
Free Market Evangelist
September 2000
avatar

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.

--
- Bob
[ -- All my signature links are 404 -- ]

dudaskank
Member #561
July 2000
avatar

?????????????????????

How I can reboot a computer with printf?

Printf not only write in stdout?

Now I'm confused:P

Toque a balada do amor inabalável, eterna love song de nós dois
Eduardo "Dudaskank"
[ Home Page (ptbr) | Blog (ptbr) | Tetris 1.1 (ptbr) | Resta Um (ptbr) | MJpgAlleg 2.3 ]

Zaphos
Member #1,468
August 2001

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.

Bob
Free Market Evangelist
September 2000
avatar

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.

--
- Bob
[ -- All my signature links are 404 -- ]

Korval
Member #1,538
September 2001
avatar

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.

Bob
Free Market Evangelist
September 2000
avatar

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 */

--
- Bob
[ -- All my signature links are 404 -- ]

Korval
Member #1,538
September 2001
avatar

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?

Quote:

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...

Quote:

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.

Bob
Free Market Evangelist
September 2000
avatar

Just type in 81 characters at the input. You've now corrupted your stack (again).

--
- Bob
[ -- All my signature links are 404 -- ]

23yrold3yrold
Member #1,134
March 2001
avatar

Thanks Bob; now my code scares the shit outta me ....
::)

--
Software Development == Church Development
Step 1. Build it.
Step 2. Pray.

Bob
Free Market Evangelist
September 2000
avatar

Quote:

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.

Quote:

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.

--
- Bob
[ -- All my signature links are 404 -- ]

23yrold3yrold
Member #1,134
March 2001
avatar

Good; I always use strings over c-strings anyway wipes sweat from brow ;)

--
Software Development == Church Development
Step 1. Build it.
Step 2. Pray.

Zaphos
Member #1,468
August 2001

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?

Bob
Free Market Evangelist
September 2000
avatar

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 :)

--
- Bob
[ -- All my signature links are 404 -- ]

Peter Wang
Member #23
April 2000

Another solution is to not use C/C++ :-)

Thomas Fjellstrom
Member #476
June 2000
avatar

Yes. Perl is nice ;) hmmm. perl and allegro ;) someone needs to finish that perl allegro module ;)

--
Thomas Fjellstrom - [website] - [email] - [Allegro Wiki] - [Allegro TODO]
"If you can't think of a better solution, don't try to make a better solution." -- weapon_S
"The less evidence we have for what we believe is certain, the more violently we defend beliefs against those who don't agree" -- https://twitter.com/neiltyson/status/592870205409353730

Bob
Free Market Evangelist
September 2000
avatar

I think Peter was refering to Lisp. But lisp is evil! Evil I tell you! ;D

--
- Bob
[ -- All my signature links are 404 -- ]

kdevil
Member #1,075
March 2001
avatar

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)

-----
"I am the Black Mage! I casts the spells that makes the peoples fall down!"

dudaskank
Member #561
July 2000
avatar

Bob, if I write this:

#include <stdio.h>

int main(int argc, char *argv[])
{
char str[80];
printf("Escreva uma string: ");
scanf("%79s", str);
printf("%s%p%s\n", str, str, str);

return 0;
}

then the system will be safe?

???

Toque a balada do amor inabalável, eterna love song de nós dois
Eduardo "Dudaskank"
[ Home Page (ptbr) | Blog (ptbr) | Tetris 1.1 (ptbr) | Resta Um (ptbr) | MJpgAlleg 2.3 ]

Bob
Free Market Evangelist
September 2000
avatar

Yes, that should work.

--
- Bob
[ -- All my signature links are 404 -- ]

 1   2 


Go to: