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