Advertisement
TheFastFish

rambug thing

Jun 30th, 2016
559
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 3.33 KB | None | 0 0
  1. # RAMBUG THING #
  2. ## Rambly document by slackerSnail ##
  3.  
  4. ## WHY DOES BGSCREEN TRIGGER THIS BUG? ##
  5. **Please be warned: some of this might be wrong, just going off what I can observe.**
  6.  
  7. The `BGSCREEN` command resizes a background tile layer to the specified width and height in tiles.
  8. The BG layer's width times its height is not allowed to exceed 16383 tiles. In most cases, this holds true.
  9. However, sometimes this isn't caught.
  10.  
  11. The width and height arguments are typed as signed 32-bit integers
  12. (thus, their range is from -2147483648 to 2147483647.) When a number that isn't a valid integer
  13. is passed to an argument that only accepts ints, it goes through an implicit cast.
  14. This cast truncates the fractional part of the number (if present) and checks if the number
  15. is within integer bounds. If it isn't, you get error `Out of range`.
  16.  
  17. The BG layer size is allowed to exceed its limit if the following conditions hold true:
  18. - The width and height arguments to the command are proper integers
  19. - Neither of the dimensions can be negative or 0, as SB will catch this and throw an error
  20. - The dimensions, when multiplied, must **exceed** integer bounds
  21. - in other words, WxH must be 2147483648 or greater
  22. - If the result of the multiply is TOO big
  23. (not yet determined, probably when it runs into the unreadable RAM block)
  24. SB will just softcrash.
  25.  
  26. Thus, the challenge was determining what dimension sizes to use to properly throw the bug.
  27. I used the values 134217728 for width and 16 for height, because they multiply exactly to 2147483648
  28. and are both valid ints. What happens is, presumably, the memory pointer for the BG layer is set to the
  29. wrong location because a size of this magnitude is unexpected. The BG layer then becomes a window into RAM,
  30. each tile holding 2 bytes in little-endian order. The memory layout extends top-to-bottom, left-to-right in
  31. terms of tile layout (instead of left-to-right top-to-bottom as I expected.) I'm not an expert, so much of
  32. the RAM contents are Greek to me, though areas of interest include the current console text, name listings
  33. for the help and autocomplete, name strings for menu dialogs, etc.
  34.  
  35. My assumption for why a multiply could be allowed to exceed bounds undetected is still unclear.
  36. A thought I have is that SB works in all math as double-precision by default, and that casting steps for ints
  37. perform after the fact. It might just perform a lazy cast to int to determine it's in proper bound, and use
  38. the unchecked result in the size. I have no idea.
  39.  
  40. ## HOW COULD THEY PATCH THIS? ##
  41. A patch for this would be really easy. All they would have to do is check if the arguments are ints in the
  42. range of 0-16383 BEFORE multiplying to find the total size. If the ints exceed the range, you're not allowed
  43. to resize it. Boom, error. It's THAT easy. Range checking exists on other commands as far as I know, so it's not
  44. like it's difficult. The memory is only resized if the total size exceeds an integer, something like 8192x2 would
  45. throw as too big of a BG layer, so locking down the argument range before multiply guarantees the exploit is unusable.
  46.  
  47. ## WHAT CAN WE DO WITH THIS? ##
  48. BG layer contents are manipulateable as well as readable, so you basically have read/write RAM access.
  49. In brief, `BGGET` gets the 16-bit value from a tile and `BGPUT` sets it. I'm not the SB manual,
  50. go read it yourself.
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement