Glitch City Laboratories Archives

Glitch City Laboratories closed on 1 September 2020 (announcement). This is an archived copy of a thread from Glitch City Laboratories Forums.

You can join Glitch City Research Institute to ask questions or discuss current developments.

You may also download the archive of this forum in .tar.gz, .sql.gz, or .sqlite.gz formats.

Generation III Glitch Discussion

Gen III: Access Pokémon beyond the sixth slot sub-glitches. - Page 35

Re: Gen III: Access Pokémon beyond the sixth slot sub-glitches.

Posted by: TheZZAZZGlitch
Date: 2016-05-12 17:58:06
1.a) Is it possible to make the console read code from only one word every double-word ?
Would there be a method (mainly having a certain quantity for every Code Item) to create code from PC Items in RS ?


Kind of. It's possible to write code with only x1 item quantities, because the opcode '0001' corresponds to a completely valid instruction 'lsl r0, r0, #0x4', which would have no effect if r0 is never used.
The problem would be storing data. The easy way of storing pointers/addresses in PC items would be gone. Loading any 32-bit constant would take 8 items (8 instructions - 4 8-bit loads and 4 shifts). The item count (and the amount of work to prepare the necessary items) would increase dramatically.

We should probably get consistent ACE on Emerald before trying R/S.

1.b)  Else, the only way to store code in RS that I see is with Pokémon data (8 bytes per 8 bytes).
What would the 8 bytes of code look like ? (If it doesn't bother too much to work on that)


The bytes would obviously vary depending on what we want to do. But the last two bytes would always be:

[tt]E0 26[/tt].

The instruction is "b $+0x50". It just jumps 0x50 bytes forward.
If this sequence of bytes happened to be hard to obtain, some other instructions would work as well: D3 26 (bcc $+0x50 - jumps on unset carry flag), D9 26 (bls $+0x50 - jumps on unset carry flag or set zero flag), D7 26 (bvc $+0x50 - jump on no overflow).

2) I tried your setup to execute overworld scripts, but things didn't work well.
Instead of having credits executed / an item obtained / nothing, I got a message box full of OE (RAM was overwritten by 0x101C).

For that, I used Glitch Move 0x1608 (pointer at 0x02030400), with a jump towards 0x02025E98 (03 99 5E 02 02 FF FF 08), then copied your code to use overworld scripts at 0x02025E98.
I tried it with 25 01 13 02 (special 0x113, end)), a paste of the script to get an item, 02 (end), and it always ended up with a message box and RAM being overwritten.


The code probably attempted to execute a garbage script. The script pointer in my example was hardcoded to 0x0E0F14E8 - did you remember to change that?
The underlined part should be changed to where the script is stored (it could be in ROM, in RAM, or in the save data):

[tt]78 46 09 30 86 46 03 49 01 48 08 47 F0 BD XX XX E8 14 0F 0E F9 8E 09 08 25 13 01 02[/tt]

Also, in order to work, the code has to be 4-byte aligned (it must start at an address ending with either 0, 4, 8 or C).

Re: Gen III: Access Pokémon beyond the sixth slot sub-glitches.

Posted by: Stackout
Date: 2016-05-12 19:13:31
Well, if someone ever finds a way to get past the sixth slot in battle in R/S, the memory corruption does occur there too, but for me it froze after only 26 pushes of the Up button (from Cancel). Probably something to do with having 0 Pokémon.

Re: Gen III: Access Pokémon beyond the sixth slot sub-glitches.

Posted by: Metarkrai
Date: 2016-05-13 10:12:32

Well, if someone ever finds a way to get past the sixth slot in battle in R/S, the memory corruption does occur there too, but for me it froze after only 26 pushes of the Up button (from Cancel). Probably something to do with having 0 Pokémon.


You can perform ACE in RS by altering the values that manage the hostess script at Trainer Tower.
- Enter Trainer Tower with Party Pokémon 4,5,6.
- Empty party slots 4,5,6.
- Alter the hostess script with ACE (put 0x02 at  0x020253FB)
- Enter Trainer Tower again.
The hostess will take you right back to matches with Pokémon from the party slots chosen on the previous attempt (4,5,6, who are empty).
You end up with a fully empty party, the Party Pokémon counter counts 0 Pokémon, this makes the Party Pokémon Selection pointer underflow, and you can scroll past 6th party slot.

But as Wack0 said, the game freezes after a few dozen of Up pushes, so you can't go far at all.
Furthermore, Party Pokémon are stored near 0x03004372 in RS, and I don't know any other interesting value that would be stored in 0x0300xxxx, so you can't even corrupt something interesting.
Even if there were interesting values to poentially corrupt, there would be a pretty high chance that they couldn't be corrupted because of the lack of DMA in RS.



2) I tried your setup to execute overworld scripts, but things didn't work well.
Instead of having credits executed / an item obtained / nothing, I got a message box full of OE (RAM was overwritten by 0x101C).

For that, I used Glitch Move 0x1608 (pointer at 0x02030400), with a jump towards 0x02025E98 (03 99 5E 02 02 FF FF 08), then copied your code to use overworld scripts at 0x02025E98.
I tried it with 25 01 13 02 (special 0x113, end)), a paste of the script to get an item, 02 (end), and it always ended up with a message box and RAM being overwritten.


The code probably attempted to execute a garbage script. The script pointer in my example was hardcoded to 0x0E0F14E8 - did you remember to change that?
The underlined part should be changed to where the script is stored (it could be in ROM, in RAM, or in the save data):

[tt]78 46 09 30 86 46 03 49 01 48 08 47 F0 BD XX XX E8 14 0F 0E F9 8E 09 08 25 13 01 02[/tt]

Also, in order to work, the code has to be 4-byte aligned (it must start at an address ending with either 0, 4, 8 or C).


Oh, ok, I didn't understand that part of your instructions this way.
After spending long minutes trying to understand what the "script pointer" was referring to, things worked !

With this, every small code should fit in Battle Pyramid Items, and it is possible to store the main part of the code there in order to manage the rest of the code with PC Items.
Using 00 as a null script, PC Items can be easily used to execute small script commands like special or setflags, which will be useful to make a multi-task code.


I found suitable Glitch Moves for every Emerald and FrLg version. (to execute code in PC Items or Pyramid Bag Items, except Jap Emerald Pyramid Bag)
I'll focus on RS today, as the lack of DMA could be annoying.

Regarding the method I had in mind to tell the DMA translation using Pomeg Glitch, it doesn't work as nicely as planned.
(for now, I only have like 10 different patterns for the 32 DMA translations)
I found an alternative strategy for Emerald (it uses the same idea I used to unlock Faraway and Birth Islands, but this time with Party Slot 0x47 and the 32+6 first Tms), but that strategy can't be applied to FrLg.

On FrLg (except Jap), I have 13 different patterns.
The DMA translation I want to use is the 12 double-words one, and it unfortunately shares its pattern with 3 other DMA translations (so 1/4 chance to get it right).
But since these patterns also have patterns in themselves, with different placements of the PC Pokémon in Box 2, I could obtain what I want.

I will also try to do the same thing on Emerald because I prefer doing that than the other strategy who requires the 38 first TMs (even if that strategy is still nice).

EDIT : Nope, there are no Glitch Moves that could make my initial DMA detection fully work.
This method will give a 1/4 chance to have the right DMA translation for an ACE.

EDIT 2 : I found a way thanks to in-game traded Meowth.
I added the method to that paste :  http://pastebin.com/sVHSwgSn

I'll check for the same methods in Emer Jap, FrLG Jap, FrLg (except Jap).


The bytes would obviously vary depending on what we want to do. But the last two bytes would always be:

E0 26.


0xE0 was easy but 0x26 was tougher to obtain.

A double-corrupted Horsea will have a Lonely nature (+ Atk, - Def). This gives a bonus in Coolness and a malus in Toughness.

Here is the Pokéblock recipe :
Oran + 2 NPC + Normal RPM : 10 Dry, 10 Bitter, 20 Feel  x3
Oran + 2 NPC + 7-23.3 RPM : 8 Dry, 8 Bitter, 20 Feel
Spelon + 3 NPC + 100-109.9 RPM : 51 Spicy, 12 Bitter, 32 Feel x4
Total : 4*(51+5) = 224 = 0xE0 Spicy (Coolness), 38=0x26 Dry (Beauty) 52*4 = 208 Sheen.

That jump can be coded in RS with Horsea, which is great for a large manipulation of the 6 other bytes (2 of them can have any value, and 4 others must have a sum lower than 510).

Re: Gen III: Access Pokémon beyond the sixth slot sub-glitches.

Posted by: Metarkrai
Date: 2016-05-26 06:04:44
In preparation for a video on all the possibilities of Double Corruption, and on ACE on Gen III, I made videos on little techniques that are either required or really useful to fasten the procedures.

Obtain Smeargles with various Corruption Types :
https://www.youtube.com/watch?v=-LgQJEHBHdA

Perfrming Instant Pomeg Glitch :
https://www.youtube.com/watch?v=PwYP6D1iTio

Obtaining the Caterpie Corruption Initiators :
https://www.youtube.com/watch?v=hBWkshUJv_8


Regarding ACE :
- I found a way to check for a DMA translation of 12 double-words on FrLg.
This allows ACE on FrLg (except Jap) to be conveniently performed, using Glitch Move 0x0713 (animation pointer at 0x023F0084), a Bootstrap Pokémon, and PC Items.

- For RS, Glitch Moves 0x804C and 0x8053 have an animation pointer of 0x02039360 who points to the beginning of the second substructure of a certain PC Pokémon.
As the substructure of the easiest Bootstrap Pokémon to make is the second one, these glitch moves will perfectly work with it.

One way to make a code in RS could be :
- Make a code using PC Pokémon to duplicate the first/last PC Item. (setting one of the highest bit to 1, or setting the quantity to 0).
Use this code to duplicate Glitch Items.
- Make the code you want with PC Items, and trigger it with another Bootstrap Pokémon.

This way, the limited size of manipulable Pokémon data wouldn't be that much of a bother for storing codes.


- The overworld script subroutine has different ROM adresses depending on the version.
I was able to find it for all Emer/R/S versions, but I can't find it for FrLg. (I searched for similar values in the ROM but I either had no or many results).
Does someone know the ROM adress of the overworld script subroutine in FrLg ?



  Item $203A x512
  Item $3026 x18689
  ; (the 3A and 26 in the item IDs above can be replaced to warp to a different map!)
  Item $6008 x48624
  Item $3C5A x518

The code overwrites the RAM address responsible for holding the map ID the player will be transported to after using an Escape Rope.

  Item $[byte to write]20 x18689
  Item $7008 x48624
  Item $[address, 3rd byte][address, 4th byte] x$[address, 1st byte][address, 2nd byte]

This piece of code only requires 3 items (besides the bootstrap animation bytecode), and will write any byte value to any RAM address.


Your first code requires 4 PC Items to change 2 consecutive bytes (xx yy), but it also changes the 2 consecutive bytes to 00 and requires the 00 00 xx yy double-word to be 4-byte aligned , whereas your second one requires 3 PC Items to change 1 byte.

- Would there be a shorter code to only change 2 consecutive bytes (a word) than using the "change 1 byte" code twice ? (something that would take less than 6 PC Items) (That word being 2-byte aligned.)

- And in the same line, would there be a code to change 4 consecutive bytes (a double-word) shorter than 4 times the "change 1 byte" code ? (something that would take less than 12 PC Items).
(That double-word being 4-byte aligned.)

I'm asking this because certain interesting values can't be changed with the same command you used for the Escape Rope warp location, and the 00 00 is also a hindrance for certain values that are stored contiguously.

Re: Gen III: Access Pokémon beyond the sixth slot sub-glitches.

Posted by: Stackout
Date: 2016-05-31 12:54:59
Metarkrai, if you still want to know where the FR/LG script_run() (US Emerald 0x8098EF8) is, it's at 0x8069AE4 in US FireRed; in the FireRed .idb it's named script_env_12_start_and_stuff().

Re: Gen III: Access Pokémon beyond the sixth slot sub-glitches.

Posted by: Metarkrai
Date: 2016-06-01 10:28:36

Metarkrai, if you still want to know where the FR/LG script_run() (US Emerald 0x8098EF8) is, it's at 0x8069AE4 in US FireRed; in the FireRed .idb it's named script_env_12_start_and_stuff().


Yup, I'm still working on procedures for console ACE on Gen 3, and overworld script execution can't be passed over. Many thanks for the adress !

With this, I completed the list of subroutine adresses I have.
– Script engine subroutine adresses :
Emer US : 0x08098EF9 / Emer Fr : 0x08098F09 / Emer Ita : 0x08098F0D / Emer Spa : 0x08098F0D / Emer Jap : 0x08098881
FrLg US : 0x08069AE5 / FrLg Fr : 0x08069B95 / FrLg Ita : 0x08069AC1 / FrLg Spa : 0x08069BA9 / FrLg Jap : 0x080693A5
Ruby US : 0x080655B9 / Ruby Fr : 0x080659E5 / Ruby Ita : 0x0806590B / Ruby Jap : 0x080628F9
Sapp US : 0x080655BD / Sapp Fr : 0x080659E9 / Sapp Ita : 0x08065911 / Sapp Jap : 0x080628FD



- I could execute code and overworld script on all Emerald and all FrLg (Jap or non Jap), but it didn't successfully work in RS.
The game executes the code, but softlocks right after that.

There may be an additional command that is required to end an animation for RS. Do you have any information about that ?


As of now, ACE on Emerald is ok, all the setup procedures are made.
For FrLg, I need to adapt the PC Item procedure from Emerald.
For RS, I would like to use PC Pokémon data to perform an ACE that sets the quantity of PC Item n°1 to 0x0000. This way, PC Items could be duplicated like in Emerald and FrLg.

I'm still trying to find some improvements in order to make the storage of multiple codes, and I haven't made the list of all potentially interesting codes yet, but the overall thing looks good to me.

Re: Gen III: Access Pokémon beyond the sixth slot sub-glitches.

Posted by: Stackout
Date: 2016-06-01 10:53:24
Your script_run() list is still incomplete, as in Ruby US v1.2, 0x80655B8 is in the middle of a function… (from what I see, it's at 0x80655D8 in v1.2)

Maybe setting a breakpoint on 0x8075CD0 will help with finding the softlock issue (again, Ruby US v1.2 offset). This is the handler for animation VM opcode 0x08.

Re: Gen III: Access Pokémon beyond the sixth slot sub-glitches.

Posted by: Metarkrai
Date: 2016-06-01 15:55:40

Oh damn, I didn't think that there would be changes of adresses for different versions of the same game.
I found a ROM that may be a 1.2 US Ruby (at least, the overworld script subroutine starts at 0x080655D8).
There doesn't seem to be too many important changes in glitch move animation pointers, but there seem to be some changes in glitch move names/effects.

On that ROM, I tried again two code executions (changing a word, using special 0x0113), but the game froze for one code and soft-resetted for the other code.

Here is a save file of that : http://www.petit-fichier.fr/2016/06/01/ruby-us-code-execution/ruby-us-code-execution.sav
The first party Pokémon knows Glitch Move 0x1626 , who has an animation pointer at 0x02030400.
At 0x02030400, you have : 025BCD03 0800FF02 (use the 03 for move animations, then jump to 0x02025BCC)
At 0x02025BCC you have : 30094678 49034686 47084801 0001BDF0 02025BE4 080655D9 (use the subroutine at 0x080655D9, and make it execute the code at 0x02025BE4)
At 0x02025BE4, you have : 02011325 (special 0x0113, end)

At 0x02025C0C, you also have : 0200023A 49013026 BDF06008 02025BE8 (writes 0x00003A26 at 0x02025BE8)
You can change the values at 0x02030400 to 025C0D03 0800FF03 to execute that code.

These codes are fully functional in Emerald and FrLg (modulus the change in the jump adresses).

I searched the overworld script subroutine in RS by using the values it started with on Emerald, so the subroutine may not be the good one (since the game freezes/resets before executing the scripts, I can't tell).
Even without that, the game freezes with the code that changes a double-word in RAM.

Re: Gen III: Access Pokémon beyond the sixth slot sub-glitches.

Posted by: Stackout
Date: 2016-06-01 18:54:57
I got bit by different versions having different offsets myself, so..

Thanks for the save file, I'll work on figuring out the issue when I get time.

(I got confused a bit because you posted the byte streams as arrays of 32bit little-endian integers.)

Re: Gen III: Access Pokémon beyond the sixth slot sub-glitches.

Posted by: Stackout
Date: 2016-06-03 15:18:29
Finally got time to look.

In no$gba, when the move is used, before the animation even happens (still on the move selection screen after pressing A), a jump to 0xA02004E2 happens. (tried 3 or 4 times with same result.) Obviously this move is too unstable, and can't even reach the animation part.

Re: Gen III: Access Pokémon beyond the sixth slot sub-glitches.

Posted by: Metarkrai
Date: 2016-06-04 09:35:01
Damn it, the save that was extracted from vba has glitch move 0x162C who indeed freezes the game before executing code on Ruby 1.2 US (on the other US Ruby it executes the code, but it has a long name who messes up a lot with the graphics and the move menu). Sorry, I messed up.

For Glitch Move 0x1626 (or 0x1620), you can edit the moves of the currently fighting Pokémon at 0x02024A8C.
Could you try your test again with one of these moves, please ? (I can do another save if you want)






Re: Gen III: Access Pokémon beyond the sixth slot sub-glitches.

Posted by: Stackout
Date: 2016-06-04 15:44:59
I tried with 0x1626, couldn't get the move to hit (it can hit the user or the opponent, but every time i tried attacking, the Pokémon evaded the move…)

So I tried with 0x1620, and it takes a few tries (one attempt it took 5 or so tries) but eventually the move hits and the payload executes.

After the payload finishes execution, it does some other stuff and then jumps.. back into the payload?! Anyway, this causes a return to 0x3002A460. Still figuring things out.

EDIT: ok, so if I patch the payload to contain a "bx lr" to allow it to return gracefully, it doesn't screw up.

The payload should really start with [tt]push {r0, lr}[/tt] and end with [tt]pop {r0, pc}[/tt] (instead of [tt]pop {r4-r7, pc}[/tt] which i think actually returns to the caller's caller!).

Re: Gen III: Access Pokémon beyond the sixth slot sub-glitches.

Posted by: Metarkrai
Date: 2016-06-06 11:26:27

EDIT: ok, so if I patch the payload to contain a "bx lr" to allow it to return gracefully, it doesn't screw up.

The payload should really start with [tt]push {r0, lr}[/tt] and end with [tt]pop {r0, pc}[/tt] (instead of [tt]pop {r4-r7, pc}[/tt] which i think actually returns to the caller's caller!).


That's good news !

So, how would Thezzazz's code executions change ?




Code (at $0E0F14D0):
  ; Load whatever we want to R0
  mov r0, #0x[byte to write]
  ; Load the address we want to write to
  ldr r1, [r15+0x4]
  ; Store the value of R0 to byte at R1
  strb r0, [r1]
  ; Pops registers R4 through R7 from the stack and returns.
  ; (R15 is instruction pointer)
  pop {r4-r7, r15}
  ; This is where the destination RAM address is loaded from
  dcd 0x[address, 1st byte][address, 2nd byte][address, 3rd byte][address, 4th byte]

As code :
20 [byte to write] 01 49 08 70 F0 BD [address, 4th byte] [address, 3rd byte] [address, 2nd byte] [address, 1st byte]



Code (at $E0F14D0):
  ; Previous setup to execute a subroutine
  mov r0, r15
  add r0, #0x9
  mov r14, r0
  ; Pointer to the script engine subroutine
  ldr r1, =RunScriptOffset
  ; The script engine subroutine takes the pointer to a script in R0
  ldr r0, =ScriptDataOffset
  ; Do some magic
  bx r1
  pop {r4-r7, r15}
  ; This nop is necessary because 4 byte alignment for ldr
  nop
RunScriptOffset:
  ; Pointer to the script engine subroutine
  dcd 0x08098EF9
ScriptDataOffset:
  ; Pointer to the script data
  dcd 0x0E0F14E8
The overworld script to execute (at $E0F14E8):
  ; lol credits
  special 0x0113
  end
As hexadecimal data :
78 46 09 30 86 46 03 49 01 48 08 47 F0 BD XX XX E8 14 0F 0E F9 8E 09 08[/tt]



Also, what would be the structure of a code that changes multiple RAM values before returning ?
(I'm still a non-initiated to ARM and I can't find what hexadecimal values correspond to pop {r4-r7, r15} in the code.)

Since setting up PC Items takes time (it becomes more tedious if you have to remove PC Items to write another code), codes that perform multiple useful commands at once would gain time in the writing procedure (like unlocking all islands, repop most of the legendaries, set multiple event flags, get mirage island and .., setting a swarm,…).

I'll look back into RS Glitch Moves to find ones that have a convenient Animation Pointer for RS 1.2 (and that doesn't mess up the fight), because the pointer should point towards the second substructure of a PC Pokémon for the Bootstrap code.
Else, we would need an ACE on Emerald to write the Bootstrap code on anoter area of a in-game traded Pokémon data.

Re: Gen III: Access Pokémon beyond the sixth slot sub-glitches.

Posted by: TheZZAZZGlitch
Date: 2016-06-06 12:15:03
In US Emerald, 'bx lr' does not return gracefully at all:

[img]http://i.imgur.com/LLUoUIe.png[/img]

Either the calling conventions change between versions, or I'm doing something wrong. It looks like it tried to return to a RAM address, so something's probably pushed on the stack after all.

The code to change a full 4-byte aligned dword would be this:
[tt]At $0E0F14C0 (box item 11):
  ; (same stuff as before)
At $0E0F14D0 (box item 15):
  ; This is the data to write
  ldr r0, [r15+0x8]
  ; The address where we want to store the value
  ldr r1, [r15+0x4]
  ; Store the value of R0 to dword at R1
  str r0, [r1]
  ; Return
  pop {r4-r7, r15}
  ; This is where the destination RAM address is loaded from
  dcd 0xXXXXXXXX
  ; This is where the value to write is loaded from
  dcd 0xYYYYYYYY[/tt]

Hex:
[tt]02 48 01 49 08 60 F0 BD XX XX XX XX YY YY YY YY[/tt]
The code has to be 4-byte aligned.

Also, [tt]bx lr[/tt] is [tt]70 47[/tt]

Re: Gen III: Access Pokémon beyond the sixth slot sub-glitches.

Posted by: Stackout
Date: 2016-06-06 12:30:09
I made such a payload with those changes (and same code size):

[tt]; fasmarm syntax
processor cpu32_v4t ; ARMv4t (GBA cpu)
thumb ; we don't want an ARM-mode payload
; code starts below
push {r0, lr} ; save r0, lr to stack
ldr r1, [script_run] ; r1 = ptr to script_run()
ldr r0, [script_vmip] ; r0 = ptr to script bytecode
bl _call_via_r1 ; let the CPU set up lr itself
pop {r0, pc} ; restore r0, and return

_call_via_r1:
bx r1

nop ; for alignment

script_run:
dw 0x080655D9
script_vmip:
dw 0x02025be4[/tt]

hex representation:
[tt]01 B5 03 49 03 48 00 F0 01 F8 01 BD 08 47 C0 46 D9 55 06 08 E4 5B 02 02[/tt]
(where [tt]D9 55 06 08[/tt] is the offset of script_run() as little endian and [tt]E4 5B 02 02[/tt] is where your script is)

and it seemed to work, at least it didn't call into the payload again then return back to some part of RAM; but it still essentially froze.

Some investigation later, it seems that it's getting into an infinite loop.. calling the payload…

Not sure what else to try.