The PokéCommunity Forums  

Go Back   The PokéCommunity Forums > Creative Discussions > Emulation & ROM Hacking > Research & Development
Register New Account FAQ/Rules Chat Blogs Mark Forums Read

Notices

Research & Development Got a well-founded knack with ROM hacking? Love reverse-engineering the Pokémon games? Or perhaps you love your assembly language. This is the spot for polling and gathering your ideas, and then implementing them! Share your hypothesis, get ideas from others, and collaborate to create!
New threads in this forum are to be approved by a moderator before they are displayed. The thread revival limit does not apply here.



Reply
Thread Tools
  #1  
Unread May 1st, 2010, 02:35 PM
HackMew's Avatar
HackMew
Mewtwo Strikes Back
 
Join Date: Jun 2006

Brief Intro


As probably most of you are aware of already, Emerald has a faulty PRNG implementation. The game does not take care of reseeding during the startup, leading to the fact it can be easily abused to get perfect IVs and similar.

Description


While it can be useful, it's indeed a major glitch. Since the whole game randomness is affected, it definitely needs to be fixed. Taking a look at Ruby's code, I found out that the initial reseeding happens as soon as the game starts (i.e. when the boot screen shows up). R/S use their internal clook to generate a 16-bit seed. In Emerald, of course, this part is totally missing. So I decided to emulate the R/S approach by porting their reseeding routine to Emerald. Here's the outcome:

Code:
.text .align 2 .thumb .thumb_func .global EmeraldPrngFix main: push {lr} ldr r1, .GET_CLOCK bl bx_r1 lsr r1, r0, #0x10 lsl r0, r0, #0x10 lsr r0, r0, #0x10 eor r0, r1 ldr r1, .UPDATE_SEED bl bx_r1 ldr r0, .UNK_RAM1 mov r4, #0x0 strb r4, [r0, #0x0] pop {pc} bx_r1: bx r1 .align 2 .UNK_RAM1: .word 0x03002700 .GET_CLOCK: .word 0x0802F664|1 .UPDATE_SEED: .word 0x0806F5F8|1
In order to apply the fix, assemble the routine and insert it somewhere where there's enough free space (if you never done it before, you better check my ASM tutorials). Take note of the address you used, and then replace 02 24 04 70 with FE 46 00 47, and 00 27 00 03 with XX XX XX XX, where XX XX XX XX represents the pointer to the routine's address + 1. For the respective offsets, see below.

The Offsets


  • Emerald US v1.0

    Code:
    0x402 0x478

This research document is Copyright © 2010 by HackMew.
You are not allowed to copy, modify or distribute it without permission.
__________________
Reply With Quote
  #2  
Unread December 20th, 2011, 07:35 AM
ArmoredGuns
Beginning Trainer
 
Join Date: Jan 2010
Can someone please make an IPS patch of this fix? It seems pretty important, and it seems it requires more than just hex editing... I would love to have this fix but I'm no programmer
Reply With Quote
  #3  
Unread December 22nd, 2011, 03:38 AM
agentgeo's Avatar
agentgeo
うにゅ?
 
Join Date: Mar 2010
Age: 16
Gender: Male
Nature: Serious
Quote:
Originally Posted by ArmoredGuns View Post
Can someone please make an IPS patch of this fix? It seems pretty important, and it seems it requires more than just hex editing... I would love to have this fix but I'm no programmer
Okay, here you go... However, I really recommend you learn to apply simple hacks like this.
Download.
*Note: Routine inserted at 0x9C0D00*
__________________

Yay! My two hacking projects!
Oh, what fun!
Reply With Quote
  #4  
Unread December 23rd, 2011, 08:19 AM
Bond697
Unhatched Egg
 
Join Date: Oct 2008
Gender:
just FYI, the code to seed emerald's prng actually does exist in the game. all you would need to do is branch to this(and maybe turn on timer1 if it's not already, but that's easy) at some point and you're set. it was going to work exactly like fire red and leaf green.

it's just never used:


Code:
ROM:08000560             @ =============== S U B R O U T I N E =======================================
ROM:08000560
ROM:08000560
ROM:08000560             @ void __fastcall seedRNG__()
ROM:08000560             seedRNG__:
ROM:08000560 10 B5                       PUSH    {R4,LR}         @ this function never runs
ROM:08000562 06 48                       LDR     R0, =0x4000104  @ Timer1Data
ROM:08000564 04 88                       LDRH    R4, [R0]
ROM:08000566 20 1C                       MOVS    R0, R4          @ Timer1Data to r0
ROM:08000568 6F F0 46 F8                 BL      setRNG__        @ set rng state (0x3005D80) to result of timer1
ROM:0800056C 04 49                       LDR     R1, =0x4000106  @ T1CNT
ROM:0800056E 00 20                       MOVS    R0, #0
ROM:08000570 08 80                       STRH    R0, [R1]        @ turn off timer1
ROM:08000572 04 48                       LDR     R0, =0x2020000
ROM:08000574 04 80                       STRH    R4, [R0]        @ store the result of timer1 to 0x2020000
ROM:08000576 10 BC                       POP     {R4}
ROM:08000578 01 BC                       POP     {R0}
ROM:0800057A 00 47                       BX      R0
ROM:0800057A             @ End of function seedRNG__
ROM:0800057A
ROM:0800057A             @ ---------------------------------------------------------------------------
ROM:0800057C 04 01 00 04 dword_800057C:  .long 0x4000104         @ DATA XREF: seedRNG__+2r
ROM:08000580 06 01 00 04 dword_8000580:  .long 0x4000106         @ DATA XREF: seedRNG__+Cr
ROM:08000584 00 00 02 02 dword_8000584:  .long 0x2020000         @ DATA XREF: seedRNG__+12r
Code:
 
ROM:0806F5F8             @ =============== S U B R O U T I N E =======================================
ROM:0806F5F8
ROM:0806F5F8
ROM:0806F5F8             @ void __fastcall setRNG__(unsigned short T1Dat)
ROM:0806F5F8             setRNG__:                               @ CODE XREF: seedRNG__+8p
ROM:0806F5F8 00 04                       LSLS    R0, R0, #0x10   @ dumb typecasting
ROM:0806F5FA 00 0C                       LSRS    R0, R0, #0x10
ROM:0806F5FC 02 49                       LDR     R1, =0x3005D80  @ rng buffer
ROM:0806F5FE 08 60                       STR     R0, [R1]        @ set rng to T1Dat
ROM:0806F600 02 49                       LDR     R1, =0x20249BC  @ rng frame counter
ROM:0806F602 00 20                       MOVS    R0, #0          @ set counter to 0 to signify starting seed
ROM:0806F604 08 70                       STRB    R0, [R1]
ROM:0806F606 70 47                       BX      LR
ROM:0806F606             @ End of function setRNG__
Reply With Quote
  #5  
Unread December 23rd, 2011, 09:42 AM
ArmoredGuns
Beginning Trainer
 
Join Date: Jan 2010
Quote:
Originally Posted by agentgeo View Post


Okay, here you go... However, I really recommend you learn to apply simple hacks like this.

*Note: Routine inserted at 0x9C0D00*
Thank you very much!!! I greatly appreciate it

Quote:
Originally Posted by Bond697 View Post
just FYI, the code to seed emerald's prng actually does exist in the game. all you would need to do is branch to this(and maybe turn on timer1 if it's not already, but that's easy) at some point and you're set. it was going to work exactly like fire red and leaf green.

it's just never used:


Code:
ROM:08000560             @ =============== S U B R O U T I N E =======================================
ROM:08000560
ROM:08000560
ROM:08000560             @ void __fastcall seedRNG__()
ROM:08000560             seedRNG__:
ROM:08000560 10 B5                       PUSH    {R4,LR}         @ this function never runs
ROM:08000562 06 48                       LDR     R0, =0x4000104  @ Timer1Data
ROM:08000564 04 88                       LDRH    R4, [R0]
ROM:08000566 20 1C                       MOVS    R0, R4          @ Timer1Data to r0
ROM:08000568 6F F0 46 F8                 BL      setRNG__        @ set rng state (0x3005D80) to result of timer1
ROM:0800056C 04 49                       LDR     R1, =0x4000106  @ T1CNT
ROM:0800056E 00 20                       MOVS    R0, #0
ROM:08000570 08 80                       STRH    R0, [R1]        @ turn off timer1
ROM:08000572 04 48                       LDR     R0, =0x2020000
ROM:08000574 04 80                       STRH    R4, [R0]        @ store the result of timer1 to 0x2020000
ROM:08000576 10 BC                       POP     {R4}
ROM:08000578 01 BC                       POP     {R0}
ROM:0800057A 00 47                       BX      R0
ROM:0800057A             @ End of function seedRNG__
ROM:0800057A
ROM:0800057A             @ ---------------------------------------------------------------------------
ROM:0800057C 04 01 00 04 dword_800057C:  .long 0x4000104         @ DATA XREF: seedRNG__+2r
ROM:08000580 06 01 00 04 dword_8000580:  .long 0x4000106         @ DATA XREF: seedRNG__+Cr
ROM:08000584 00 00 02 02 dword_8000584:  .long 0x2020000         @ DATA XREF: seedRNG__+12r
Code:
 
ROM:0806F5F8             @ =============== S U B R O U T I N E =======================================
ROM:0806F5F8
ROM:0806F5F8
ROM:0806F5F8             @ void __fastcall setRNG__(unsigned short T1Dat)
ROM:0806F5F8             setRNG__:                               @ CODE XREF: seedRNG__+8p
ROM:0806F5F8 00 04                       LSLS    R0, R0, #0x10   @ dumb typecasting
ROM:0806F5FA 00 0C                       LSRS    R0, R0, #0x10
ROM:0806F5FC 02 49                       LDR     R1, =0x3005D80  @ rng buffer
ROM:0806F5FE 08 60                       STR     R0, [R1]        @ set rng to T1Dat
ROM:0806F600 02 49                       LDR     R1, =0x20249BC  @ rng frame counter
ROM:0806F602 00 20                       MOVS    R0, #0          @ set counter to 0 to signify starting seed
ROM:0806F604 08 70                       STRB    R0, [R1]
ROM:0806F606 70 47                       BX      LR
ROM:0806F606             @ End of function setRNG__
Hmm I wonder if FRLG's PRNG seeding routine is better than Ruby/sapphire's...
Reply With Quote
  #6  
Unread January 28th, 2012, 04:52 PM
Kaphotics
♥ Quick Claw Guillotine ♥
 
Join Date: Apr 2011
Quote:
Originally Posted by ArmoredGuns View Post
Hmm I wonder if FRLG's PRNG seeding routine is better than Ruby/sapphire's...
It's not, R/S was better due to the more variant initial starting seeds (hence more random).

FRLG had 0x0000 - 0xFFFF starting seeds, whereas R/S was 0x0 - 0x7FFFFFFF.

Both are definitely more random than Emerald, but R/S did it better. In later games (DPPt and BW) you have a mix of datetime and hardware timers (delay).
Reply With Quote
  #7  
Unread September 2nd, 2012, 03:23 PM
AlphaDrache's Avatar
AlphaDrache
Unhatched Egg
 
Join Date: Dec 2009
Gender: Male
Are the addresses the same for the german emerald ROM?
Reply With Quote
  #8  
Unread September 2nd, 2012, 03:50 PM
Darthatron's Avatar
Darthatron
巨大なトロール。
 
Join Date: Jan 2006
Location: Melbourne, Australia
Age: 21
Gender: Male
Nature: Modest
Quote:
Originally Posted by AlphaDrache View Post
Are the addresses the same for the german emerald ROM?
Probably, but to check just see if the bytes at the given offsets are the ones described in the tutorial.
__________________
あなた は しきしゃ です
わたし は ばか です
Reply With Quote
  #9  
Unread September 3rd, 2012, 08:52 PM
Bond697
Unhatched Egg
 
Join Date: Oct 2008
Gender:
Quote:
Originally Posted by Kaphotics View Post
It's not, R/S was better due to the more variant initial starting seeds (hence more random).

FRLG had 0x0000 - 0xFFFF starting seeds, whereas R/S was 0x0 - 0x7FFFFFFF.

Both are definitely more random than Emerald, but R/S did it better. In later games (DPPt and BW) you have a mix of datetime and hardware timers (delay).
this is wrong. r/s seeds only go 0-0xffff also even though they use a more complex formula. the seeding is 16-bit either way, so no there's not more seeds.

Code:
ROM:080003E4 ; =============== S U B R O U T I N E =======================================
ROM:080003E4
ROM:080003E4
ROM:080003E4 seedRNG                                 ; CODE XREF: main+30p
ROM:080003E4                 PUSH    {LR}
ROM:080003E6                 BL      buildSeed
ROM:080003EA                 MOVS    R2, R0          ; s32 seed to r2
ROM:080003EC                 LSRS    R0, R2, #0x10   ; r0 = seed >> 16
ROM:080003EE                 LDR     R1, =0xFFFF
ROM:080003F0                 ANDS    R1, R2          ; r1 = seed & 0xFFFF (get lower 16 bits of seed)
ROM:080003F2                 EORS    R0, R1          ; upperSeed ^ lowerSeed
ROM:080003F4                 BL      setRNG
ROM:080003F8                 POP     {R0}
ROM:080003FA                 BX      R0
ROM:080003FA ; End of function seedRNG
ROM:080003FA
ROM:080003FA ; ---------------------------------------------------------------------------
ROM:080003FC dword_80003FC   DCD 0xFFFF              ; DATA XREF: seedRNG+Ar
(sapphire)

Last edited by Bond697; September 3rd, 2012 at 09:26 PM.
Reply With Quote
  #10  
Unread October 25th, 2012, 06:35 AM
aroenai
Unhatched Egg
 
Join Date: Oct 2012
Gender: Male
Quote:
Originally Posted by Bond697 View Post
just FYI, the code to seed emerald's prng actually does exist in the game. all you would need to do is branch to this(and maybe turn on timer1 if it's not already, but that's easy) at some point and you're set. it was going to work exactly like fire red and leaf green.

it's just never used:


Code:
ROM:08000560             @ =============== S U B R O U T I N E =======================================
ROM:08000560
ROM:08000560
ROM:08000560             @ void __fastcall seedRNG__()
ROM:08000560             seedRNG__:
ROM:08000560 10 B5                       PUSH    {R4,LR}         @ this function never runs
ROM:08000562 06 48                       LDR     R0, =0x4000104  @ Timer1Data
ROM:08000564 04 88                       LDRH    R4, [R0]
ROM:08000566 20 1C                       MOVS    R0, R4          @ Timer1Data to r0
ROM:08000568 6F F0 46 F8                 BL      setRNG__        @ set rng state (0x3005D80) to result of timer1
ROM:0800056C 04 49                       LDR     R1, =0x4000106  @ T1CNT
ROM:0800056E 00 20                       MOVS    R0, #0
ROM:08000570 08 80                       STRH    R0, [R1]        @ turn off timer1
ROM:08000572 04 48                       LDR     R0, =0x2020000
ROM:08000574 04 80                       STRH    R4, [R0]        @ store the result of timer1 to 0x2020000
ROM:08000576 10 BC                       POP     {R4}
ROM:08000578 01 BC                       POP     {R0}
ROM:0800057A 00 47                       BX      R0
ROM:0800057A             @ End of function seedRNG__
ROM:0800057A
ROM:0800057A             @ ---------------------------------------------------------------------------
ROM:0800057C 04 01 00 04 dword_800057C:  .long 0x4000104         @ DATA XREF: seedRNG__+2r
ROM:08000580 06 01 00 04 dword_8000580:  .long 0x4000106         @ DATA XREF: seedRNG__+Cr
ROM:08000584 00 00 02 02 dword_8000584:  .long 0x2020000         @ DATA XREF: seedRNG__+12r
Code:
 
ROM:0806F5F8             @ =============== S U B R O U T I N E =======================================
ROM:0806F5F8
ROM:0806F5F8
ROM:0806F5F8             @ void __fastcall setRNG__(unsigned short T1Dat)
ROM:0806F5F8             setRNG__:                               @ CODE XREF: seedRNG__+8p
ROM:0806F5F8 00 04                       LSLS    R0, R0, #0x10   @ dumb typecasting
ROM:0806F5FA 00 0C                       LSRS    R0, R0, #0x10
ROM:0806F5FC 02 49                       LDR     R1, =0x3005D80  @ rng buffer
ROM:0806F5FE 08 60                       STR     R0, [R1]        @ set rng to T1Dat
ROM:0806F600 02 49                       LDR     R1, =0x20249BC  @ rng frame counter
ROM:0806F602 00 20                       MOVS    R0, #0          @ set counter to 0 to signify starting seed
ROM:0806F604 08 70                       STRB    R0, [R1]
ROM:0806F606 70 47                       BX      LR
ROM:0806F606             @ End of function setRNG__
Can someone post an .ips patch that uses the built in code for Emerald, and possibly port it to R/S? The reason I ask is the batteries finally died in my copies of R/S/E so I wanted to start using my EZ Flash 3in1 and EZ Flash IV which both lack a RTC (gbata patched).

Edit: Oh wait, would that just be 61 05 00 08 at 0x478 for Emerald?
Edit 2: Nope white screen

Last edited by aroenai; October 26th, 2012 at 02:21 AM.
Reply With Quote
Reply
Quick Reply

Sponsored Links


Thread Tools

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off

Forum Jump


All times are UTC. The time now is 11:14 AM.


Style by Perdition Haze, artwork by Sa-Dui.
Like our Facebook Page Follow us on TwitterMessage Board Statistics | © 2002 - 2013 The PokéCommunity™, pokecommunity.com.
Pokémon characters and images belong to Pokémon USA, Inc. and Nintendo. This website is in no way affiliated with or endorsed by Nintendo, Creatures, GAMEFREAK, The Pokémon Company, Pokémon USA, Inc., The Pokémon Company International, or Wizards of the Coast. We just love Pokémon.
All forum styles, their images (unless noted otherwise) and site designs are © 2002 - 2013 The PokéCommunity / PokéCommunity.com.
PokéCommunity™ is a trademark of The PokéCommunity. All rights reserved. Sponsor advertisements do not imply our endorsement of that product or service. User posts belong to the user.