• Just a reminder that providing specifics on, sharing links to, or naming websites where ROMs can be accessed is against the rules. If your post has any of this information it will be removed.
  • Ever thought it'd be cool to have your art, writing, or challenge runs featured on PokéCommunity? Click here for info - we'd love to spotlight your work!
  • Welcome to PokéCommunity! Register now and join one of the best fan communities on the 'net to talk Pokémon and more! We are not affiliated with The Pokémon Company or Nintendo.

[Other] IV and EV modyfying

  • 794
    Posts
    11
    Years
    I searched for something that could allow me to alter IV/EV data, but to no avail. My question, is there any tool/routine/script/etc. that would change Pokemon's IV and EV? I know that JPAN had this option in his hacked engine and I'd happily use it if not for the fact that my rom is corrupted and switching to a new, clean one is a no-option for me(I added way too many things). But I'm sure there has to be something else, it would be hard to believe that Emerald hackers didn't think of that(as hacked engine only works for fire red). If there is nothing however, would making a routine that alters IV/EV data be hard?
     
    I searched for something that could allow me to alter IV/EV data, but to no avail. My question, is there any tool/routine/script/etc. that would change Pokemon's IV and EV? I know that JPAN had this option in his hacked engine and I'd happily use it if not for the fact that my rom is corrupted and switching to a new, clean one is a no-option for me(I added way too many things). But I'm sure there has to be something else, it would be hard to believe that Emerald hackers didn't think of that(as hacked engine only works for fire red). If there is nothing however, would making a routine that alters IV/EV data be hard?

    It depends on how you want it to work. There are built-in functions that you can use that will handle all the decryption and encryption for you. All you really need to know is where the Pokemon data is and how to call a function from ASM. The function at 0806ACAC sets attributes and the function at 0806A518 gets them.

    Call with arguments: r0 - Pointer to pokemon data, r1 - attribute, r2 - new value (set attribute only). There is a list of attributes in knizz's IDB for Fire Red (it's the same for Emerald).
    For IVs, set r1 to one of:
    Code:
    0x27 = HP
    0x28 = ATK
    0x29 = DEF
    0x2A = SPD
    0x2B = SP_ATK
    0x2C = SP_DEF

    If you don't understand how to write the ASM, don't hesitate to ask.
     
    Last edited:
    It depends on how you want it to work. There are built-in functions that you can use that will handle all the decryption and encryption for you. All you really need to know is where the Pokemon data is and how to call a function from ASM. The function at 0806ACAC sets attributes and the function at 0806A518 gets them.

    Call with arguments: r0 - Pointer to pokemon data, r1 - attribute, r2 - new value (set attribute only). There is a list of attributes in knizz's IDB for Fire Red (it's the same for Emerald).
    For IVs, set r1 to one of:
    Code:
    0x27 = HP
    0x28 = ATK
    0x29 = DEF
    0x2A = SPD
    0x2B = SP_ATK
    0x2C = SP_DEF
    If you don't understand how to write the ASM, don't hesitate to ask.

    I didn't expect that someone would answer my question, thanks!
    About decryption and encryption, I think I can handle that. There is an article on Bulbapedia that explains the process(Xoring Personality Value and PIT to get the key and then Xoring key with words.) But if there's an in-game function that could do it for me, that's even better. Pokemon Data is in the WRAM I believe and all offsets are on Bulbapedia.
    Now, what do you exactly mean by attributes? IV, EV? If so, would the routine look like this?
    @call function 0806ACAC
    @r0 = (address)
    @r1 = 0x27(HP IV for example)
    @r2 = 0x1F(set max IV)
    And to just read IV I would have to call a function at 0806A518, choose an argument and get its value? Am I understanding this correctly? Sorry if I got something wrong, but the concept is still new to me.
     
    If your only editing EVs of enemy trainer's pokemon, I think G3T has an option for that O.o
     
    I didn't expect that someone would answer my question, thanks!
    About decryption and encryption, I think I can handle that. There is an article on Bulbapedia that explains the process(Xoring Personality Value and PIT to get the key and then Xoring key with words.) But if there's an in-game function that could do it for me, that's even better. Pokemon Data is in the WRAM I believe and all offsets are on Bulbapedia.
    Now, what do you exactly mean by attributes? IV, EV? If so, would the routine look like this?
    @call function 0806ACAC
    @r0 = (address)
    @r1 = 0x27(HP IV for example)
    @r2 = 0x1F(set max IV)
    And to just read IV I would have to call a function at 0806A518, choose an argument and get its value? Am I understanding this correctly? Sorry if I got something wrong, but the concept is still new to me.

    You need to set the arguments before you call a function.

    A Call to setattr would look like this:
    Code:
    @ ...
    ldr r0, =(0xDEADBEEF) @ Replace with address of pokemon data
    mov r1, #0x27 @ HP IV
    mov r2, #0x1F @ value
    
    @ Here comes the call
    ldr r3, =(0x0806ACAC + 1) @ add one because target code is THUMB
    bl call_via_r3
    
    @ ...
    
    call_via_r3:
    bx r3

    We load the arguments on the registers r0-r3 (we only need up to r2 in this case). Then we load the address of the code into another register. The rest is a bit hacky. What we would LIKE to do is BL to that code. However, BL has a limit to the distance it can jump. So we need to use BX (which is essentially unlimited). However, another caveat is that BX does not set the link register, so the target code has no idea how to get back to our code after it is finished. Thus, we BL to our our own function, setting LR, and then immediately BX to our code. This allows the function to properly return. T
    here are a few other ways of doing this, but the above is generally preferred around here. This essentially is the same as the BLX opcode - but that is unavailable in ARMv4 (GBA/ARM7TDMI instruction set).

    As for reading (getattr), its much the same. However, you don't set r2 (it doens't need a value) and the result is given back to you in r0.

    Do you know C? If so I can write equivalent C code.

    EDIT: I would recommend against writing your own decryption/encryption code unless you want to try to challenge yourself. There is no point in duplicating code - JPAN does this, but his code is generally weird.
     
    Last edited:
    You need to set the arguments before you call a function.

    A Call to setattr would look like this:
    Code

    We load the arguments on the registers r0-r3 (we only need up to r2 in this case). Then we load the address of the code into another register. The rest is a bit hacky. What we would LIKE to do is BL to that code. However, BL has a limit to the distance it can jump. So we need to use BX (which is essentially unlimited). However, another caveat is that BX does not set the link register, so the target code has no idea how to get back to our code after it is finished. Thus, we BL to our our own function, setting LR, and then immediately BX to our code. This allows the function to properly return. T
    here are a few other ways of doing this, but the above is generally preferred around here. This essentially is the same as the BLX opcode - but that is unavailable in ARMv4 (GBA/ARM7TDMI instruction set).

    As for reading (getattr), its much the same. However, you don't set r2 (it doens't need a value) and the result is given back to you in r0.

    Do you know C? If so I can write equivalent C code.

    EDIT: I would recommend against writing your own decryption/encryption code unless you want to try to challenge yourself. There is no point in duplicating code - JPAN does this, but his code is generally weird.

    Thanks for detailed answer. I think I now understand everything except one part. I don't know how to get Pokemon Data. Or rather what data is needed there. Do I load 0x02024284(beginning of first pokemon data) and it magically finds IVs? Or do I need to load an address with IVs which has encrypted data and can be find in different places depending on Personality Value?

    As of C. I don't really know it, I was learning programming in C++. but I quit before learning anything useful(just loops, arrays, functions, ifs), so no. I probably wouldn't understand your code.
     
    Thanks for detailed answer. I think I now understand everything except one part. I don't know how to get Pokemon Data. Or rather what data is needed there. Do I load 0x02024284(beginning of first pokemon data) and it magically finds IVs? Or do I need to load an address with IVs which has encrypted data and can be find in different places depending on Personality Value?

    As of C. I don't really know it, I was learning programming in C++. but I quit before learning anything useful(just loops, arrays, functions, ifs), so no. I probably wouldn't understand your code.

    Yes it will just work with 0x02024284, etc. It allows access of other attributes too (non-encrypted) - like gender, HP and other stuff. That way you don't have to remember the layout of the struct when reading or setting data.
     
    Yes it will just work with 0x02024284, etc. It allows access of other attributes too (non-encrypted) - like gender, HP and other stuff. That way you don't have to remember the layout of the struct when reading or setting data.

    Alright then. Would you take a look at that code?
    Spoiler:

    It's basically a copy-paste of yours. I tried it and rom just resets. Have I forgotten about something important?
     
    Alright then. Would you take a look at that code?
    Spoiler:

    It's basically a copy-paste of yours. I tried it and rom just resets. Have I forgotten about something important?

    Sorry, I assumed you were using Emerald due to misreading your OP. Change 0806ACAC to 0804037C. Get attribute is 0803FBE8 in FireRed.
    Some advice. You should get yourself a copy IDA, because it will free you up significantly (you'll be able to find this out for yourself), also join the IRC because your questions will be answered much more quickly.
     
    Sorry, I assumed you were using Emerald due to misreading your OP. Change 0806ACAC to 0804037C. Get attribute is 0803FBE8 in FireRed.
    Some advice. You should get yourself a copy IDA, because it will free you up significantly (you'll be able to find this out for yourself), also join the IRC because your questions will be answered much more quickly.

    Are you sure 0804037C is correct? I changed it and my rom freezes.
    Also, I'd had a fire red IDA at some time but I couldn't understand anything so I deleted it. I'll check it again.
     
    Are you sure 0804037C is correct? I changed it and my rom freezes.
    Also, I'd had a fire red IDA at some time but I couldn't understand anything so I deleted it. I'll check it again.

    I can't see any reason for it to freeze unless you didn't add 1 to 0804037C or you inserted it wrong. Can you please paste your code you are currently using and the offset at which you are inserting it?
     
    I can't see any reason for it to freeze unless you didn't add 1 to 0804037C or you inserted it wrong. Can you please paste your code you are currently using and the offset at which you are inserting it?
    Sure. My code:
    Spoiler:
    Inserted at offset 0xA00500.
    XSE script:
    Spoiler:
     
    Sure. My code:
    Spoiler:
    Inserted at offset 0xA00500.
    XSE script:
    Spoiler:

    Your problem is after the bl call_via_r3. After this is finished, it executes the code directly after this instruction as this is the instruction that sets LR. Move pop {r0-r3,pc} to after this line so that it reads:

    Code:
    bl call_via_r3
    pop {r0-r3,pc}

    BX does not set LR so execution does not return there.

    EDIT: As daniilS pointed out, the value for r2 needs to be a pointer, rather than a value.

    You can create a pointer on the stack as follows
    Code:
    push {r2} @ Put r2 on the stack
    mov r2, sp @ Use pointer rather than value
    @ Call something
    pop {r2}
     
    Last edited:
    Your problem is after the bl call_via_r3. After this is finished, it executes the code directly after this instruction as this is the instruction that sets LR. Move pop {r0-r3,pc} to after this line so that it reads:

    Code:
    bl call_via_r3
    pop {r0-r3,pc}
    BX does not set LR so execution does not return there.

    EDIT: As daniilS pointed out, the value for r2 needs to be a pointer, rather than a value.

    You can create a pointer on the stack as follows
    Code:
    push {r2} @ Put r2 on the stack
    mov r2, sp @ Use pointer rather than value
    @ Call something
    pop {r2}

    Whoa, there's a lot of info. And I think I'm lost...Help?
    Spoiler:
     
    Whoa, there's a lot of info. And I think I'm lost...Help?
    Spoiler:

    I meant that you need to wrap the function call in a push and pop. They don't necessarily need to be at the start and end of the routine

    Code:
    .text
    .align 2
    .thumb
    .thumb_func
    
    main:
        push {lr} @ Preserve LR, you are setting it and it needs to be maintained
    
        ldr r0, =(0x02024284)
        mov r1, #0x27
        
        @ Load the value we want to set
        mov r2, #0x1F
        @ We want a pointer to this value, so place it on the stack
        push {r2}
        mov r2, sp 
    
        @ We now have a pointer to 0x1F. Thus a ldr r2, [r2] would set r2 to 0x1F
    
        @ Call the function as usual
        ldr r3, =(0x0804037C + 1)
        bl call_via_r3
    
        @ Take the value off the stack (we don't need it anymore)
        pop {r2}
        
        @ Return (LR was pushed onto the stack, take it off and put the value on PC)
        pop {pc}
    
    call_via_r3:
        bx r3

    Remember, the stack can be used for arbitrary data storage. It doesn't matter what you put on there, so long as you undo what you did. Routines outside your own cannot know what you did to the stack so you have to make sure your routine is an isolated unit - modifying the stack pointer and not fixing it to its original value before returning will crash the game, because the routines calling ours do not get the values off the stack (when they pop data off) that they were expecting.

    When we push registers to the stack, we're just preserving their CONTENTS for the calling routine - nothing more. Since thr routine calling ours expects r0-r3 to be messed up by the code (they're used for arguments), we only need to push higher registers (r4 and up). Thus, only registers that are changed need to be "saved" on the stack.

    We can also save LR on the stack, which is needed if you change its value (explicitly with MOV or something, or implicitly with BL). If we pushed LR, we can pop that value onto PC, otherwise we can return to the calling function with BX LR.
     
    I never used ASM and don't know how to, and I like when I understand what I'm doing
     
    I never used ASM and don't know how to, and I like when I understand what I'm doing

    It's actually really easy, I was surprised by how easy it was when I first had to insert ASM. There's a tutorial here.
     
    Back
    Top