Atia of the Julii, I call for justice!

Someone Exploited My Scoreboard

Someone managed to exploit a flaw in the way I calculate high scores for my game Gem Story.

As of 8/18/09,


Name Score Level Date
ma 2147483647 16 August 13 2009
Loren 1317023 28 August 16 2009
yan 1108697 9 August 04 2009
Matt 880118 20 August 06 2009
moogleii 313409 17 July 10 2009
smd 298247 1 July 08 2009
bud 284941 32 July 11 2009
Emily 242672 6 July 07 2009
hech 184688 8 July 15 2009
Gg 170662 13 August 05 2009

I thought I had accounted for such a scenario with proper checks, but it looks like I made some false assumptions about how things are cast in Objective-C. Guess I should have read the documentation more thoroughly. I wonder if this is true with C as well. I admit, I haven’t coded in C in a long time.

Anyway, player “ma” got an exorbitant score as you can see. To computer science folks, his particular score number, 2147483647, should immediately pop out.  That happens to be the maximum value for a signed integer.  So I figured he must have lowered his score into the negative, and at some point, my program attempted to assign a negative value to a variable that only accepts positive values. When that happens, the number will wrap around to the other side. So assigning -1 to a positive-only variable will jump the number around to the highest value.

Anyway, as I said, I thought I had accounted for that, by doing something like:

if ( ( NSInteger ) score + ( pointValue * multiplier ) ) > 0 )

but I guess that wasn’t enough. I did some testing (I’ve renamed some stuff to make it a little more readable):

  1. NSUInteger uStartValue = 0;
  2. NSInteger sPointValue = -1000; //signed value
  3. NSUInteger uMultiplier = 10; //unsigned value
  4. NSInteger sMultiTest = sPointValue * uMultiplier; //-10000
  5. BOOL test = NO;
  6. test = (sPointValue * multiplier) > 0; // YES…whut?
  7. NSUInteger unsignedTest = (sPointValue * uMultiplier); //4294957296

So this is interesting. So 7 shows the overflow in action. 6 seems to show that if a mixed-type operation isn’t assigned to a value, then it will default to type NSUInteger, if the operation contains an NSUInteger. But if you explicitly assign it, as in 4, then it’ll work fine.

About The Author


Leave a Reply