ItemDex/RB:085

From Glitch City Wiki
Jump to navigation Jump to search

(↑ Back to the ItemDex index.)

Name (transcribed): B1F
RB item 55 inventory.png

Identifier (HEX): 55
Identifier (DEC): 085
Effect pointer: A7D0
Unterminated name glitch item?: No
Tossable/Sellable?: Yes
Buy Price: 0
Sell Price: 0
Name bytes: {{{9}}}

B1F glitch item name.png (hex:55) is a glitch item in Pokémon Red and Blue. Its name is taken from lists of lift destinations.

Using this glitch item will execute arbitrary code at A7D0 in the SRAM region. SRAM may be locked resulting in a rst $38 freeze; however, viewing a Pokémon summary in the party just before using the item will unlock the SRAM (in bank 0).

0:A7D0 under normal circumstances

Assuming the Hall of Fame was never corrupted, 0:A7D0 can be touched normally in a reliable way. Hall of Fame data starts at A598 and writes (6*0x10)*N bytes, where N is the number of inductions (up to 0x32/dec:50). Entering the Hall of Fame 6 times will write data up to A7D7, and D2F2 onward is moved into A7D0 onward. This begins from the nickname's seventh character of the sixth Pokémon in the party; so code can be written from there (and redirected with a jump or call for more space, if necessary). If the player has entered the Hall of Fame too many times or wants to skip to the sixth induction, they can change D5A2 (the number of inductions) from the expanded PC items.

However, the available opcodes are limited using a normal Pokémon nickname. It may still be possible to craft the Pokémon nickname for a useful code without arbitrary code execution or connection copier (connection copier serves as a pseudo-GameShark similar to a RAM write from arbitrary code execution) but a method to do this has not been published yet.

Application with SRAM ('Hall of Fame') corruptions

As demonstrated by TheZZAZZGlitch, with a series of SRAM corruptions (empirically, these may be seen as Hall of Fame corruptions), it is possible to manipulate the data within the program counter area of B1F (beginning at SRAM:A7D0). If the corruptions are due to sprite decompressions from glitch Pokémon (as viewed from the Pokémon summary in the party; as this opens SRAM specifically in the un-banked area), the outcomes are chaotic (which while technically deterministic are based on the subroutine used to decompress a Pokémon sprite extrapolated further into SRAM than intended).

As the process is complex, viewing certain glitch Pokémon sprites without further knowledge can be viewed as an elaborate pseudo-random number generator for an outcome of bytes in the SRAM, if the initial SRAM is interpreted as a 'seed' (pseudo-random as given the sprite pointer of a glitch Pokémon is not from RAM or SRAM itself, the input SRAM would in theory always produce the same output SRAM).

Coincidentally, the player may come across a desirable outcome after running B1F following these corruptions.

However, it is possible to calculate an exact series of corruptions required for a given result using TheZZAZZGlitch's SRAM corruption emulator.

First, a known series of bytes can be used for seeding the "SRAM RNG"; such as a series of FF bytes from resetting the game, or the game freeze from ゥ (0xC1) (itself, influenced by a front sprite pointer of VRAM:8E8F - which may effectively be the data on the screen just before battle; the font, map sub-tiles, process of the battle transitions to turn sub-tiles solid black can alter this) - in this case, it is sometimes able to fill a portion of the SRAM (including the region accessed by B1F) with a continuous 00 39 or 39 00 pattern.

This is due to a rst 38 (restart vector 0x38, opcode 0xFF which jumps to 0038 containing another rst 38 (0xFF) instruction; corrupting the memory downward from the stack (late DFXX area in WRAM), including potentially the SRAM) to match the pointer of the following address 00 39. The player can test if the desired area became 00 39 from checking the Hall of Fame following a game freeze by ゥ (0xC1) and viewing a series of Level 57 'M (00) in the Hall of Fame, because the decimal Level 57 corresponds with the hexadecimal 0x39, and these 'M have the index number 0 (0x00).

Next, TheZZAZZGlitch's SRAM corruption emulator can be used to calculate the required sequence of Hall of Fame corruptions from glitch Pokémon sprites from the party menu, leading to the desired sequence of bytes. A downside of the SRAM corruption emulator however, is that certain (or longer) sequences of bytes may result in an extremely very long computation time.

LM4 (0xC6) (relative upper area of the SRAM) and Glitch Pokémon (0xDC) (relative lower area of the SRAM) are examples of glitch Pokémon which corrupt the Hall of Fame, and were verified by TheZZAZZGlitch for use with the SRAM corruption emulator.

While Hall of Fame corruptions through glitch Pokémon sprites may be appealing in their own ways, they are not necessary if the player wants more control and efficiency, as the player could simply modify the SRAM with arbitrary code execution precisely in advance, nonetheless it can be desirable by some to grind for a desirable result in advance.

Theoretically, an even more relatively chaotic corruption of the SRAM could be achieved with arbitrary code execution as well; such as through the player's own pseudo-random number generator that they programmed themselves, or perhaps through grabbing environmental noise from the Game Boy Color's infrared port.


Planned SRAM corruptions as a concept outside of 10F

This may eventually be moved to its own article, where the body might be replaced with a template like {{main|[Name of article]}}.

Note this method of calculated/planned sequential SRAM corruptions caused by glitch Pokémon sprites is not only useful for B1F. Furthermore, in the case of arbitrary sprites; it may be possible to corrupt the compressed sprite of the glitch Pokémon as well (affecting the sprite decompression process in another way), potentially leaving more opportunities for control.

Other examples of the usefulness of calculated/planned sequential SRAM corruptions from viewing summary glitch Pokémon sprites are:

  • As a means of precisely manipulating which Pokémon appear in the Hall of Fame.
  • The contents of Trainer (0x34)'s roster 1 (0xFC from 0xD059 and 0x01 from 0xD05D, hence the required Special stat is 252, and the required Attack stat modifier is -6. Specifically however, it is just the representation of $CD2D and $CD2E effectively) depends on the contents of pointer 0xA5A5 in SRAM. This is within the region that can be changed through glitch Pokémon sprite corruptions such as LM4. If the player is able to corrupt the sprite pointer region of a glitch Pokémon for those sourced in SRAM like ゥ₽ (F4) and its front sprite pointer of SRAM:A922, grinding (or calculating the series of corruptions) for an interesting front sprite is an option as well (see also: arbitrary sprites).
  • As a means of manipulating SRAM arbitrary code executions other than 10F (and not strictly limited to glitch items); there are other arbitrary code execution exploits which can attempt to execute SRAM.


If the SRAM corruptions is not restricted to the area corrupted by glitch Pokémon sprites, the SRAM banks or SRAM inaccessibility, then perhaps there is a deterministic way to corrupt any data stored on the save. According to the Pokémon Red disassembly project, the layout of the SRAM is stored as such:

SECTION "Sprite Buffers", SRAM

sSpriteBuffer0:: ds SPRITEBUFFERSIZE
sSpriteBuffer1:: ds SPRITEBUFFERSIZE
sSpriteBuffer2:: ds SPRITEBUFFERSIZE

	ds $100

sHallOfFame:: ds HOF_TEAM * HOF_TEAM_CAPACITY


SECTION "Save Data", SRAM

	ds $598

sGameData::
sPlayerName::  ds NAME_LENGTH
sMainData::    ds wMainDataEnd - wMainDataStart
sSpriteData::  ds wSpriteDataEnd - wSpriteDataStart
sPartyData::   ds wPartyDataEnd - wPartyDataStart
sCurBoxData::  ds wBoxDataEnd - wBoxDataStart
sTileAnimations:: db
sGameDataEnd::
sMainDataCheckSum:: db


; The PC boxes will not fit into one SRAM bank,
; so they use multiple SECTIONs
box_n = 0
boxes: MACRO
REPT \1
box_n += 1
sBox{d:box_n}:: ds wBoxDataEnd - wBoxDataStart
ENDR
ENDM

SECTION "Saved Boxes 1", SRAM

; sBox1 - sBox6
	boxes 6
sBank2AllBoxesChecksum:: db
sBank2IndividualBoxChecksums:: ds 6

SECTION "Saved Boxes 2", SRAM

; sBox7 - sBox12
	boxes 6
sBank3AllBoxesChecksum:: db
sBank3IndividualBoxChecksums:: ds 6

; All 12 boxes fit within 2 SRAM banks
	ASSERT box_n == NUM_BOXES, \
		"boxes: Expected {d:NUM_BOXES} total boxes, got {d:box_n}"

Hence, any of this data could be corrupted. The save checksums must match (there is a single 8 bits copy for the bankless region of SRAM and there are different checksums for banks 1 through 3 as well), but empirically it is just desirable that:

  • The save file is recognised for Continue to appear from the title screen. (An example of an issue may be a player name over 10 characters long).
  • The game does not freeze on boot. (An example of an issue may be the SRAM responsible for loading the data to D36E-F (the "level-script pointer" map script) loaded a pointer pointing to code that freezes the game).
  • "The file data is destroyed!" message does not appear. (An example of an issue may be a bad save checksum).
  • That it's possible in the first place to achieve the desired result while meeting the criteria above through calculation or a tool/SRAM corruption emulator.

As a general concept, the subject may also have implications for the logistics of programming a tool (such as a SRAM corruption emulator). If the tool is given support for algorithmic or mathematical models or a metaheuristic (e.g. simulated annealing) it may be possible to follow/visualise simulations and calculate desired outcomes to the SRAM from a 'seed' as well.

YouTube videos

YouTube video by TheZZAZZGlitch

YouTube video by TheZZAZZGlitch

YouTube video by TheZZAZZGlitch