PDA

View Full Version : Pokemon data decrypting (asm code)


JPAN
February 13th, 2009, 08:13 PM
NOTE: all the code posted here was made with the US fire red version in mind. If you are interested in using this code in any other verison, it should still work as long as you change the values for the variable adress and party adress with those from your respective version. To find them, see the end of this post.


I have made an algorithm to decrypt the encripted data and place it somewhere in the RAM where we can look at and modify it acording to our needs. First, a brief explanation on how it works.





The GBA pokemon data is composed of 80 bytes (or 100, for party pokemon). On those 80 bytes, we can divide it in two:

The first 32 bytes of unencrypted information, like the nickname, original trainer name and IDs and a 32 bit word usually called Personality/Pokemon ID, that determines if it's shiny, gender, nature, amongst other things;
The remaining 48 bytes, encrypted information that contains almost everything important about our pokemon, like species, IV's, EV's, contest and regular status, happiness, experience, level...
Now, to access the first information, one can easily read it just by fetcing it. the second block, however, can only be read if one has the key. That key is found by performing an exclusive OR on the Personality value and OTids, both as 32bit words.



Applying that key to the data, one word at the time will decrypt it, and passing it on decrypted information will encrypt it.

On that second block, the information is compacted in four sub-blocks that store pieces of information of the same nature. Those sub-blocks change position depending on the Personality value. The remainder of Personality\24 indicates it position.

To make it harder to modify, there is also a checksum for this second block on the first block, and if the second block, adding all data as 16bit words is not equal to that checksum, the pokemon becomes a BadEgg.

This algorithm works by having a party pokemon number stored at 0x8004 (where the special 9f stores it)








So, what this algorithm does:

Finds the encryption key and stores it at the first memory position (first)
Stores the checksum at another memory position (first + 0x6)
decrypts and copies all the data from the selected pokemon (first+ 0x18)
trough a large algorytm of compares, stores all four sub-blocks starting positions (growth = first +0x8; attack = first + 0xc; effort = first +0x10; miscelaneous info = first + 0x14)
Here's the code
Edit: the portions in bold on the code is the part you need to change in order for it to work. Goes for all valid posts.

.align 2
.thumb
Start: PUSH {R0-R7,LR}
LDR R5, var_8004
LDRH R5, [R5, #0x0]
LDR R4, party_addr
MOV R6, #0x64
LDR R7, New_poke_addr
MUL R5, R6
ADD R4, R4, R5
B decrypt
.hword 0x0000
var_8004: .word 0x20370C0
party_addr: .word 0x2024284
New_poke_addr: .word 0x203F400

decrypt: LDR R0, [R4, #0x0]
PUSH {R0}
LDR R1, [R4,#0x4]
EOR R1, R0
STR R1, [R7, #0x0]
LDRH R1, [R4, #0x1C]
STRH R1, [R7, #0x6]
MOV R2, #0x20
ADD R0, R2, R4
MOV R2, #0x18
ADD R1, R2, R7
MOV R2, #0xC
LDR R5, [R7, #0x0]
decrypt_loop: LDR R3, [R0, #0x0]
EOR R3, R5
STR R3, [R1, #0x0]
ADD R1, #0x4
ADD R0, #0x4
SUB R2, #0x1
CMP R2, #0x0
BNE decrypt_loop
POP {R0}
MOV R1, #0x18
MOV R2, #0xC0
LSL R2, R2, #0x18
CMP R2, R0
BHI lower_than_c
SUB R0, R0, R2
lower_than_c: LSR R2, R2, #0x1
CMP R2, R0
BCS lower_than_6
SUB R0, R0, R2
LSL R0, R0, #0x0
lower_than_6: SWI #0x6
ADD R0, R1, #0x0
MOV R1, #6
SWI #0x6
g_in_first: CMP R0, #0x0
BNE g_in_second
MOV R2, #0x18
B g_final
g_in_second: CMP r1, #0x1
BGT g_in_third
MOV R2, #0x24
B g_final

g_in_third: MOV R2, #1
AND R2, R1
CMP R2, #1
BEQ g_in_fourth
MOV R2, #0x30
B g_final
g_in_fourth: MOV R2, #0x3C
g_final: ADD R2, R7, R2
STR R2, [R7, #0x8]

m_in_first: CMP R0, #0x3
BNE m_in_second
MOV R2, #0x18
B m_final

m_in_second: CMP R1, #0x4
BLT m_in_third
MOV R2, #0x24
B m_final

m_in_third: MOV R2, #0x1
AND R2, R1
CMP R2, #0x1
BNE m_in_fourth
MOV R2, #0x30
B m_final

m_in_fourth: MOV R2, #0x3C
m_final: ADD R2, R7, R2
STR R2, [R7,#0x14]
a_first: CMP R0, #0x1
BGT a_second
CMP R0, #0x0
BEQ a_lesser_second
MOV R2, #0x18
B a_final

a_second: MOV R3, #0x2
BEQ a_greater_second
CMP R1, #0x3
BEQ a_greater_second
CMP R1, #0x0
BEQ a_greater_third
CMP R1, #0x5
BEQ a_greater_third
MOV R2, #0x3C
B a_final

a_greater_second: MOV R2, #0x24
B a_final

a_greater_third: MOV R2, #0x30
B a_final
a_lesser_second: CMP R1, #0x1
BGT a_lesser_third
MOV R2, #0x24
B a_final
a_lesser_third: MOV R2, #0x1
AND R2, R1
CMP R2, #0x2
BNE a_lesser_fourth
MOV R2, #0x30
B a_final

a_lesser_fourth: MOV R2, #0x3C
a_final: ADD R2, R7, R2
STR R2, [R7,#0xC]
e_first: CMP R0, #0x2
BLT e_second
CMP R0, #0x2
BGT e_greater_second
MOV R2, #0x18
B e_final

e_second: CMP R1, #0x2
BEQ e_lesser_second
CMP R1, #0x3
BEQ e_lesser_second
CMP R1, #0x0
BEQ e_lesser_third
CMP R1, #0x5
BEQ e_lesser_third
MOV R2, #0x3C
B e_final

e_lesser_second: MOV R2, #0x24
B e_final

e_lesser_third: MOV R2, #0x30
B e_final

e_greater_second: CMP R1, #0x5
BLT e_greater_third
MOV R2, #0x24
B e_final
e_greater_third: MOV R2, #1
AND R2, R1
CMP R2, #0
BEQ e_greater_fourth
MOV R2, #0x30
B e_final

e_greater_fourth: MOV R2, #0x3C
e_final: ADD R2, R7, R2
STR R2, [R7,#0x10]
POP {R0-R7,PC}

But this code is pretty much useless if you don't know how to access its information. I will post further ahead some code examples on how to change and read this information.

This code has a second part to it, that must be called upon to save changes on the selected pokemon. It's pretty much the reverse, but much shorter because it doesn't need to know what was changed or the position where it must put the data. It just corrects the checksum and copies the information after encrypting it.
.align 2
.thumb
Start: push {r0-r7, lr}
ldr r5, var_8004
ldrh r5, [r5, #0x0]
ldr r4, Party_addr
mov r6, #0x64
ldr r7, new_store_addr
mul r5, r6
add r4, r4, r5
b calc_checksum
.hword 0x0000
var_8004: .word 0x020370c0
Party_addr: .word 0x02024284
new_store_addr: .word 0x0203f400
calc_checksum: mov r2, #0x1c
add r0, r4, r2
mov r2, #0x18
add r1, r7, r2
mov r5, #0x0
checksum_add: ldrh r3, [r1, #0x0]
add r5, r3, r5
add r1, #0x2
sub r2, #0x1
cmp r2, #0x0
bhi checksum_add
lsl r5, r5, #0x10
lsr r5, r5, #0x10
strh r5, [r0, #0x0]
sub r1, #0x30
add r0, #0x4
mov r2, #0xc
ldr r5, [r7, #0x0]
store_loop: ldr r3, [r1, #0x0]
eor r3, r5
str r3, [r0, #0x0]
add r0, #0x4
add r1, #0x4
sub r2, #0x1
cmp r2, #0x0
bhi store_loop
pop {r0-r7, pc}
With these two algoritms, many new commands manipulating and checking pokemon caracteristics are possible. I hope this code will be helpful on your rom-hacking.

Edit:
For easy insertion, The two main codes are now available in a small hex file, at this post.
http://www.pokecommunity.com/showthread.php?p=4914212#post4914212

Now, some asm examples on how to use this new found information.
Identifying a pokemon species
I know there is a combination of commands to identify a pokemon, but it only works on pokemon that are not eggs. This code allows you to identify a pokemon egg as well. Only one problem. You must manually set the variable 0x8004 to the egg's position as it cannot be selected by special 0x9f. I would recommend setting it to 0x0, and asking the player to put the egg in the first party slot.
b503 push {r0-r1, lr}
4803 ldr r0, 0x0203f408 ;growth structure address
6800 ldr r0, [r0]
4903 ldr r1, 0x020370c2 ;var to store pokemon species (0x8005)
8800 ldrh r0, [r0]
8008 sdrh r0, [r1]
bd03 pop {r0-r1, pc}
0000 garbage
pointers
Or in ROM-ready version
03 b5 03 48 00 68 03 49 00 88 08 80 03 db 00 00
08 f4 03 02 c2 70 03 02

Increasing a pokemon happiness by any value
If you wish to make some ways for a pokemon to gain happiness, or to make a pokemon love his trainer after an event, this code will allow it.

b50f push {r0-r3, lr}
4808 ldr r0, 0x0203f408 ;growth structure address
6800 ldr r0, [r0]
4908 ldr r1, 0x020370c2 ;var 0x8005 contains value to increase happiness by
880b ldrh r3, [r1]
7a42 ldrb r2, [r0+0x9] ;current happiness
189a add r2, r3, r2
2aff cmp r2, 0xff ; sees if the sum overflows the max happiness level
dc01 bgt correct
7262 strb r2, [r0 + 0x9]
bd0f pop {r0-r3, pc}
23ff correct: mov r3, 0xff
1ad3 sub r3, r2, r3 ;calculates difference between original and max happiness
22ff mov r2, 0xff
7242 strb r2, [r0+ 0x9]
800b strh r3, [r1] ;places actual given value back in variable, for checking purposes.
bd0f pop {r0-r3, pc}
xxxx garbage
pointers
ROM-ready version
0f b5 08 48 00 68 08 49 0b 88 42 7a 9a 18 ff 2a
01 dc 62 72 0f bd ff 23 d3 1a ff 22 42 72 0b 80
0f bd 00 00 08 f4 03 02 c2 70 03 02

See a Pokemon's pokeball
If you wish to have a place to release pokemon but keep their ball, or for a script that
bars entrance to any trainer who doesn't keep all pokemons in a special kind of ball, we have this code

b503 push {r0-r1, lr}
4803 ldr r0, 0x0203f414 ;Miscellaneous data
6800 ldr r0, [r0]
4903 ldr r1, 0x020370c2 ;var 0x8005, where the ball is stored afterards
78c0 ldrb r0, [r0 + 0x3] ; Because ball storage is peculiar, one must get rid of all
08c0 lsl r0, r0, 0x3 ;remainig information inside it
8008 strh r2, [r1]
bd03 pop {r0-r1, pc}
pointers
ROM ready version
03 b5 03 48 00 68 03 49 c0 78 c0 08 08 80 03 bd
14 f4 03 02 c2 70 03 02

And that's it for now. I shall post more examples later on. For now, you may post requests on this thread.

For more information on the data stored, I recommend the place where I learned about it, bulbapedia (search there for Pokémon data substructures in the GBA).

To find the addresses for your version:
More than likely, someone else already found the party data for you. A search on google should land you results. If not, the manual method to find them is
1. open up your rom of choice in VBA (or other emulator with cheat-search function)
2. play up to a pokecenter and have at least two pokemon. deposit all pokemon you may carry except for the one you cannot.
3. search for 32 bit value 00000000.
4. withdraw one pokemon, close the box and search with the "different than" option for 0000000
5.deposit pokemon, close box and repeat steps 3-5 until you have a set of sequential non-zero values when the second pokemon is in your party.
The first code from the sequence should be less 4 than the next, and so on, for about 20 entries. Don't worry if there is one adress missing between them (a gap of +8)
Some pokemon have a null entrance, by sheer luck.
That first code is the first value (PID) for the second pokemon in the party. Subrtract 0x64 to that address and you got the first party address.

To find the variables 0x8000:
These you must find by a similar method to the one above.
Make two scripts - one that sets the variable 0x8000 to any value you want and one that sets it to 0x0 (I will use 0x10d as an example)
Insert the scripts somewhere you can activate them quickly (if in a new game, two signposts in pallet town is a good choice)
1. Open up the game and activate one of the scripts (know which.) For instance, start with the 0x0 script
2. Search for that value (0x0000) in 16bit mode
3. activate the other script.
4. search for the other value (0x10d) in the same mode.
If you picked a odd enough number, you should get only one result. if not, repeat until there is only one.
The address you get is the address of 0x8000. add the last digit times two to the adress and you got the adress for that variable (to find 0x8004, add 0x8 to the address)

0m3GA ARS3NAL
February 14th, 2009, 06:38 AM
How about editing a Pokemon's EXP? That is what I need to know...
You should write a tutorial... you seem good at explaining alot of things...

JPAN
February 14th, 2009, 05:29 PM
To 0m3GA ARS3NAL

While it is possible to make code that changes the amount of experience on a pokemon, I have no way of reproducing the level up routine without messing up some of the status gains, at the moment. As such, I give here a code that will allow you to give a pokemon experience, but for it to level up, it is necessary to fight a battle. Also, this code has several limits. First, you can only add up to 32767 exp points (0x7fff). Any bigger and the pokemon will crash your game. Also, if the experience surpasses that of the needed to gain a level, the pokemon will present, on the status screen, a full blue experience bar with a transparent middle, and the numbers will be mixed with question marks.

If you still want it, here it is.
b507 push {r0-r2, lr}
4804 ldr r0, 0x0203f408 ;Growth block data storage address
6800 ldr r0, [r0]
4904 ldr r1, 0x020370C2 ;var 0x8005 used for storing the exp value
8809 ldrh r1, [r1]
2280 mov r2, 0x80
0912 lsl r2, 0x8
418a cmp r1,r2 ; checks if exp is between "safe" values
db02 blt add_exp
bd07 pop {r0-r2, pc}
6842 add_exp: ldr r2, [r0+0x4]
188a add r2, r2, r1 ; adds the experience
6042 str r2, [r0+0x4]
bd07 pop {r0-r2, pc}

And in the compiled version
07 b5 04 48 00 68 04 49 09 88 80 22 12 02 91 42
04 db 07 bd 08 f4 03 02 c2 70 03 02 42 68 8a 18
42 60 07 bd

Edit: As promissed, some more examples of what to do with this code

Catch the pokerus
This code here allows you to cure, immunize and catch the pokemon virus. To make it work, put in var 0x8005 a number between 0x1 and 0xf to give it, 0x0 to cure but not immunize and 0x10 or higher to immunize the pokemon, preventing him to ever catch the virus again (even with this code)
b507 push {r0-r2, lr}
4806 ldr r0, 0x0203f414 ;Misc block data storage address
6800 ldr r0, [r0]
4906 ldr r1, 0x020370C2 ;var 0x8005, keeps pokerus new status
7802 ldrb r2, [r0]
2a0f cmp r2, 0xf ; if immune, do nothing
dc02 bgt end
8809 ldrh r1, [r1] ;time to remain, bigger than 10 to immunize
2910 cmp r1, 0x10
db00 blt infect
2110 mov r1, 0x10
7001 infect:strb r1, [r0]
bd07 end:pop {r0-r2, lr}
Compiled and ready
07 B5 06 48 00 68 06 49 02 78 0F 2A 04 DC 09 88
10 29 00 DB 10 21 01 70 07 BD 00 00 14 F4 03 02
C2 70 03 02

EV related material
Several codes that allow you to manipulate Contest stats and Effort values. This following "Stat table" is used in all the following examples
Value -> Stat
0x0 -> HP EV
0x1 -> Attack EV
0x2 -> Defense EV
0x3 -> Speed EV
0x4 -> Special Attack EV
0x5 -> Special Defense EV
0x6 -> Coolness
0x7 -> Beauty
0x8 -> Cuteness
0x9 -> Smartness
0xa -> Toughness
0xb -> Feel (not used in Fire Red, so if needed, any new stat)
Any of the following EV codes only work correctly if the value is present on the table. Using others results in the unexpected.

Reading EV's/Contest stats
This one code reads the values of the stat placed on variable 0x8005, and places the result on that variable, a number from 0x0 - 0xff.
b507 push {r0-r2, lr}
4803 ldr r0, 0x0203f410 ;Effort block data storage address
6800 ldr r0, [r0]
4903 ldr r1, 0x020370C2 ;0x8005 for effort type
880a ldrh r2, [r1]
5c82 ldrb r2, [r0 + r2]
800a strh r2, [r1] ;stores effort value on variable
bd07 pop {r0-r2, pc}

Ready to use version
07 B5 03 48 00 68 03 49 0A 88 82 5C 0A 80 07 BD
10 F4 03 02 C2 70 03 02

Adding to EV/Contest stats
This code allows you to change the values of both EV's and Contest Stats, but it works differently on both situations. Place the value to add, between 0x0 - 0xff on var 0x8006 and a table value on 0x8007.
Adding EV obeys the 512 limit, so only values up to a total of 512 will be accepted. On both the Contest and EV, adding a value that is bigger than the allowed will cause the code to add only up to that limit, meaning that adding efforts that surpass 512 after adding will add only up to 512, and adding values that exceed 0xff will make the value 0xff.
b51f push {r0-r4, lr}
4811 ldr r0, 0x0203f410 ;Effort block data storage address
6800 ldr r0, [r0]
4911 ldr r1, 0x020370C4 ; use 8006 for storing given points and 0x8005 for effort type
6809 ldr r1, [r1]
040a lsr r2, r1, 0x10 ;value to increase effort-contest stats by
0c09 lsl r1, r1, 0x10 ;stat to increase
0c12 lsl r2, r2 0x10
2906 cmp r1, 0x6
db02 blt Effort
290c cmp r1, 0xc
db0d blt Contest
bd1f pop {r0-r4, pc}

1c13 Effort: add r3, r2, 0x0
2500 mov r5, 0x0

5d44 loop:ldrb r4, [r0 + r5]
18e3 add r3, r3, r4
3501 add r5, 0x1
2d06 cmp r5, 0x6
d1fa bne loop

2420 mov r4, 0x20
0124 lsl r4, r4, 0x4
429c cmp r4, r3
dc01 bgt Contest
e00f b Checkmax

5c43 Contest:ldrb r3, [r0 + r1]
18d2 add r2, r2, r3
23ff mov r3, 0xff
429a cmp r2, r3
dd01 ble add_value
22ff mov r2 , 0xff
0000 nop
5411 add_value: strb r2 , [r0 + r1]
bd1f pop {r0-r4,pc}
pointers

1a9b checkmax: sub r3, r3, r2
1ae2 sub r2, r4, r3
2a00 cmp r2, 0x0
dbf6 bgt add_value
bd1f pop {r0-r4,pc}
Ready version
3F B5 11 48 00 68 11 49 09 68 0A 04 09 0C 12 0C
00 00 06 29 02 DB 0C 29 0D DB 3F BD 13 1C 00 25
44 5D E3 18 01 35 06 2D FA D1 20 24 24 01 9C 42
01 DC 0D E0 00 00 43 5C D2 18 FF 23 9A 42 01 DD
FF 22 00 00 42 54 3F BD 10 F4 03 02 C4 70 03 02
9B 1A 45 5C 5B 1B E2 1A 00 2A F3 DC 3F BD

Erasing all EV's
This last code receives nothing and returns nothing, changing only all EV's to 0.
b505 push {r0-r1, lr}
4803 ldr r0, 0x0203f410 ;Effort block data storage address
6800 ldr r0, [r0]
2100 mov r1, 0x0
6001 str r1, [r0]
8081 strh r1, [r0 + 0x4]
bd05 pop {r0-r2,pc}
0000 garbage
pointer
Ready version
03 B5 03 48 00 68 00 21 01 60 81 80 03 BD 00 00
10 F4 03 02

And that is all for now. Feel free to ask for any other codes. Next time I post here I will bring a "teaching Attacks" code, a dumbed down "move tutor".

liuyanghejerry
February 14th, 2009, 09:34 PM
According to this tut,it seems there are a lot of things we can do now ...

0m3GA ARS3NAL
February 15th, 2009, 09:55 PM
Wow, this is great, I did not need to level the Pokemon up, but this is insane, you really should make a tutorial, and add to the super cool ASM saga that is about to hit PC.
(PC went is stages, Hex, ScriptED, Pokescript PKSV, XSE... I can see more people are going to start using ASM now...)

Okay, I have a toughie, how about changing Pokemon from shiny to normal and vice/versa while they are in your party/activated with a script? (also having it activate like leveling up would be cool, for instance if you battle for bunch of battles, the Pokemon becomes shiny, or vice versa, cause I also need that, hehe.

JPAN
February 16th, 2009, 06:26 PM
To make a pokemon shiny, as explained in Mastermind_X shiny hack, the encryption key on a pokemon must be lower than 8. For that to be acomplished one of two things must be sacrificed: either we make Personality = OTID or OTID = Personality. The main question here is when do you wish to use that script. One will sacrifice nature, gender and all that is determined by personality. The other will make the pokemon not to be yours. If at a higher level, a pokemon will not obey a trainer if he doesn't have the right badge.
So, the first method (nature-changing) is recomended for short periods of time, at the beggining of the game. But the second (OTID) is the best way as all the stat-changing nature, gender, etc will be maintained and the location for all the data will remain the same. Personality editing, for the reasons mentioned in the first post, would mess things up. So will write the code for OT changing.
Suggestions for keeping pokemon obeying you: Set a flag with the current eight badge flag value. set the flag before the battle start and clear it if both flags aren't identical.
As all other code in this page, you should keep var 0x8004 as the pokemon slot.
Place variable 0x8005 to 0x0 to return the pokemon to normal.

Turning a pokemon shiny
b5ff push {r0-r7, lr}
4d08 ldr r5 , 0x020370C0 ;var 0x8004 with pokemon value
8828 ldrh r0 , [r5]
4c08 ldr r4 , 0x02024284;first pokemon address
2664 mov r6 , 0x64
4f08 ldr r7, 0x0203f400 ;memory where pokemon was stored
4370 mul r0 , r6
4e08 ldr r6, 0x03005008 ;Variables 0x4000-0x7fff addresses dynamic address
1824 add r4, r4 , r0
8868 ldrh r0 , [r5 + 0x2]
2270 mov r2, 0x70
0152 lsl r2, r2, 0x8
3a04 sub r2, 0x4 ; places var 0x6ffe on r2, ready for address decryption
6836 ldr r6, [r6]
18b6 add r6, r6, r2; current address of 0x6ffe
2000 cmp r0, 0x0
d013 beq normal
e007 b Shiny
pointers
6830 Shiny: ldr r0, [r6]
2e00 cmp r6, 0x0 ;checks if a pokemon is already stored there
d000 beq Transform
bdff pop {r0-r7, pc} ;if it is, don't overwrite
6821 Transform: ldr r1, [r4] ; personality value
6862 ldr r2, [r4 + 0x4] ; OTID
6061 str r1, [r4+0x4] ;OTID is changed to personality
6032 str r2, [r6] ;Stored changed value on 0x6ffe and 0x6fff
2300 mov r3, 0x0
603b str r3, [r7] ;erases old key and replaces it with new key, 0
bdff pop {r0-r7, pc}
6830 normal: ldr r0, [r6]
6821 ldr r1, [r4]
6060 str r0, [r4 + 0x4]
4048 eor r0, r1
6038 str r0, [r7]
2000 mov r0, 0x0
6030 str r0, [r6]
bdff pop {r0-r7, pc}
Compiled rom code
FF B5 08 4D 28 88 08 4C 64 26 08 4F 70 43 08 4E
24 18 68 88 70 22 12 02 04 3A 36 68 B6 18 00 28
13 D0 07 E0 C0 70 03 02 84 42 02 02 00 F4 03 02
08 50 00 03 30 68 00 28 00 D0 FF BD 21 68 62 68
61 60 32 60 00 23 3B 60 FF BD 30 68 21 68 60 60
48 40 38 60 00 20 30 60 FF BD

Also, as promissed, a dumbed down move tutor. It will always teach your pokemon a move, replacing one move if no empty slots are available.
Free attack slot finder
This piece of code is to be used before the teaching code, and will check the pokemon for empty attack slots, returning 0 if none are found(corresponding to the first slot). This code will place its result on variable 0x8007.

b50f push {r0-r3,lr}
4807 ldr r0, 0x0203f40c ; attack block address
6800 ldr r0, [r0]
4907 ldr r1, 0x020370c6 ; var 0x8007 to store
2300 mov r3, 0x0
8802 loop:ldrh r2, [r0] ;loads an attack
2a00 cmp r2, 0x0 ;see if it's the empty attack
d003 beq found ;if it is, return that position
3301 add r3, 0x1
3002 add r0, 0x2
2b04 cmp r3, 0x4 ;check if it is the last attack
d1f8 bne loop
2300 mov r3, 0x0 ;if it is, places the default slot (slot 1) to store
800b found: strh r3, [r1]
bd0f pop {r0-r3, pc}
pointers

Compiled and ready
0F B5 07 48 00 68 07 49 00 23 02 88 00 2A 04 D0
01 33 02 30 04 2B F8 D1 00 23 0B 80 0F BD 00 00
0C F4 03 02 C6 70 03 02

Teaching the attack
This code will place any attack you placed on 0x8006 on the slot indicated by 0x8007,
placing its corresponding pp to the fullest and erasing any pp bonus from the previous attack. This code will check for range, not working it 0x8007 is equal to or bigger than 0x4, but it will not check for a pokemon's capability to learn such attack.
Changing attack slots
b53f push {r0-r5,lr}
4805 ldr r0, 0x0203f40c ; attack block address
6800 ldr r0, [r0]
4d05 ldr r5, 0x0203f408 ; growth block address, for pp bonus reset
682d ldr r5, [r5]
4905 ldr r1, 0x020370c4
6809 ldr r1, [r1] ;loads attack on first half and slot on second half
4c05 ldr r4, 0x08250c08 ;address of the first pp record for 0x00
0bca lsr r2, r1, 0xf ;loads attack slot*2 on r2
2a08 cmp r2, 0x8
db08 blt teach ; if r2 => 4, its not a valid slot
bd3f End: pop {r0-r4,pc}
pointers
0409 Teach: lsl r1, r1, 0x10
0c09 lsr r1, r1, 0x10 ; gets rid of attack slot
23b1 mov r3, 0xb1 ; this limits the number of attacks. For more attacks change this value
005b lsl r3, r3, 0x1
4299 cmp r1, r3
dcf0 bgt End
1880 add r0, r0, r2 ; corrects attack location
8001 strh r1, [r0] ; and places attack
0852 lsr r2, r2, 0x1
230c mov r3, 0x0c
434b mul r3, r1 ; checking location of pp address on the attack table
18e4 add r4, r4, r3
7821 ldrb r1, [r4]
1a80 sub r0, r0, r2
3008 add r0, 0x8
8001 strb r1, [r0] ; places new attack PP to full
3508 add r5, 0x8
7828 ldrb r0, [r5]
2303 mov r3, 0x3 ;3 = 11b
0092 lsl r2, r2, 0x2
4093 lsl r3, r2 ;shifting it r2 times places 11 at the bonus location
21ff mov r1, 0xff
1ac9 sub r1, r1, r3 ;r1 now contains a number with full bonus except at new attack location
4008 and r0, r1 ;this cleans the true PP bonus area
7028 strb r0, [r5]
bd3f pop{r0-r5, pc}

Ready to use version
3F B5 05 48 00 68 05 4D 2D 68 05 49 09 68 05 4C
CA 0B 08 2A 08 DB 3F BD 0C F4 03 02 08 F4 03 02
C4 70 03 02 08 0C 25 08 09 04 09 0C B1 23 5B 00
99 42 F0 DC 80 18 01 80 52 08 0C 23 4B 43 E4 18
21 78 80 1A 08 30 01 70 08 35 28 78 02 23 92 00
93 40 FF 21 C9 1A 08 40 28 70 3F BD

That is all for now.

0m3GA ARS3NAL
February 16th, 2009, 07:21 PM
So, if I want a pokemon to be shiny, I have 0x8005 set to 1, and if not, set it to 0?
And what if I need multiple pokemon de-shinnied, up to 6 at a time?

JPAN
February 16th, 2009, 09:04 PM
So, if I want a pokemon to be shiny, I have 0x8005 set to 1, and if not, set it to 0?
And what if I need multiple pokemon de-shinnied, up to 6 at a time?

Yes, to make a pokemon shiny, set 0x8005 to a value that is not 0x0.
While it would be possible to make 6 pokemon shiny at a time, it would be very hard to keep track of what pokemon was changed when with this code. Also, all these codes were made to alter one pokemon at a time.

0m3GA ARS3NAL
February 16th, 2009, 09:26 PM
That would be cool to do 6 at a time... important for a hack actually...
Am I able to change 0x8004 to change a 2nd pokemon, or 3rd, or 4th etc.. Shiny/Normal?
if not, would you be able to do that?

JPAN
February 17th, 2009, 11:49 AM
By editing the previous shiny code, and placing a small value in one of the pokemon unused stats to keep track of which variables hold the corresponding ID, I managed to modify the code to allow for up to six pokemon to be "Shinied" at a time. But, as the code only works in between a Decrypt-encrypt function, to use it correctly your script should look like this:


setvar 0x8004 0x0
#org @loop
compare 0x8004 0x6
if 0x1 goto @next
callasm @decript
callasm @shine
callasm @encript
add 0x8004 0x1
jump @loop
#org @next
This will make all party pokemon shiny. Next, I'll post the code. This time, I'll post it compilable on the devkitARM assembler, and indicate only where the values should be changed to allow a new shiny limit.
push {r0-r7, lr}
ldr r5 , pokeSlot
ldrh r0 , [r5]
ldr r4 , pokeadr
mov r6 , #0x64
ldr r7, storeadr
mul r0 , r6
ldr r6, Varadr
add r4, r4 , r0
ldrh r0 , [r5 ,#0x2]
mov r2, #0x70
lsl r2, r2, #0x8
sub r2, #0x4
ldr r6, [r6]
add r6, r6, r2
cmp r0, #0x0
beq normal
b Shiny

pokeSlot:
.word 0x020370C0
pokeadr:
.word 0x02024284
storeadr:
.word 0x0203f400
Varadr:
.word 0x03005008

Shiny: mov r3, #0x1
ShinyLoop: ldr r0, [r6]
cmp r0, #0x0
beq Transform
sub r6, #0x4
add r3, #0x1
cmp r3, #0x7 @change 0x7 to any other number for a higher limit
blt ShinyLoop
pop {r0-r7, pc}
Transform: ldr r1, [r4]
ldr r2, [r4, #0x4]
str r1, [r4, #0x4]
str r2, [r6]
strh r3, [r4, #0x1e]
mov r3, #0x0
str r3, [r7]
pop {r0-r7, pc}

normal: ldrh r2, [r4, #0x1e]
lsl r2, r2, #0x18
lsr r2, r2, #0x17
cmp r2, #0xc
bgt Bottom
cmp r2, #0x0
beq Bottom
sub r2, #0x2
sub r6, r6, r2
ldr r0, [r6]
ldr r1, [r4]
str r0, [r4, #0x4]
eor r0, r1
str r0, [r7]
mov r0, #0x0
str r0, [r6]
strh r0, [r4, #0x1e]
Bottom: pop {r0-r7, pc}
The compiled version
FF B5 08 4D 28 88 08 4C 64 26 08 4F 70 43 08 4E
24 18 68 88 70 22 12 02 04 3A 36 68 B6 18 00 28
19 D0 07 E0 C0 70 03 02 84 42 02 02 00 F4 03 02
08 50 00 03 01 23 30 68 00 28 04 D0 04 3E 01 33
07 2B F8 DB FF BD 21 68 62 68 61 60 32 60 E3 83
00 23 3B 60 FF BD E2 8B 12 06 D2 0D 0C 2A 0B DC
00 2A 09 D0 02 3A B6 1A 30 68 21 68 60 60 48 40
38 60 00 20 30 60 E0 83 FF BD

The stat I used was the two bytes next to the checksum, right before the encripted data.

Grinner
February 18th, 2009, 10:29 AM
Heh I dont know if I should be exasperated or gratefull (leaning towards gratefull) becuse I have been trying to learn ASM to do simmiler things to this for a while thinking that ASM would never become mainstream enough to have this complecated stuff posted on a forum. Now I need to work out if I will struggle on and write inferior code so I can feel I have earned it or...

Anyway thanks for posting this.

0m3GA ARS3NAL
February 18th, 2009, 10:04 PM
Heh I dont know if I should be exasperated or gratefull (leaning towards gratefull) becuse I have been trying to learn ASM to do simmiler things to this for a while thinking that ASM would never become mainstream enough to have this complecated stuff posted on a forum. Now I need to work out if I will struggle on and write inferior code so I can feel I have earned it or...

Anyway thanks for posting this.

I agree 100% I am extremly greatful for the ASM hackers coming out of seclusion and ASMing... heheh.
May I recomend HackMew's tutorial on ASM, and ZodiacDaGreat... his site has 2 ASM tutorials...
or even maybe JPAN could try his hand at one? you never know!

~0A :t282:

HentaiHentai
February 20th, 2009, 01:55 AM
Ok, Admitted looking at this and my eyes are telling me Im insane.
Lol, I understand this is ASM, and I do see that you have converted I have no clue what into hex so.
What Im most curious about is that Pokerus virus. How would I use that. heres an example of what I want to do.
EX: Player goes somewhere umm...toxic, touches something infecting the lead pokemon with pokerus what steps would i have to use to get the asm/hex stuff into a script?
Thank You

JPAN
February 20th, 2009, 03:37 PM
EX: Player goes somewhere umm...toxic, touches something infecting the lead pokemon with pokerus what steps would i have to use to get the asm/hex stuff into a script?

After inserting the ASM code in the ROM, and being (for example) 0x800000 the offset of the pokemon loading script (first posted) , 0x800500 the give-pokerus code offset and 0x801000 the pokemon storing/encryption code offset, nomething like this would work

(other preceding code)
setvar 0x8004 0x0
callasm 0x08800001
setvar 0x8005 0xf (for maximum time, any other value below is fine)
callasm 0x08800501
callasm 0x08801001
(code after event)

Basically the structure is always
choose pokemon (either fixed through setvar, or variable with special 0x9f)
callasm Decript_function
set variable needed
callasm modifying_function1
set variable needed
callasm modifying_function2
...
callasm encryption_code

Sophidius
May 10th, 2009, 07:41 AM
Does anyone know the code to make a new Hidden Machine?

onyx79
May 12th, 2009, 01:04 AM
can you add more then 386 pokemon by using asm?

destinedjagold
May 14th, 2009, 10:43 PM
sophidius, please don't revive month-old threads~

edit...
nevermind...
new rule applied. :P

Gamer2020
May 22nd, 2009, 05:11 PM
EV related material
Several codes that allow you to manipulate Contest stats and Effort values. This following "Stat table" is used in all the following examples
Value -> Stat
0x0 -> HP EV
0x1 -> Attack EV
0x2 -> Defense EV
0x3 -> Speed EV
0x4 -> Special Attack EV
0x5 -> Special Defense EV
0x6 -> Coolness
0x7 -> Beauty
0x8 -> Cuteness
0x9 -> Smartness
0xa -> Toughness
0xb -> Feel (not used in Fire Red, so if needed, any new stat)
Any of the following EV codes only work correctly if the value is present on the table. Using others results in the unexpected.

Reading EV's/Contest stats
This one code reads the values of the stat placed on variable 0x8005, and places the result on that variable, a number from 0x0 - 0xff.
b507 push {r0-r2, lr}
4803 ldr r0, 0x0203f410 ;Effort block data storage address
6800 ldr r0, [r0]
4903 ldr r1, 0x020370C2 ;0x8005 for effort type
880a ldrh r2, [r1]
5c82 ldrb r2, [r0 + r2]
800a strh r2, [r1] ;stores effort value on variable
bd07 pop {r0-r2, pc}

Ready to use version
07 B5 03 48 00 68 03 49 0A 88 82 5C 0A 80 07 BD
10 F4 03 02 C2 70 03 02

Adding to EV/Contest stats
This code allows you to change the values of both EV's and Contest Stats, but it works differently on both situations. Place the value to add, between 0x0 - 0xff on var 0x8006 and a table value on 0x8007.
Adding EV obeys the 512 limit, so only values up to a total of 512 will be accepted. On both the Contest and EV, adding a value that is bigger than the allowed will cause the code to add only up to that limit, meaning that adding efforts that surpass 512 after adding will add only up to 512, and adding values that exceed 0xff will make the value 0xff.
b51f push {r0-r4, lr}
4811 ldr r0, 0x0203f410 ;Effort block data storage address
6800 ldr r0, [r0]
4911 ldr r1, 0x020370C4 ; use 8006 for storing given points and 0x8005 for effort type
6809 ldr r1, [r1]
040a lsr r2, r1, 0x10 ;value to increase effort-contest stats by
0c09 lsl r1, r1, 0x10 ;stat to increase
0c12 lsl r2, r2 0x10
2906 cmp r1, 0x6
db02 blt Effort
290c cmp r1, 0xc
db0d blt Contest
bd1f pop {r0-r4, pc}

1c13 Effort: add r3, r2, 0x0
2500 mov r5, 0x0

5d44 loop:ldrb r4, [r0 + r5]
18e3 add r3, r3, r4
3501 add r5, 0x1
2d06 cmp r5, 0x6
d1fa bne loop

2420 mov r4, 0x20
0124 lsl r4, r4, 0x4
429c cmp r4, r3
dc01 bgt Contest
e00f b Checkmax

5c43 Contest:ldrb r3, [r0 + r1]
18d2 add r2, r2, r3
23ff mov r3, 0xff
429a cmp r2, r3
dd01 ble add_value
22ff mov r2 , 0xff
0000 nop
5411 add_value: strb r2 , [r0 + r1]
bd1f pop {r0-r4,pc}
pointers

1a9b checkmax: sub r3, r3, r2
1ae2 sub r2, r4, r3
2a00 cmp r2, 0x0
dbf6 bgt add_value
bd1f pop {r0-r4,pc}
Ready version
3F B5 11 48 00 68 11 49 09 68 0A 04 09 0C 12 0C
00 00 06 29 02 DB 0C 29 0D DB 3F BD 13 1C 00 25
44 5D E3 18 01 35 06 2D FA D1 20 24 24 01 9C 42
01 DC 0D E0 00 00 43 5C D2 18 FF 23 9A 42 01 DD
FF 22 00 00 42 54 3F BD 10 F4 03 02 C4 70 03 02
9B 1A 45 5C 5B 1B E2 1A 00 2A F3 DC 3F BD

Erasing all EV's
This last code receives nothing and returns nothing, changing only all EV's to 0.
b505 push {r0-r1, lr}
4803 ldr r0, 0x0203f410 ;Effort block data storage address
6800 ldr r0, [r0]
2100 mov r1, 0x0
6001 str r1, [r0]
8081 strh r1, [r0 + 0x4]
bd05 pop {r0-r2,pc}
0000 garbage
pointer
Ready version
03 B5 03 48 00 68 00 21 01 60 81 80 03 BD 00 00
10 F4 03 02

And that is all for now. Feel free to ask for any other codes. Next time I post here I will bring a "teaching Attacks" code, a dumbed down "move tutor".

Could you please explain a little on more on this?
Like How would I include this in a script?
(I know I have to use callasm but is that all?)

0m3GA ARS3NAL
June 10th, 2009, 02:38 AM
I just read through the first ASM code, and I must ask, am I Able to edit a pokemon's hold item using the first 2 ASM routines in this thread?
If so, I thank thee for your ASM skills, and will learn from them if you don't mind...

HackMew
June 10th, 2009, 03:16 AM
I just read through the first ASM code, and I must ask, am I Able to edit a pokemon's hold item using the first 2 ASM routines in this thread?
If so, I thank thee for your ASM skills, and will learn from them if you don't mind...

Acrutally those just decrypt the data into RAM.

0m3GA ARS3NAL
June 10th, 2009, 03:24 AM
Acrutally those just decrypt the data into RAM.

I know, but Jpan states that you can modify the data (If you know how to access it (And I am pretty sure I do) And then use the second ASM code to encrypt it back to the original place, using the second ASM script. Would this work?

HackMew
June 10th, 2009, 04:01 AM
I know, but Jpan states that you can modify the data (If you know how to access it (And I am pretty sure I do) And then use the second ASM code to encrypt it back to the original place, using the second ASM script. Would this work?

Eventually, yes. To me, decrypting stuff, copying it somewhere unencrypted, then modify it, then encypt it and copy back where it was is quite a waste though.

0m3GA ARS3NAL
June 10th, 2009, 04:26 AM
Eventually, yes. To me, decrypting stuff, copying it somewhere unencrypted, then modify it, then encypt it and copy back where it was is quite a waste though.

What do you mean, eventually?

HackMew
June 10th, 2009, 05:05 AM
What do you mean, eventually?

If you do everything correctly, that is.

0m3GA ARS3NAL
June 10th, 2009, 05:32 AM
If you do everything correctly, that is.

If it is inserted into the RAM, can't I just use writebytetooffset to edit it, since the second ASM code will insert my edited RAM into it's correct location, and fix my checksum?
EDIT
I have been fiddling around with your Pokemon Data Decryption / Encryption codes, and noticed every time I try to encrypt, the pokemon turns into a bad egg.
Is there a problem with your ASM code?

HackMew
June 10th, 2009, 05:43 AM
If it is inserted into the RAM, can't I just use writebytetooffset to edit it, since the second ASM code will insert my edited RAM into it's correct location, and fix my checksum?

Yes but using writebytetooffset doesn't make a lot of sense then. You might just make an ASM routine that uses variables as inputs so it can be easily reused.

0m3GA ARS3NAL
June 10th, 2009, 06:12 AM
Yes but using writebytetooffset doesn't make a lot of sense then. You might just make an ASM routine that uses variables as inputs so it can be easily reused.

Good point, I will do so, since I am getting into ASM a little more.

JPAN
July 28th, 2009, 03:52 PM
I can't seem to find a way to add an attachment in my first post, so here is the file with the code compiled.

Use: open up in hex editor, find the line where the character part says it starts, and copy from that line up to the one filled with FF (both codes should end in bd, no more after that)

Edit: an error in the file, where it is written "decryption code starts at 0x1b0" should read "encryption code starts at 0x1b0".
And on the edit button, I see no way to manage attatchments, so... I'm sorry.

0m3GA ARS3NAL
July 28th, 2009, 04:11 PM
I'll try it out...
and you could have just clicked edit, and replaced your old code...

Korronensu
July 28th, 2009, 05:04 PM
To 0m3GA ARS3NAL

While it is possible to make code that changes the amount of experience on a pokemon, I have no way of reproducing the level up routine without messing up some of the status gains, at the moment. As such, I give here a code that will allow you to give a pokemon experience, but for it to level up, it is necessary to fight a battle. Also, this code has several limits. First, you can only add up to 32767 exp points (0x7fff). Any bigger and the pokemon will crash your game. Also, if the experience surpasses that of the needed to gain a level, the pokemon will present, on the status screen, a full blue experience bar with a transparent middle, and the numbers will be mixed with question marks.

If you still want it, here it is.
b507 push {r0-r2, lr}
4804 ldr r0, 0x0203f408 ;Growth block data storage address
6800 ldr r0, [r0]
4904 ldr r1, 0x020370C2 ;var 0x8005 used for storing the exp value
8809 ldrh r1, [r1]
2280 mov r2, 0x80
0912 lsl r2, 0x8
418a cmp r1,r2 ; checks if exp is between "safe" values
db02 blt add_exp
bd07 pop {r0-r2, pc}
6842 add_exp: ldr r2, [r0+0x4]
188a add r2, r2, r1 ; adds the experience
6042 str r2, [r0+0x4]
bd07 pop {r0-r2, pc}

And in the compiled version
07 b5 04 48 00 68 04 49 09 88 80 22 12 02 91 42
04 db 07 bd 08 f4 03 02 c2 70 03 02 42 68 8a 18
42 60 07 bd

Edit: As promissed, some more examples of what to do with this code

Catch the pokerus
This code here allows you to cure, immunize and catch the pokemon virus. To make it work, put in var 0x8005 a number between 0x1 and 0xf to give it, 0x0 to cure but not immunize and 0x10 or higher to immunize the pokemon, preventing him to ever catch the virus again (even with this code)
b507 push {r0-r2, lr}
4806 ldr r0, 0x0203f414 ;Misc block data storage address
6800 ldr r0, [r0]
4906 ldr r1, 0x020370C2 ;var 0x8005, keeps pokerus new status
7802 ldrb r2, [r0]
2a0f cmp r2, 0xf ; if immune, do nothing
dc02 bgt end
8809 ldrh r1, [r1] ;time to remain, bigger than 10 to immunize
2910 cmp r1, 0x10
db00 blt infect
2110 mov r1, 0x10
7001 infect:strb r1, [r0]
bd07 end:pop {r0-r2, lr}
Compiled and ready
07 B5 06 48 00 68 06 49 02 78 0F 2A 04 DC 09 88
10 29 00 DB 10 21 01 70 07 BD 00 00 14 F4 03 02
C2 70 03 02

EV related material
Several codes that allow you to manipulate Contest stats and Effort values. This following "Stat table" is used in all the following examples
Value -> Stat
0x0 -> HP EV
0x1 -> Attack EV
0x2 -> Defense EV
0x3 -> Speed EV
0x4 -> Special Attack EV
0x5 -> Special Defense EV
0x6 -> Coolness
0x7 -> Beauty
0x8 -> Cuteness
0x9 -> Smartness
0xa -> Toughness
0xb -> Feel (not used in Fire Red, so if needed, any new stat)
Any of the following EV codes only work correctly if the value is present on the table. Using others results in the unexpected.

Reading EV's/Contest stats
This one code reads the values of the stat placed on variable 0x8005, and places the result on that variable, a number from 0x0 - 0xff.
b507 push {r0-r2, lr}
4803 ldr r0, 0x0203f410 ;Effort block data storage address
6800 ldr r0, [r0]
4903 ldr r1, 0x020370C2 ;0x8005 for effort type
880a ldrh r2, [r1]
5c82 ldrb r2, [r0 + r2]
800a strh r2, [r1] ;stores effort value on variable
bd07 pop {r0-r2, pc}

Ready to use version
07 B5 03 48 00 68 03 49 0A 88 82 5C 0A 80 07 BD
10 F4 03 02 C2 70 03 02

Adding to EV/Contest stats
This code allows you to change the values of both EV's and Contest Stats, but it works differently on both situations. Place the value to add, between 0x0 - 0xff on var 0x8006 and a table value on 0x8007.
Adding EV obeys the 512 limit, so only values up to a total of 512 will be accepted. On both the Contest and EV, adding a value that is bigger than the allowed will cause the code to add only up to that limit, meaning that adding efforts that surpass 512 after adding will add only up to 512, and adding values that exceed 0xff will make the value 0xff.
b51f push {r0-r4, lr}
4811 ldr r0, 0x0203f410 ;Effort block data storage address
6800 ldr r0, [r0]
4911 ldr r1, 0x020370C4 ; use 8006 for storing given points and 0x8005 for effort type
6809 ldr r1, [r1]
040a lsr r2, r1, 0x10 ;value to increase effort-contest stats by
0c09 lsl r1, r1, 0x10 ;stat to increase
0c12 lsl r2, r2 0x10
2906 cmp r1, 0x6
db02 blt Effort
290c cmp r1, 0xc
db0d blt Contest
bd1f pop {r0-r4, pc}

1c13 Effort: add r3, r2, 0x0
2500 mov r5, 0x0

5d44 loop:ldrb r4, [r0 + r5]
18e3 add r3, r3, r4
3501 add r5, 0x1
2d06 cmp r5, 0x6
d1fa bne loop

2420 mov r4, 0x20
0124 lsl r4, r4, 0x4
429c cmp r4, r3
dc01 bgt Contest
e00f b Checkmax

5c43 Contest:ldrb r3, [r0 + r1]
18d2 add r2, r2, r3
23ff mov r3, 0xff
429a cmp r2, r3
dd01 ble add_value
22ff mov r2 , 0xff
0000 nop
5411 add_value: strb r2 , [r0 + r1]
bd1f pop {r0-r4,pc}
pointers

1a9b checkmax: sub r3, r3, r2
1ae2 sub r2, r4, r3
2a00 cmp r2, 0x0
dbf6 bgt add_value
bd1f pop {r0-r4,pc}
Ready version
3F B5 11 48 00 68 11 49 09 68 0A 04 09 0C 12 0C
00 00 06 29 02 DB 0C 29 0D DB 3F BD 13 1C 00 25
44 5D E3 18 01 35 06 2D FA D1 20 24 24 01 9C 42
01 DC 0D E0 00 00 43 5C D2 18 FF 23 9A 42 01 DD
FF 22 00 00 42 54 3F BD 10 F4 03 02 C4 70 03 02
9B 1A 45 5C 5B 1B E2 1A 00 2A F3 DC 3F BD

Erasing all EV's
This last code receives nothing and returns nothing, changing only all EV's to 0.
b505 push {r0-r1, lr}
4803 ldr r0, 0x0203f410 ;Effort block data storage address
6800 ldr r0, [r0]
2100 mov r1, 0x0
6001 str r1, [r0]
8081 strh r1, [r0 + 0x4]
bd05 pop {r0-r2,pc}
0000 garbage
pointer
Ready version
03 B5 03 48 00 68 00 21 01 60 81 80 03 BD 00 00
10 F4 03 02

And that is all for now. Feel free to ask for any other codes. Next time I post here I will bring a "teaching Attacks" code, a dumbed down "move tutor".


Now HERE is some much needed info. Thanks so much for that. I hope Score_Under finds this.

0m3GA ARS3NAL
July 28th, 2009, 05:10 PM
Now HERE is some much needed info. Thanks so much for that. I hope Score_Under finds this.

There was an error in the original decrypting code.
You need to use hte new one JPAN just posted, or you WILL have errors.

Korronensu
July 29th, 2009, 04:51 PM
What does that have to do with the EV gain/loss ASM?

liuyanghejerry
July 29th, 2009, 05:38 PM
Finally,you make these methods out...really thanks,JPAN.

0m3GA ARS3NAL
July 30th, 2009, 12:02 PM
What does that have to do with the EV gain/loss ASM?

Because in order for the EV gain/loss ASM to work, you need to first decrypt the pokemon data wit the Decrypt ASM, then use the EV one, THEN use the encrypt one.
That is how those work.

Verloren
November 18th, 2009, 02:56 PM
Um.... I was told that this would probably be the right thing to use if I wanted to do this...

I'm trying to make a hack of fire red that implements the Shadow Pokemon features of XD - Gale of Darkness and Pokemon Coliseum.

So, I'm not sure how to make it so you can catch certain trainers' pokemon, or have pokemon you can't catch on the same team as someone with a pokemon you can catch.

Do you have an idea how I would go about doing this? It might be a good thing to include in a tutorial for other people who might want to do something like I do...

hi sir tomato my password is syvniti
November 19th, 2009, 07:07 AM
Um.... I was told that this would probably be the right thing to use if I wanted to do this...

I'm trying to make a hack of fire red that implements the Shadow Pokemon features of XD - Gale of Darkness and Pokemon Coliseum.

So, I'm not sure how to make it so you can catch certain trainers' pokemon, or have pokemon you can't catch on the same team as someone with a pokemon you can catch.

Do you have an idea how I would go about doing this? It might be a good thing to include in a tutorial for other people who might want to do something like I do...
Uhmm.... I don't think this is the right place, who told you that?
Now please don't be offended, but I think it's too big a job, for what you can handle. (Only juding by your post, sorry)

Verloren
November 22nd, 2009, 07:46 AM
:) Probably. A lot of other people told me the same.

I'm working on a new thing... I need to edit the ASM routine for when you get a game over to heal your pokemon only back 1 health and 1 PP for each move, instead of a full recovery.

Would that be something more along the lines of what I could do? And if so, how would I do it?

HackMew
November 22nd, 2009, 08:35 AM
:) Probably. A lot of other people told me the same.

I'm working on a new thing... I need to edit the ASM routine for when you get a game over to heal your pokemon only back 1 health and 1 PP for each move, instead of a full recovery.

Would that be something more along the lines of what I could do? And if so, how would I do it?

I can describe you the needed steps, as for actually making the things work, you'll have to read some ASM tutorials (e.g. the ones I posted in the Documents and Tutorials) and experiment yourself:


Find the exact point when the Pokémon are fully healed after "game over".
Immediately after that point, expand the routine and make it so it reset the HP/PP points all to 1.

Verloren
November 22nd, 2009, 08:43 AM
Oh! I'd never have thought of it like that! Thanks!

NarutoActor
November 30th, 2009, 06:28 PM
Hey Jpan how would you go about making an asm routime where when you step on a tile the first pokemon in your party becomes paralyzed or poisoned?

colcolstyles
November 30th, 2009, 10:00 PM
Hey Jpan how would you go about making an asm routime where when you step on a tile the first pokemon in your party becomes paralyzed or poisoned?
http://bulbapedia.bulbagarden.net/wiki/Pokémon_data_structure_in_Generation_III#Status_ailment

Decrypt, modify the "status ailment" halfword, then re-encrypt.

NarutoActor
December 2nd, 2009, 05:25 PM
ah I have been trying for two days now on taking the info from bublipidia and no go. can you be a bit more descriptive on what I should do. Thanks~

Luster
February 15th, 2010, 01:36 PM
Oh God, I am so stuck. How do you actually use these? XSE? Hex editor? please halp... I am trying to make a script to change arceus/rotom/giratina/deoxys etc forms without going through evolutions. If anyone can help, I would be forever grateful

Luster
February 23rd, 2010, 08:29 AM
s'okay folks, i learned =D

karatekid552
March 28th, 2013, 04:12 PM
I can't seem to find a way to add an attachment in my first post, so here is the file with the code compiled.

Use: open up in hex editor, find the line where the character part says it starts, and copy from that line up to the one filled with FF (both codes should end in bd, no more after that)

Edit: an error in the file, where it is written "decryption code starts at 0x1b0" should read "encryption code starts at 0x1b0".
And on the edit button, I see no way to manage attatchments, so... I'm sorry.

This resouce has sooo much in it, but for some reason, everything gave me bad eggs. Most of the people who know ASM have probably already figured this out, but no one actually posted what the solution was. For anyone who used JPAN's compiled decryption/encryption, the problem was actually quite simple: there was another typo, the line "encryption code starts at 0x1b0" should read "encryption code starts at 0x1a0". This may seem quite simple, but it left me stuck for almost 4 hours:D until I gave up and just converted the entire document to ASM instructions and realized I had the wrong starting point.

I hope this helps anyone looking to add some cool new in-game Pokemon editing to their hacks!

Spherical Ice
March 29th, 2013, 03:44 AM
Hm, does anyone know how I could change the gender and nickname of a Pokémon?

I've got everything else to work but I'm not quite sure what I'm doing for that.

karatekid552
March 29th, 2013, 08:19 AM
Hm, does anyone know how I could change the gender and nickname of a Pokémon?

I've got everything else to work but I'm not quite sure what I'm doing for that.

Gender is linked into the PID. this thread just deals with unencryting the Data section which was XOR'd with the PID word by word. I've wanted to know this too. Let me take a look at how the PID is set up. the coding here should proove useful as it resets the checksum which is necessary for any PID changes.

edit: I didn't read through this completely yet, but it should be useful: http://bulbapedia.bulbagarden.net/wiki/Personality

Spherical Ice
April 1st, 2013, 04:13 AM
Spherical Ice:
Okay, so I know that you have to set the fourth byte of the Pokémon's PID to 0xFE to make it female. I have no idea what I do with this information D:

I still don't understand ASM despite the tutorials I've read.

karatekid552
April 1st, 2013, 03:46 PM
Spherical Ice:
Okay, so I know that you have to set the fourth byte of the Pokémon's PID to 0xFE to make it female. I have no idea what I do with this information D:

I still don't understand ASM despite the tutorials I've read.

Well, the decryption routine and the encryption routine will recalculate the checksum, so if we use those and then in between them, we change the last (first? Reverse hex, or is it already reverse? IDK) byte to 0xFE, it should work.

To accomplish this, you would just load the offset of the byte you want to change into r0 and then 0xFE into r1 and then strb r1, [r0]. Fairly simple, if you understand it.:p Hit me up on MSN sometime and I might be able to help you understand it better.

Nightcrow
April 4th, 2013, 03:53 AM
I'm a bit an old fashioned pokemon gamer. I really love the firered remake and the abilities, but i'm not very fond of the natures system. I want to give all (gifts/wild/trainerbattle) pokemon the docile nature (in other words, use the normal stats they had in red/blue). i guess some ASM is required when the pokemon is generated, has anyone looked into this so far or do i start from scratch?

AlphaDrache
July 5th, 2013, 01:13 PM
Hi,

I have a little problem with the decryption code.
I use the code in the emerald version and it works fine but there is still one problem:
the four blocks of the pokemon substructures don't have the order they should still have. It is every time a different order which makes it impossible to me to change data like happiness.

I wonder how could this work for other people who posted in this thread.
I only had changed the addresses of the party and the var 8004 to make it work for my language version of emerald.

Can someone help me please?

Ethanb900
March 22nd, 2014, 09:20 AM
Hey. Do you know how to add Rotom and all of its forms? I was told that it was only possible through ASM. I don't feel right asking for its code or something, but could you tell me what I have to code into the game? I understand HEX though (I use HEX Workshop if there's any difference in programs) and from what I see, ASM is just flipped HEX. Can you help me out?

karatekid552
March 22nd, 2014, 12:15 PM
Hey. Do you know how to add Rotom and all of its forms? I was told that it was only possible through ASM. I don't feel right asking for its code or something, but could you tell me what I have to code into the game? I understand HEX though (I use HEX Workshop if there's any difference in programs) and from what I see, ASM is just flipped HEX. Can you help me out?

http://www.pokecommunity.com/showthread.php?t=299696

You need to read this.