Guides:Mail Writer GS (KOR)

From Glitch City Wiki
Jump to navigation Jump to search


WARNING: This portion of the guide is outdated, the contents of this guide have been merged with the main setup articles. It is only kept for legacy purposes. You can find all up-to-date guides on the TimoVM's Gen 2 ACE setups article.

This is a guide on how to execute and/or exploit a glitch. For a more technical overview of the glitch involved, see Mail writer.

The Mail writer is an arbitrary code execution program that allows the user to quickly and accurately write and execute arbitrary code payloads of up to a maximum size of 428 bytes. Payloads are written from wOtPartyCount onward, where enemy trainer's parties are usually buffered.

This guide is applicable to the Korean versions of Gold & Silver only. It is part of the TimoVM's gen 2 ACE setups set of guides.

Using the Mail writer requires an ACE setup that redirects execution to the start of box names, such as this Wrong Pocket TM ACE setup.

If you encounter any issues when going through this guide or would like to provide feedback, please contact TimoVM on the Glitch City Research Institute Discord.

How the mail writer works

Upon execution, the Mail writer will open the mail character entry screen where the player can write up to 32 different characters. After the player has confirmed the mail, the following actions take place:

  • The Mail writer will take pairs of characters and convert them into a single combined value. These values are then sequentially written, converting the 32 letter mail into a 16 byte long line of code.
  • Next, the Mail writer will display a checksum calculated from the combined value of all written bytes for the player to verify. Then the program enters a waiting state where they can either choose to write another mail, go back and correct previously written values or stop the mail writer and execute the newly written payload.
  • If the player has chosen to write a new mail, the Mail writer will open a new mail entry screen. The new mail is then also converted into a block of 16 bytes and placed right after the code written by the previous mail(s), allowing the player to write arbitrarily long payloads.

Installation

The mail writer itself will be installed in the TM/HM pocket through the following two step process:

  1. Execute a box code using Wrong Pocket TM ACE that sets the quantities of all 50 TMs to x255.
  2. Sell TMs in specific quantities so that the amount of TMs in the TM/HM pocket spell out a small mail writer program.

Afterwards, simply use TM15 to start up the mail writer whenever necessary.

Step 1: setting all TM quantities to x255

  • Rename box codes according to the image on the left. Box 9 and box 10 are not part of the setup and do not need to be overwritten. Then change box #11's name so that it matches the image on the right. Make sure to follow this exact order.
Before After


Finally, go through the following process to execute ACE:

  • Use TM15 once.

If the code was executed successfully, switch to the TM/HM pocket. It should now contain every TM at a quantity of x255.

A note on this box code

The above box code doesn't just set all TMs to x255, it also automatically alters the name of box 11 so that using TM15 will execute TM quantities from the TM/HM pocket instead. For this guide, we won't be needing to reset TM quantities to x255 after installing the mail writer.

If you do wish to reset all TM quantities, simply reset the name of box 11 in the following manner:

  • Name box 11: (space) (space) (space) 꺽
  • Overwrite box 11: (space) (space) 상

Step 2: Selling TMs to form a program in the TM/HM pocket

Now that we have obtained x255 of every TM, we'll be selling specific amounts of these in order to form a program. This program differs slightly depending on the specific language you're using. The following table displays how many TMs of each kind you need to end up with, along with the amount of money you gain by selling them.

Korean

TM Quantities to sell

TM Final amount Amount sold for
TM01 213 63000
TM02 213 42000
TM03 33 333000
TM04 217 38000
TM05 96 79500
TM06 207 72000
TM07 225 30000
TM08 209 23000
TM09 42 106500
TM10 254 1500
TM11 80 175000
TM12 40 107500
TM13 15 120000
TM14 48 310500
TM15 249 9000
TM16 42 319500
TM17 203 78000
TM18 55 200000
TM19 35 330000
TM20 174 121500
TM21 18 118500
TM22 19 354000
TM23 129 189000
TM24 79 264000
TM25 18 237000
TM26 42 319500
TM27 24 115500
TM28 236 19000
TM29 33 222000
TM30 1 381000
TM31 196 88500
TM32 77 178000
TM33 205 75000
TM34 206 24500
TM35 58 98500
TM36 27 114000
TM37 205 50000
TM38 121 134000
TM39 55 200000
TM40 240 7500
TM41 171 126000
TM42 189 99000
TM43 40 107500
TM44 212 64500
TM45 56 298500
TM46 238 25500
TM47 7 372000
TM48 208 70500
TM49 24 346500
TM50 241 14000
  • After selling TMs and verifying the amounts remaining are correct, make sure to save the game. Afterwards, use TM15 to start the mail writer.

Using the mail writer

From now on, simply use TM15 to start up the RAM writer.

The mail writer will open a screen that asks you to write the contents of a mail. This is where you'll need to enter mail codes. Once done, use the "END" option to finish the mail.

This will cause the mail writer to convert the newly written code into assembly. It will also print a checksum (sum of all written values) on the screen just to the right of the lower row. This can be used to verify if a code was entered correctly.

Due to a lack of available memory in the TM/HM pocket, it is not possible to quit the RAM writer without executing the newly written code. If you ever accidentally activate the mail writer and would like to quit, simply write a mail containing "ㅍㅊ" then confirm and exit the RAM writer.

Assembly can easily be converted to mail codes using TimoVM's MailConverter. Simply paste the assembly of the code you wish to enter here, press "run" and the converter will automatically generate mail codes requiring the least amount of button presses to write.

Controls

Between entering mail codes, the mail writer will ask for user input.

  • Press SELECT to open a new mail and continue writing data.
  • Press START to immediately jump to and start executing the newly written program. Only use this when you've finished every mail.
  • Press any other button to go back one byte at a time to correct errors. If the printed checksum doesn't match the expected checksum, press DOWN 16 times to retry the last mail. This will also overwrite the printed checksum with the value at the currently selected address, giving you a method to check how far back you're going.
Enter your mail code, then press "END". It prints the checksum and waits for input.

What to do with the Mail writer

The Mail writer allows you to easily write and execute arbitrary payloads. Aside from writing your own codes, we recommend the following:

  • Mail codes: this page contains a collection of assembly for mail codes that can be used for a variety of common purposes such as editing pokémon, obtaining items, etc..
  • RAM writer: (recommended for more experienced users) this page contains the assembly for a large one-size-fits all program that allows you to edit any value in RAM with a user-friendly GUI. It will also fix the side effects of the ACE setup when you first run it.

Addendum: repairing box 11's name

In case something happens with box 11's name that causes it to no longer function, you can repair the name without having to reset TM quantities using the following procedure:

  • Rename box codes according to the image on the left. Box 6 through box 10 are not part of the setup and do not need to be overwritten. Then change box #11's name so that it matches the image on the right. Make sure to follow this exact order.
Before After


Finally, go through the following process to execute ACE:

  • Use TM15 once.
  • If the code executes succesfully, box 11's name has now been repaired.

Appendix: in-depth explanation of the setup

Effect of the setup box name code

Converting the characters from box names to assembly results in the following code. Please note that the box name code overwrites part of itself, the translated assembly assumes the code was already used once.

The code overwrites part of itself to call the byteFill function. This will fill the area between $D57E and $D5AF with $FF values, setting all 50 TM quantities to 255.

Separately, this code overwrites the latter half of party pokémon #5's stat experience data, allowing it to function as a TM25 bootstrap that redirects execution to the Mail Writer.

Box 1: $D952
04		inc b
21 08 DA	ld hl, DA08	; Middle of box #11's name
04		inc b
AF		xor a		; a = $00
01 31 01	ld bc, $0131
A9		xor a, c	; a = $31
03		inc bc
32		ldd (hl), a
01 C5 01	ld bc, $01C5
A9		xor a, c	; a = $F4
50		inc d, b

Box 2: $D963
03		inc bc
32		ldd (hl), a
01 37 01	ld bc, $0137
A9		xor a, c	; a = $C3
03		inc bc
32		ldd (hl), a
01 15 01	ld bc, $0115
A9		xor a, c	; a = $D6
03		inc bc
32		ldd (hl), a
01 E7 50	ld bc, $50E7

Box 3: $D974
04		inc b
A9		xor a, c	; a = $31
03		inc bc
32		ldd (hl), a
01 10 01	ld bc, $0110
A9		xor a, c	; a = $21
03		inc bc
32		ldd (hl), a
01 DE 01	ld bc, $01DE
A9		xor a, c	; a = $FF
03		inc bc
32		ldd (hl), a
50		inc d, b

Box 4: $D985
01 09 01	ld bc, $0109
A9		xor a, c	; a = $F6
03		inc bc
32		ldd (hl), a
01 32 01	ld bc, $0132
E5		push hl
05		dec b
CD 01 DA	call .byteFill
04		inc b
E1		pop hl		; continue writing to box #11's name 
50		inc d, b

Box 5: $D996
01 AF 01	ld bc, $01AF
A9		xor a, c	; a = $50
03		inc bc
22		ldi (hl), a
01 6E 01	ld bc, $016E
A9		xor a, c	; a = $3E
03		inc bc
22		ldi (hl), a
01 3A 01	ld bc, $013A
A9		xor a, c	; a = $04
50		inc d, b

Box 6: $D9A7
03		inc bc
22		ldi (hl), a
01 15 01	ld bc, $0115
A9		xor a, c	; a = $11
03		inc bc
22		ldi (hl), a
01 43 01	ld bc, $0143
A9		xor a, c	; a = $52
03		inc bc
22		ldi (hl), a
01 8C 50	ld bc, $508C

Box 7: $D9B8
04		inc b
A9		xor a, c	; a = $DE
03		inc bc
22		ldi (hl), a
01 0B 01	ld bc, $010B
A9		xor a, c	; a = $D5
03		inc bc
22		ldi (hl), a
01 16 01	ld bc, $0116
A9		xor a, c	; a = $C3
03		inc bc
22		ldi (hl), a
50		inc d, b

Box 8: $D9C9
01 F2 01	ld bc, $01F2
A9		xor a, c	; a = $31
03		inc bc
22		ldi (hl), a
01 E7 01	ld bc, $01E7
A9		xor a, c	; a = $D6
03		inc bc
22		ldi (hl), a
05		dec b
C9		ret

Box 11 before first execution: $D9FC
0B FF 0B FF 05			; filler
C3 50 D9	jp wBoxNames - 2; .entryPoint, renaming the box placed a $50 at $DA02

Box 11 during first execution: $D9FC
0B FF 0B FF 05			; Filler
F6 FF		or $FF		; .byteFill, a = $FF
21 31 D6	ld hl, wTMsHMs
C3 F4 31	jp byteFill	; Due to prior code, bc = $0032

Box 11 after first execution: $D9FC
0B FF 0B FF			; Filler
50		ld d, b		; Terminator $50 makes the rest of the box code invisible to the player
3E 04	ld a, $04		; .entryPoint, a = $04
11 52 DE	ld de, $DE52	; Code written by the Mail Writer starts from here
D5		push de		; When closing the Mail Writer, return to $DE52 to execute the newly written code
C3 31 D6	jp wTmsHMs	; Execute mail writer

Box 12: $DA0D
0B FF				; Filler
05		dec b		; Entrypoint of TM15, two preceding bytes are filler
C3 01 DA

Effect of the TM code

Converting the TM quantities to assembly results in the following code. Please note that this code requires a value of $04 in register a, a value of $DE52 in registers de and the value $DE52 pushed on the stack in order to properly work.

D5		push de		; .nextMail
D5		push de
21 D9 60	ld hl, _ComposeMailMessage
CF		rst08h, FarCall a:hl
E1		pop hl
D1		pop de
2A		ldi a, (hl)	; .continue
FE 50		cp $50	; If terminator, break loop. if newline, skip and get new character.
28 0F		jr z, .terminator
30 F9		jr nc, .continue
2A		ldi a, (hl)	; Since Korean text takes up two bytes per character, get the second byte
CB 37		swap a	; swap high and low nibbles of a
23		inc hl	; Skip first byte of second character
AE		xor a, (hl)
12		ld (de), a
13		inc de
81		add a, c	; Update checksum and store the result in c
4F		ld c, a
12		ld (de), a
2A		ldi a, (hl)
18 EC		jr .continue
21 01 C4	ld hl, $C401	; .screenLoop
4D		ld c, l
CD CE 3A	call PrintBCDNumber.loop - 1 ; inc hl by 3, inc de, display byte at address de
1B		dec de		; .goBack, compenstate inc de of PrintBCDNumber.loop
CD 79 37	call JoyTextDelay_ForcehJoyDown	; Wait until end of frame, then store button state in hJoyLast
F0 AB		ld a, (hJoyLast)
BD		cp a, l		; l = $04
28 D4		jr z, .nextMail
38 EE		jr c, .displayLoop
07		rlca
D0		ret nc
18 F1		jr .goBack

Effect of the reset box name code

Converting the characters from box names to assembly results in the following code. This code overwrites box #11's name, allowing it to function as a TM15 bootstrap that redirects execution to the Mail Writer.

Box 1: $D952
04		inc b
21 01 DA	ld hl, $DA01
04		inc b
AF		xor a		; a = $00
04		inc b
2B		dec hl
01 B0 01	ld bc, $01B0
91		sub a, c	; a = $50
03		inc bc
22		ldi (hl), a
01 6E 50	ld bc, $506E

Box 2:
04		inc b
A9		xor a, c	; a = $3E
03		inc bc
22		ldi (hl), a
01 3A 01	ld bc, $013A
A9		xor a, c	; a = $04
03		inc bc
22		ldi (hl), a
01 15 01	ld bc, $0115
A9		xor a, c	; a = $11
03		inc bc
22		ldi (hl), a
50		ld d, b

Box 3:
01 43 01
A9		xor a, c	; a = $52
03		inc bc
22		ldi (hl), a
01 8C 01	ld bc, $018C
A9		xor a, c	; a = $DE
03		inc bc
22		ldi (hl), a
01 0B 01	ld bc, $010B
A9		xor a, c	; a = $D5
50		ld d, b

Box 4:
03		inc bc
22		ldi (hl), a
01 16 01	ld bc, $0116
A9		xor a, c	; a = $C3
03		inc bc
22		ldi (hl), a
01 F2 01	ld bc, $01F2
A9		xor a, c	; a = $31
03		inc bc
22		ldi (hl), a
01 E7 50	ld bc, $50E7

Box 5:
04		inc b
A9		xor a, c	; a = $D6
03		inc bc
22		ldi (hl), a
05		dec b
C9		ret

Box 11 before first execution: $D9FC
0B FF 0B FF 05			; filler
C3 50 D9	jp wBoxNames - 2; .entryPoint, renaming the box placed a $50 at $DA02

Box 11 after first execution: $D9FC
0B FF 0B FF			; Filler
50		ld d, b		; Terminator $50 makes the rest of the box code invisible to the player
3E 04	ld a, $04		; .entryPoint, a = $04
11 52 DE	ld de, $DE52	; Code written by the Mail Writer starts from here
D5		push de		; When closing the Mail Writer, return to $DE52 to execute the newly written code
C3 31 D6	jp wTmsHMs	; Execute mail writer

Box 12: $DA0D
0B FF				; Filler
05		dec b		; Entrypoint of TM15, two preceding bytes are filler
C3 01 DA

Plain text transcripts for codes

  • Rename box codes according to the following names:
Box 1: 묻 붰 성 닥 갑 근 성 꺾
Box 2: 꺌 근 성 랴 같 근 성 박
Box 3: 껭 근 성 섈 갠 근 성 앰
Box 4: 겜 근 성 젬 깝 근 성 쵭
Box 5: 겊 긋 생 꺾 깐 근 성 꺾
Box 6: 겠 근 성 닥 깠 근 성 랴
Box 7: 샘

Box 12: (space) 상 꺾
  • Next, name box 11: (space) (space) (space) 꺽
  • Finally, overwrite box 11: (space) (space) 상