Show Posts

This section allows you to view all posts made by this member. Note that you can only see posts made in areas you currently have access to.

Topics - Wack0

Pages: [1] 2 3 ... 5
Pokémon Discussion / Crystal: Unused party sanitisation function
« on: October 03, 2017, 10:37:50 am »
I was looking in pokecrystal for something unrelated and this caught my eye.

As the filename would have you expect, it's in EN Crystal at $13A47 (4:7A47). (It's in JP Crystal at $13BB3 (4:7BB3)). That's near the end of the bank, located after some Bug-Catching Contest-related stuff, and before a function that uses a lookup table to find square roots. It appears to not be in G/S (and given that it calls a function in a bank related to mobile code, that's not unexpected).

It is completely unreferenced and unused in at least JP and EN Crystal.

Here's what it does:

  • If the number of Pokémon in the party is over 6, set it to 6
  • The party species bytes are checked. If a byte is an invalid species ($00, $FC, $FE, $FF), change that species byte and the first species byte of that Pokémon structure to Smeargle ($EB).
  • For all Pokémon in the party:
    • If the second species byte in the Pokémon structure is invalid ($FD (Egg) is also considered invalid here), change it to Smeargle.
    • If the Pokémon's level is below 2, set it to 2; if it is over 100, set it to 100. Recalculate the Pokémon's stats, no matter whether or not the level was modified.
    • If the Pokémon's nickname is unterminated after 6 bytes, terminate it by setting the 6th byte to $50; if the nickname has any invalid characters (defined here as anything that is not $00, $05 - $13, $19 - $1C, $26 - $34, $3A - $3E, $40 - $48, $60 - $FF; a function in a bank related to mobile functionality is called to do this), set it to the Pokémon species name (if the Pokémon is an Egg, then set it to "タマゴ" ("Tamago"/Egg) followed by 50 50 50 instead)
    • If the Pokémon's Original Trainer name is unterminated after 6 bytes, terminate it by setting the 6th byte to $50; if it has any invalid characters, set it to the player's name
    • If the Pokémon has an invalid move in slot 1 ($00, $FC, $FD, $FE, $FF), replace it with Pound. If there is an invalid move in slot 2, 3, or 4, delete all moves starting from that slot(!!!).

Note that this code is only half localised in non-JP - it assumes nicknames and OT names are 6 bytes long, the list of characters considered valid assumes a Japanese game, and if an Egg's nickname contains invalid characters, it gets set to "タマゴ"; however, when removing a Pokémon's nickname, or changing its OT name, it copies the correct number of bytes for the localisation.

Given that this calls a function in a mobile-related bank, this function may have been intended to have been used to force the legitimacy of party Pokémon when using mobile-related features. Of course, it may have just been debug code.
Generation I Glitch Discussion / Cause of Special Menu Select glitches (JP)
« on: September 01, 2017, 08:19:45 pm »
Couldn't get to sleep, so why not look into the cause of a glitch that hasn't been documented very well?
I used luckytyphlosion's pokered-jp disassembly (a fork of pokered that aims to be a disasm of JP R/G) to help me.

This glitch is caused entirely by the HandleItemListSwapping function. As you can probably see by the helpful comments, the direct cause is the wrong conditional jump was used, and the jump back to the item menu loop happens when carry flag is set, instead of when zero flag is not.

The function can only handle item swapping, and special item lists are just lists of item indices, without quantities.
So, swapping items 1 and 2 cause items 1 and 2 to be swapped with 3 and 4, as items 1 and 2 are interpreted as item+quantity of item 1, and items 3 and 4 as item+quantity of item 2.

Going by the sets of swaps in the wiki article, the last swap swaps items 7 and 8, that is, bytes 14-15 and 16-17. These bytes are located after the FF array terminator. The buffer in WRAM where the item list is located is in fact only 16 bytes long (and the first byte is the list quantity). Directly after this buffer is a pointer to the item list itself, so this pointer is swapped with some undefined data beyond the list terminator but still within the buffer.

I have not yet determined why this causes corruptions to other parts of memory.
Generation III Glitch Discussion / Gen III Remote Code Execution
« on: February 18, 2017, 07:58:35 pm »
TL;DR: with a Wii or GameCube where you can run homebrew (obviously easier with a Wii), and a GBA->GC link cable, you can abuse the functionality officially used by Pokémon Colosseum/XD/a bunch of Berry Glitch fixdiscs to get code exec in the context of Gen III.
(of course, you could also use the GBA BIOS multiboot, but here you don't have to press any buttons on the GBA BIOS to get multiboot going! And because this is in the Gen III ROM, this can legitimately be called Gen III RCE :P)

What is this?
Have you ever connected up Pokémon Colosseum/XD to your Gen III game? Remember how it told you to turn the GBA on with the GBA->GC link cable plugged in, then it took an awfully long time on the copyright screen and then showed some Colosseum/XD thing?
The awfully long time on the copyright screen was Colosseum/XD transferring a multiboot image (basically a GBA ROM image with modifications, namely it runs from RAM lol) to your GBA. The Colosseum/XD thing on the GBA was basically your GBA executing that multiboot image.
After two days of reversing (this multiboot protocol is pretty different to the one used by the BIOS, but it does have a couple of similarities), I got a respectable PoC working. So, where else to release this to the world?

Here's an image of, basically, the very PoC I'm releasing today. The payload only supports an English Pokémon Ruby, version 1.0, 1.1 or 1.2 (because that's the only of my Gen III carts I could find; I didn't know what version it was; and the GC/Wii-side application doesn't work inside Dolphin); The payload now supports every Generation III game, except Pokémon LeafGreen v1.1 (Japan) due to it being undumped; it calls the game's save-loading function, replaces the first character of the player name with 'z', then returns to the game (by calling the game's main loop as a function, because just returning would reload the save and overwrite the change made).

Where's the code?
Right here:

If you want to modify the GBA-side payload, you can naturally find it in the gba directory. Note that the payload is in the C language. A refreshing change of pace from position-independent ASM shellcode, I'm sure you'll agree.

To compile this, you'll need devkitPro (devkitARM for the GBA side and devkitPPC for the GC/Wii side). Remember, this is very much a proof of concept which I'm sure will be improved on by others.

How do I run it after compiling?

I assume you have a Wii (I'm not even going to mention GameCube, I think all the good ways to get homebrew running there need a Wii anyway lol), with the Homebrew Channel installed and running. Just execute the compiled gen3multiboot_wii.dol there. When testing, I always used wiiload, it being quicker than copying a new binary to the SD card every time.

Make sure you have a GameCube controller plugged into controller port 1 and your GC->GBA link cable plugged into port 2.

Hey, it didn't work. What gives?

Code execution on the GBA side is not 100% reliable for some reason. A couple of different things could go wrong. If you see an error about KeyC derivation, you should just be able to turn your GBA off, press any button on your GameCube controller plugged into port 1, then turn your GBA back on again.

If, however, your GBA didn't seem to notice the code being transferred to it, and your Wii has frozen on a line with a CRC, you're going to need to power off both GBA and Wii, turn your Wii back on, get back into the Homebrew Channel and run gen3multiboot_wii.dol again.

It may take a few tries but it will eventually work.

What is this "different" protocol?

If you want technical details, best see the source code.
At a higher level, it goes like this:

  • GBA game starts, game calls the multiboot main() function
  • GC sends a reset command, GBA sends a game code
  • GC receives game code, maybe checks to see if it's supported, and sends it back to GBA
  • GBA checks this, if it's wrong then GBA stops listening on the JoyBus link cable
  • GC generates and sends the first of three 32-bit encryption keys. This is officially (yay for debug messages!) called "KeyA" (imaginative). GBA checks one of the bytes to make sure it's valid, then generates and sends its own encryption key, "KeyB".
  • KeyA and KeyB are XORed together to form the initial value of the checksum (algorithm used is the same as the GBA BIOS multiboot). This value is also obfuscated to form a session key that will be used to encrypt most of the multiboot image when it is sent (again, algorithm used is the same as GBA BIOS)
  • GC sends the size of the multiboot image it's about to send, in uint32s, to GBA. GC then sends the ROM header (up to 0xA0, the end of the Nintendo logo) to GBA in the clear. When this is done, GBA checks the received Nintendo logo to make sure it's the same as the Nintendo logo in the ROM of the cartridge it's executing. If not, GBA stops listening on the JoyBus link cable.
  • GC sends the rest of the multiboot image to the GBA. Each uint32 is encrypted using the session key, which is also incremented in the same way as the GBA BIOS multiboot. Each plaintext uint32 is also checksummed, using the existing checksum as the initial value, again the algorithm used here is the same as the GBA BIOS multiboot.
  • GBA, as it's receiving the image, decrypts it, and checksums the plaintext in the same way. After this is done, the GBA will send GC a value that can be used with the correct multiboot image checksum to derive KeyC, which was created by GBA using some historical value of its VCount register.
  • GC receives this value, and attempts to derive KeyC. It will use the derived KeyC to create a "boot key" which is sent to GBA; if this boot key is the same as the one the GBA already created, it will call the entry point of the sent multiboot image. If not, GBA will stop listening on the JoyBus link cable.

This took me quite some time of reversing work to figure out (there was lots of info about the GBA BIOS multiboot protocol on the internet; only ARM ASM code about this one, from the Pokémon reverse engineering project). I hope it helps someone.
Generation VII Glitch Discussion / Gen VII invalid Pokémon / etc research
« on: December 09, 2016, 11:06:29 am »
Finally got that modded PKHeX compiled. Find it here - mirrors would be appreciated.

Expect lots and lots of lag, this has support for Pokémon/items/attacks up to 0xffff.

I took a Pokémon in my box, made a copy of it, changed its species to 0xffff, gave it move 0xffff, shoved it in the PC.

When hovering over it in the PC I got a nice crash, a null pointer deref related to the attack name (Luma's exception dump showed r0 to r4 all being zero, and pc pointed at ldr r1, [r4, #0x84]).

Changed the attack 0xffff to something valid (Flamethrower), and now I can hover over it in the PC! It looks like Kirlia; and viewing its summary crashes in the exact same place as before.

0xffff's species name is not constant. I think it's based on the level number of the Pokémon you previously selected or something. (it changed from "70" to "64", then hovering over it inside the PC when the Pokémon was in the party caused a crash)

OK, that's interesting. Put 0xffff in the party, went  back out of the PC, went back into the PC, touched 0xffff (to avoid a crash), and it now looks like Staravia.

he forced a mystery gift retrieval when there was nothing waiting and got a Bad Egg named after himself.
Pokémon Discussion / R/B/Y VC, and butthurt morons on miiverse
« on: October 25, 2016, 06:42:18 pm »
So I hopped onto miiverse for the first time in a while and looked through the Gen1VC community.

I noticed at least one person spreading rumours that "you'll never be able to send your fake Mew to Sun/Moon" on posts showing a wild Mew encounter or capture using Trainer-Fly.

Of course this is pure speculation at this point, we won't know for sure what Gen1VC transfer stuff will be accepted until Gen7's release.

I can only assume the people spreading these rumours never managed to do Trainer-Fly successfully, and are taking out their anger on others.

This page showed up in my Twitter feed today. I thought some people here may find it interesting.

Some of the art made for the incompatibility messages happens to be rather enjoyable.

I wonder why the incompatibilty message for the German version of Monsters Inc (GBC) got inverted when compared to the English version.

I also note similar fonts used in some of the messages; could these be tied together by a common dev? (the one I noticed specifically was the one used by Micromachines V3, Championship Motocross, and other GBC games; as it's also used in the copyright messages of the first Harry Potter game for GBA, which I have a cart of.)
Forum Discussion / Forum links broken?
« on: August 12, 2016, 05:51:29 pm »
Seems the recent maintenance changed the forum URL format and broke all external links to topics, posts etc?
Pokémon Discussion / I figured out the cause of my dead Red cart.
« on: August 10, 2016, 04:12:57 am »
Turns out the bank switcher is screwed, and only the first 512kb of the ROM can be accessed.

Other carts (Red and Blue) have developed the same issue over time.

Have fun screwing about with it in an emulator, just cut a Red or Blue ROM down to the first 512kb!

The article details code exec in Gen 1 via save corruption, and utilising that to escape the SGB to get full code exec on the SNES.

As is the style of PoC||GTFO, the pdf is also valid as a zip file (which includes a copy of the pokered disassembly), and as an LSNES movie which does that.
Video Game Glitches Discussion / The Simpsons Hit and Run
« on: December 18, 2015, 11:59:31 am »
I saw this video

I think a topic discussing some of these things would be interesting.

I've done a little experimentation and I got the no vehicles glitch to work by going into a race, canceling it then immediately selecting a mission. I noticed it does not work at all in certain types of missions, as in those that require you to interact some way with a vehicle (follow, hit and collect, destroy etc).

Next up, void fun. I haven't yet consistently managed to get into the void from that spot in Level 7, I think practise is needed. However the guy who made the video forgot about that you can press a button to respawn your car (Back on Xbox, not sure about other platforms). I reproduced getting to Kang and Kodos' spaceship through the void, but hitting the Back button after hitting the invisible wall respawned my car on the other side of the wall, and driving into the spaceship destroyed my car as usual! I still think horn-to-jump is the easiest way to get into the void though.

EDIT: I just successfully completed L7M3 going exclusively through the void, using horn to jump to get in. I had ~45 seconds left on the clock on completion (as a reminder, in L7M3 you have 1:40 to travel the entire length of the map (power plant to school playground).
Generation VI Glitch Discussion / Invalid Pokémon in Gen 6
« on: January 30, 2015, 02:25:02 pm »
So, thanks to the 9.x browser exploit, we're now in a position to research Gen 6.

I patched PKHex to allow for invalid moves, items and Pokémon. Above a certain point, when selecting an invalid Pokémon from the list, it will throw an exception, but you can just click continue and it'll work fine.

First thing to note is that invalid Pokémon (in Omega Ruby at least) seems to use Bulbasaur's sprite/texture, and have Normal type. I'm not sure how it gets the cry, one of them has Deoxys' cry. They do not learn any moves, and cannot be taught any TMs or HMs.

I first used some invalid Pokémon close to the last valid one, that don't error out, and got unremarkable Pokémon with bad stats. (14 Speed after Rare Candying to Level 100!)

I then tried 0x82B1, and it's pretty unstable, as I assume most will be. I had to use Withdraw Pokémon, withdraw 0x82B1 then press B straight away to avoid a freeze. I tried to use a Rare Candy on it and the game froze, probably trying to recalculate stats. It has no cry, and Pokédex number ?55 (convert 0x82B1 to decimal to see why that is!)

No screenshots yet, (I'm obviously doing this on real hardware and I don't have any decent way to take them) but the glitch Pokémon I tried (not 0x82B1 yet!) worked fine in battles and in contests. As said by someone else, species names seem to be dynamic. Sometimes they are blank, in summary screens it's their dex number and so on.

When I get home, I'll provide a download link to the modded PkHex. That is if Torchickens hasn't uploaded it (I already gave it to him). It's a .NET exe so you *should* be able to run it on non-Windows platforms using mono.

Apologies for any typos, etc in this post, I made it on my Android tablet.
Otherwise known as: Adventures of my Glitchy Ruby Save File, Part (TM)34.

If you don't know, I used cheats on a brand new Ruby save file. This gives me access to 255 Pokémon. I also cheated the Retire option to warp to the Safari Zone. Current location: Lilycove City.

Enough of that, here's why I made this topic.

As you should know, some glitch moves corrupt RAM when their names are displayed. The 18th Pokémon from the bottom on my Ruby save contains three stable-enough glitch moves. One or more of them corrupt my Berry pocket, giving me two different glitch berries, quantity 12369.

I had the bright idea to check the tags. The first one causes a freeze. The second, however...

Well, it shows a glitched tag. Either a discoloured Cheri Berry tag with a glitch sprite, or a discoloured blank tag with a glitch sprite. Anyway, the fun begins when you go back to your bag.

This unknown glitch berry tag corrupts a lot of RAM. All items pockets got corrupted (TM34 was in every pocket, working as usual). On at least one occasion I got Doubleslap as an HM (HM 7920 in case you are wondering). Use one of the many, many ???????? items you have, and watch as Dad's message gives way to an insanely long corrupted name, that I let scroll by for five minutes before deciding enough was enough and resetting already. Using one of your TMs (choose a pocket, any pocket!) shows your party isn't corrupted, but even your gender got corrupted (I was Brendan, but the Bag's blue pattern changed to red). Unfortunately, the whole truth you never get to see. Exit your Bag to get a freeze. Maybe due to the insanely long name. I don't know.

Now then, who wants to hack the Pokémon and Retire options onto a brand new Ruby save and do this for yourself, as real hardware means I have absolutely no idea what the index number of this glitch berry is.

Or, by the way TM34s showed up in my berry pocket, maybe it's some kind of side-effect of a non-berry in the berry pocket? It could be a bog standard ???????? item for all I know.
Generation VI Glitch Discussion / ORAS Surfing Wailmer evolve freeze
« on: December 02, 2014, 08:32:29 am »
Found this thread on reddit:

Will quote the contents just in case the post gets deleted.

Wailmer, as we all know, has a special surf sprite. If you let it evolve while you are surfing on it, your game crashes and both screens go black.

Can anyone confirm?
Remember Newo's old extended hacker? Well, screw that. It was always buggy, probably because I don't think Newo actually had the source code.

I've taken karatekid552's Gen 3 hacking suite (that's coded in python for proper multiplatform support), and added support for invalid pokemon, and everything that goes with that.

The only known bug is that the moves tab on glitch Pokémon (probably) isn't right; and obviously, don't even TRY to edit data about an invalid pokemon!

The Egg Moves tab also doesn't work with invalid Pokémon... but seeing as most decamarks freeze on hatch anyway...

Please note that it will take a few minutes to load a ROM with this tool...


Win32 (self-contained exe):
Python 2 code (for running on other platforms - needs Python Imaging Library and wxPython2.8):
Pages: [1] 2 3 ... 5