Main Menu
Main Page
Forums
Recent changes
Random page
Help

Databases
GlitchDex
AttackDex
AreaDex
DexDex
ItemDex
TMHMDex
TypeDex
More

Major Glitches
Trainer escape glitch
Old man trick
Celebi Egg trick
SRAM glitch
Buffer overflow techniques
Pomeg glitch data corruption (Glitzer Popping)
Tweaking
Pokémon cloning
Select glitches (Japan)
Time Capsule exploit
Arbitrary code execution
More

Other Glitch Categories
Glitches by generation
Japan-only/language specific glitches
Natural glitches
Non-core series glitches
Non-Pokémon glitches
Recurring glitches
More

References
Pokémon GameShark codes
The Big HEX List
GB programming
Curiosities
Debugging features
Error traps
Non-glitch exploits
Pokémon glitch terminology
Unused content and prerelease information
More

Useful Tools
8F Helper
GBz80 to Items
Old man trick name generator
PATH (Prama's Advanced Tweaking Heaven)
Save file editors
Special stat/Pokémon converter
Trainer escape Trainer Pokémon finder

Affiliates
Legendary Star Blob 2 (Hakuda)
Pokémon Speedruns wiki
PRAMA Initiative
Become an affiliate!

Technical
Site Source Code

Search Wiki

 

Search Forums

 

Author Topic: Initiating ACE during game startup in Pokemon Crystal  (Read 168 times)

0 Members and 1 Guest are viewing this topic.

Npo

  • GCLF Member
  • Offline Offline
  • CHARIZRAD 'M ROXORX or is it.
    • View Profile
Initiating ACE during game startup in Pokemon Crystal
« on: May 16, 2018, 01:06:13 pm »
So now that I have lots of free time for the summer I decided to look into setting up a save file that has ACE running all the time, and will continue to run even after a reset. The way I intend to do this is by editing the player name to contain the char $15 00, this will cause the game to jump to $cd52 which holds data corresponding to map tiles. The first time the player name is read after a reset is after the player selects 'Continue' from the start menu. If I can get the byte $c9 to be written to that part of memory then the program counter will return to after the address where the $15 00 char in the player name and will execute the rest of the player name as asm. Then from their I can write a jump to somewhere else in ram that had been previously set up to run whatever I want.

Editing the player name to have the char 50 00 in it can be done using a different ACE method, and by writing directly to SRAM instead of wram we won't have to worry about trying to save the game afterword, as doing so would cause the game to read the player name and thus cause the game to start running code from ram.

The first problem is trying to get the byte $c9 written to $cd52 before the game reads the $15 00 sequence. My solution to this is to make the player's name so long that as the game reads the name it will overwrite that part of memory with the char $c9. When the game starts reading the player name it stores the location of where to print the name in memory in hl which at the start of the name hl=$c574, we need to get hl up to $cd52. I found while looking into the unused mobile char functions, that the char sequence

$15 04 -- -- xx 50      where '--' is just any char, and 'xx' is some byte.

will cause the game to 'skip' xx spaces in it's output, effectively adding 'xx' to hl. However, I want to keep the player name short enough to fit in the 10 char limit so that the entire name is loaded when the game resets. To do this i will use char that refence other 'names' in the game.

The game actually has memory stored for Mom's name, Red's name and Green's name. It seems that the developers once intented the player to be able to change these NPC's names, but since that was never implemented the names stored in RAM are never refrenced in normal play. This means if we edit those names in ram, we can refrence them in the player name using the chars $49, $39, $38 for Mom's, Green's and Red's names respectivly.

Finaly we have what we need to set up the exploit. Here are the names we need for each character for the exploit to work.
Mom's name:    15 04 00 00 ff 50 50 (skip 255 char)
Red's  name:    15 04 00 00 f2 50 50 (skip 242 char)
Green's name:  49 49 49 38 50 ( skip 255 + 255 + 255 +242 = 1007 char)
Your name:       39 39 c9 15 00 c3 0e da 50  (skip 1,007*2=2,014 char then write c9...)

the player name when read will then cause the game to jump to $da0e which then should contain code to fix the player name so that once it is read again it will be as normal, and also initiate an HRAM hook allowing for pretty much anything.

It's important to note that the game actually reads the player name once before it actually prints it anywhere on screen after picking continue, this means that (assuming the code at $da0e will fix the player name) the game should appear to run normaly.

I will attach a link to a save file / save-state for bgb which is set up to run a "Rainbow Pallet" payload where the players pallet is randomly changed every frame as an example of how this would work.
https://drive.google.com/drive/folders/13Lwo0_5bhnaZCFnNf_B12oGJA26XHF3-?usp=sharing

---------------------
That was a pretty dense look at what I have been doing, but basically I made a way to have ACE on startup, my next goal is to write a method that will run with the HRAM hook and will detect when the player saves to fix the player name in SRAM so that when the game resets after a save the exploit will still work. If I can get that to work then this would open up the possibility of a functional "mod" to the gen 2 pokemon games. I will update this post in the future with the asm code for fixing the player name and implementing the HRAM hook.






ISSOtm

  • The French Lord of Laziness (and a huge The Legend Of Zelda fan)
  • Staff
  • *****
  • Offline Offline
  • Gender: Male
  • Pewter City (B)rocks !
    • View Profile
    • My Little Website
Re: Initiating ACE during game startup in Pokemon Crystal
« Reply #1 on: May 17, 2018, 07:13:30 am »
To detect if the player saved, you can check if the "SAVE" option in the menu has been selected (I think this could be detected by checking the cursor tile). I'm interested in this as well, I could lend you a hand if you want.
However, which version of Crystal are you using? (MD5/SHA1 if possible, please)
I'd prefer to use the US versions if possible, due to the SYM file provided by the disassembly.
« Last Edit: May 17, 2018, 07:55:29 am by ISSOtm »
"THOU SHALL NOT PASS !!"  RIVAL's effect, Gandalf.

Proudly glitching Pokémon Red and Yellow on a Black & White GB, Pocket GB, GB Color, GBA SP and new 3DS.

My Twitter (beware, I'm French)
My YouTube (same warning)

Here is an online tool to build 8F setups : GBz80 to Items !

They see me layzin', they ha-tin'...
Heavy contributor of the global augmentation of entropy (my room's is too damn high !)

Npo

  • GCLF Member
  • Offline Offline
  • CHARIZRAD 'M ROXORX or is it.
    • View Profile
Re: Initiating ACE during game startup in Pokemon Crystal
« Reply #2 on: May 17, 2018, 09:46:04 am »
I am using :
Pokemon - Crystal Version (UE) (V1.1)
MD5: 54858AA278A0576B545FDC35CDBD1CF8

Although Since i'm pretty early in the project I am totally willing to use a different version if that would be helpful. For the Save detection, I think we would need to test more then just if the player has selected the save option since it's possible to save the game other ways as well, initiating a trade, going to the hall of fame, switching Pokemon boxes and such. Looking at the save procedure it seems that every time the game is saved the method PauseGameLogic is called and sets a byte in ram. I'm pretty sure this is the only time in normal play this happens so I think checking for that byte might be the best way of doing that. Later today I will post the asm code needed to fix the player's name and set up the hram hook.

EDIT:
So here is the asm code for the exploit starting at DA0E
This is probably not the best way to implement an hram hook but it's what I was able to figure out...
I had some problems where somethimes part of wram would be 'missing' and not contain the payload, so to fix this I check to see
if the last opcode of the exploite hasn't been changed to make sure it's safe to execute the payload..



Code: [Select]
DA0E:
di /might not be nesicary just easier to check for mistakes
push hl
push bc
push de /this is so we can return to romal code without any prblm
ld de,ffed /where the hram hook needs to go
ld hl,da65 /where it is stored
ld bc,000c /length of hram hook
call 3026 /copy data function
ld a,64
ld (ff00+88),a /cause the hram loop to jr to ffed
ld de,d47d /player name in wram
ld hl,da5b /backup of our player name
ld c,0a /size of player name
call 3026 /coby bytes
pop de
pop bc
pop hl /get ready to return to normal play
scf /Important! game wont stop printing char of player name otherwise
reti    /Note this byte is also checked by the hram hook to ensure it is 'safe' to execute the payload

Hram hook stored at DA65:
dec a 3d
jr nz,ffed 20 fd
ld a,(da31) fa 31 da /check byte for reti opcode to make sure it's safe to execute payload...
cp a,d9 fe d9
jp z,da32 ca 32 da
ret c9

example payload (rainbow pallet) stored at DA32
ld a,(ff00+e2)
ld (d4dc),a
ret
I'm not too happy with this asm code and will probably come back to this but it works as a proof of concept.

« Last Edit: May 17, 2018, 10:24:48 am by Npo »

ISSOtm

  • The French Lord of Laziness (and a huge The Legend Of Zelda fan)
  • Staff
  • *****
  • Offline Offline
  • Gender: Male
  • Pewter City (B)rocks !
    • View Profile
    • My Little Website
Re: Initiating ACE during game startup in Pokemon Crystal
« Reply #3 on: May 17, 2018, 12:14:17 pm »
I actually re-did all your work on my own side, in order to have a RGBDS setup that patches in any save file. It's currently working! If you want, I can publish this to a GitHub repo and work from there.

I'm currently using the US Crystal 1.0 version built from pokecrystal (MD5: 9f2922b235a5eeb78d65594e82ef5dde), on which your exploit seemed to work out of the box.
Btw, US Crystal 1.1 (as built from pokecrystal, again) has a MD5 of 301899b8087289a6436b0a241fbbb474.


Checking if saving has occurred is actually trivial. Switch to SRA1, check if the player's name is still out exploit's name (checking for the first byte is enough, since the "Green's name" control char shouldn't be obtainable by the player). If that's the case, patch in the existing save, and call `Checksum`, and finally write it back. (This might be actually a bit dangerous if the code triggers while in the normal `Checksum` function, but there's a chance it doesn't occur)


As for the HRAM hook, here's how I do it:
Code: [Select]
OAMHook: ; Ends up at FF80
    call $C002
    ld [$ff00+c], a

DMALoader: ; Ends up at $C000
    ; Code here...

    ; Set up regs for DMA to go on smoothly
    ld c, $46 ; LOW(rDMA)
    ld a, $C4 ; HIGH(wVirtualOAM)
    ret
DMALoaderEnd:

NewPlayerName:
    db "GCL@"

InitialPayload:
    di
    push bc
    push de
    push hl
    ; Hook OAM DMA
    ld hl, OAMHook
    ld bc, 4 << 8 | $80
.copyOAMHook
    ld a, [hli]
    ld [$ff00+c], a
    inc c
    dec b
    jr nz, .copyOAMHook
    ; Copy loader to WRAM
    ld hl, DMALoader
    ld de, $C000 ; Stack space, of which a lot is usually available
    ld bc, DMALoaderEnd - DMALoader
    call CopyBytes
    ld de, NewPlayerName
    ld hl, wPlayerName
    call CopyName2
    pop hl
    pop de
    pop bc
    scf
    reti
(In my source, it's a bit different, due to requiring some artifacts to get RGBDS to output code with the proper, WRAM, addresses)

A side note regarding the use of C000+ as storage: this works fine, except with Withdraw Smash ACE. Should be OK, I guess.

Another side note as to how to restore the player's name: instead of copying a default name, we can probably fetch it from the save backup instead!
[EDIT] Sadly, the backup is overwritten before our name is evaluated, thus, we can't restore the name from the backup. My other idea is to instead store the player's name in another region of SRAM, and copy back from there. (Side note, I'm aiming at something like MrCheeze's virus, which can be applied to basically any save file, thus we could copy the player's name to an unused SRAM section before patching takes place)

And finally, another quirk: the game uses the Mom's name to store the player's during the Dude's catching tutorial. We'd have to patch that as well with the exploit's string.
« Last Edit: May 17, 2018, 12:43:14 pm by ISSOtm »
"THOU SHALL NOT PASS !!"  RIVAL's effect, Gandalf.

Proudly glitching Pokémon Red and Yellow on a Black & White GB, Pocket GB, GB Color, GBA SP and new 3DS.

My Twitter (beware, I'm French)
My YouTube (same warning)

Here is an online tool to build 8F setups : GBz80 to Items !

They see me layzin', they ha-tin'...
Heavy contributor of the global augmentation of entropy (my room's is too damn high !)

Npo

  • GCLF Member
  • Offline Offline
  • CHARIZRAD 'M ROXORX or is it.
    • View Profile
Re: Initiating ACE during game startup in Pokemon Crystal
« Reply #4 on: May 17, 2018, 01:16:39 pm »
Wow! That's Great!

I like the idea of checking the SRAM to see if the name has changed, I'm not entirely familiar with the GB hardware but would there be a problem with unlocking / locking SRAM every frame? Or would you just be checking to see if it has changed when sram is already unlocked ie. when the game is saving?

As for the Mom's name being over written during the dude tutorial, I had no idea that happens. So I came up with a new set of names that only uses Red's and Green's names for the exploit to work, that way we won't have to worry about fixing / checking for Mom's name being overwritten.
Here are the new names:

RED:       15 04 00 00 FF 50 50
GREEN:   15 04 00 00 E5 50 38 38 38 38 50
YOUR's:   39 38 38 38 C9 15 00 C3 0E DA 50

If you replace these names with the ones I currently use then it should load the payload just fine.

And I love the idea of recreating MrCheeze's virus in gen 2. (That was part of the reason I started working on this...)

Also a GitHub repo would be great!

ISSOtm

  • The French Lord of Laziness (and a huge The Legend Of Zelda fan)
  • Staff
  • *****
  • Offline Offline
  • Gender: Male
  • Pewter City (B)rocks !
    • View Profile
    • My Little Website
Re: Initiating ACE during game startup in Pokemon Crystal
« Reply #5 on: May 17, 2018, 01:17:53 pm »
Alright, I'll try with the new names, and when I get something working, I'll publish a repo :)
"THOU SHALL NOT PASS !!"  RIVAL's effect, Gandalf.

Proudly glitching Pokémon Red and Yellow on a Black & White GB, Pocket GB, GB Color, GBA SP and new 3DS.

My Twitter (beware, I'm French)
My YouTube (same warning)

Here is an online tool to build 8F setups : GBz80 to Items !

They see me layzin', they ha-tin'...
Heavy contributor of the global augmentation of entropy (my room's is too damn high !)

ISSOtm

  • The French Lord of Laziness (and a huge The Legend Of Zelda fan)
  • Staff
  • *****
  • Offline Offline
  • Gender: Male
  • Pewter City (B)rocks !
    • View Profile
    • My Little Website
Re: Initiating ACE during game startup in Pokemon Crystal
« Reply #6 on: May 17, 2018, 01:50:50 pm »
I think this is enough to warrant a double-post, but... the new names worked perfectly, BGB keeps breaking due to accessing disabled SRAM (intended, lel), but it's working!

[EDIT]
The GitHub repository is live!
« Last Edit: May 17, 2018, 03:54:15 pm by ISSOtm »
"THOU SHALL NOT PASS !!"  RIVAL's effect, Gandalf.

Proudly glitching Pokémon Red and Yellow on a Black & White GB, Pocket GB, GB Color, GBA SP and new 3DS.

My Twitter (beware, I'm French)
My YouTube (same warning)

Here is an online tool to build 8F setups : GBz80 to Items !

They see me layzin', they ha-tin'...
Heavy contributor of the global augmentation of entropy (my room's is too damn high !)

Torchickens

  • Administrator
  • *****
  • Offline Offline
  • Gender: Female
  • The Torchic Princess 🌸🦋
    • View Profile
Re: Initiating ACE during game startup in Pokemon Crystal
« Reply #7 on: May 17, 2018, 03:34:09 pm »
Wow. :O This sounds amazing!

ISSOtm, can you upload a save file please, and I can mirror it?

Thanks.
Hi! I identify as female.  She/her pronouns, please.

Online I most often use the username Torchickens or Chickasaurus.

Ah.. koucha ga oishii ♪





Thank you Captain Piika for my avatar.

Thanks too Aeriixion for the cute sprite above! :) Roelof also made different variations of the sprite (which I animated).

Contact:
If you like, please contact me by private message here on the forums as I no longer check other places very often.

YouTube: http://www.youtube.com/user/ChickasaurusGL

I like to collect interesting video games. ^_^
https://www.vgcollect.com/Torchickens

Always be yourself.

ISSOtm

  • The French Lord of Laziness (and a huge The Legend Of Zelda fan)
  • Staff
  • *****
  • Offline Offline
  • Gender: Male
  • Pewter City (B)rocks !
    • View Profile
    • My Little Website
Re: Initiating ACE during game startup in Pokemon Crystal
« Reply #8 on: May 17, 2018, 03:57:30 pm »
I'm doubtful to upload a save file as long as I haven't made sure that saving is at least 99% fail-proof. Currently hard-resetting wile the game is saving may permanently "uninstall" the exploit. (The save patching currently only takes place when SRAM has been re-locked, which seems to happen very late into the process)

I'll also be providing a patching program (probably Python) later on, when I get around to meta-program it from the RGBDS output \o/
"THOU SHALL NOT PASS !!"  RIVAL's effect, Gandalf.

Proudly glitching Pokémon Red and Yellow on a Black & White GB, Pocket GB, GB Color, GBA SP and new 3DS.

My Twitter (beware, I'm French)
My YouTube (same warning)

Here is an online tool to build 8F setups : GBz80 to Items !

They see me layzin', they ha-tin'...
Heavy contributor of the global augmentation of entropy (my room's is too damn high !)

Torchickens

  • Administrator
  • *****
  • Offline Offline
  • Gender: Female
  • The Torchic Princess 🌸🦋
    • View Profile
Re: Initiating ACE during game startup in Pokemon Crystal
« Reply #9 on: May 17, 2018, 04:05:26 pm »
I'm doubtful to upload a save file as long as I haven't made sure that saving is at least 99% fail-proof. Currently hard-resetting wile the game is saving may permanently "uninstall" the exploit. (The save patching currently only takes place when SRAM has been re-locked, which seems to happen very late into the process)

I'll also be providing a patching program (probably Python) later on, when I get around to meta-program it from the RGBDS output \o/

I see. That's OK.

Good luck in further developing it. :)
Hi! I identify as female.  She/her pronouns, please.

Online I most often use the username Torchickens or Chickasaurus.

Ah.. koucha ga oishii ♪





Thank you Captain Piika for my avatar.

Thanks too Aeriixion for the cute sprite above! :) Roelof also made different variations of the sprite (which I animated).

Contact:
If you like, please contact me by private message here on the forums as I no longer check other places very often.

YouTube: http://www.youtube.com/user/ChickasaurusGL

I like to collect interesting video games. ^_^
https://www.vgcollect.com/Torchickens

Always be yourself.