This game does not work on normal hooks (multi DOL) (freezes on load screen), you need to use 1.07 or newer with rebooter to start the game.
One of the hardest games to look for the codes so far for me, because game freezes if you do normal mem2 dump :confused:, and all the item locations change dynamically without reliable pointer, so I had to do ASM injection for this code.
Unlimited Ammo, Unlimited Health, Max Damage to enemies with any weapon [Dr.Pepper]
200804A0 901F0000
C208049C 00000007
3E60C08F 6273F590
82730000 7E73F850
2C1303C0 41820020
7E74F850 2C1303C0
40820008 386000FF
2C080002 41820008
7C030050 00000000
This time, I'm quite proud of this code. Game does not have any good static pointers, all memory pointers change randomly between missions.
NOPing the normal substraction (sub r0,r0,r3) from assembly is bad idea, since same function is used for subtracting the damage from enemies, ie they wouldnt die after that. So I ended by adding exceptions to the subtraction code with following logic:
lis r19,0xC08F # (hig) while in gameplay (not in animations) this memory position has
ori r19,r19,0xf590 # (low) pointer address (+offset) to your player health
lwz r19,0(r19) # load address from pointer into register
sub r19,r31,r19 # count offset from address beeing substracted vs your health address offset
cmpwi r19,960 # compare to person offset (960, 0x3C0)
beq- 0x20 # if matches (then its your player) -> skip the subtraction == infinite health
sub r19,r31,r20 # to see the pointer offset, ie to see if it is "person offset"
cmpwi r19,960 # if person offset matches then we are hitting enemy
bne- 0x08 # jump over li if we are not hitting enemy
li r3,255 # change damage to enemy to 255 (kills enemy with single shot or single sword hit)
cmpwi r8,2 # check if we are subtracting gun ammo
beq- 0x08 # skip subtraction if it was gun ammo == unlimited ammo
sub r0,r0,r3 # this sub was the one we were injecting.
Hopefully this would be helpfull for people who are looking into ASM injection code making, atleast I would have found comments usefull when reading forum for first time :)
thats brilliant, and thanks you so much with the comment, if your like me, you love the feeling when it all comes together.
The way that within the subroutine you were able to check between player and enemy was pretty cool. Do you think though, it would be possible to find a multilevel pointer in this game (i.e pointer pointing to another pointer) for a standard base?
I did try pointer in pointer searches with the wiird, without succeeding, might be because values are mixed between 80, 90 and C0 ranges, and I didn't test to merge the memory dumps to combine them all in one big search. Somebody might be able to find working pointer, but that one is not me :)
The C0 range pointer seemed to work the best, but if I used static pointer load with DE000000 900093000 checks, it still freezed the game on animations, most likely that pointer changes to some other pointer in the same range during animations, and writing your health there would freeze up the game. So in the end ASM injection was the safest way not to freeze the game, since subtraction routine is only called during gameplay and then the pointer is always valid.
C0 ? Wow... C0 should mostly contain the same stuff as 80 --> http://wiibrew.org/wiki/Memory_Map
C0 is MEM1 uncached, while 80 is cached.. so that shouldn't make tooo different results.. at least poking the C0 area should be hard if you find anything there, try to poke it in the 80 area.. C0 and 80 are mirrors, as well as D0 and 90..
Yeah sounded quite wierd, but C0 area gave me working pointer to mem2 area and searching 80 area didn't. Ohwell maybe I'll try 80 area again some day, but as my current code is working fine, then I dont see much point doing so :)
Might be that 80 area did give me same pointers to 90-area health, but then same pointer failed on direct writes and froze the game on animations even with DE000000 900093000 checks, and while I was stydying C0 area, I got the idea for ASM injection, and that way worked.
Yeah i see no reason to change what you've done now, its a great code. I'm still new at the wii hacking scene though (i've hacked other consoles extensively however)
Can you just give me a brief rundown on the asm injection, i understand the top line is where it hooks in, now can this be in the place where you want the injection, or do you make a hook using a JUMP command, to jump to an area of 0's and write your routine there? I understand that the subtract was the reducing of the health found through breakpoint??? So did you simply inject your routine there, and wiird handles it so it doesn't interupt gameplay, or did you inject on a random JUMP and then simply refer to the area with the subtraction??
Just a bit confused, coz on psp scene we didn't have code types like this, we had to do the whole thing by WRITING and thats it, so we'd modify a jr ra (jump return in mips) to jump to a area of blank code, then write our routine there, then jr ra so that it linked back to where it was meant to be because we didn't touch the RA register.
EDIT: I did a bit of reading again with this question in mind, so can you confirm this is how it works?
You find the actual execution code with a breakpoint (i.e the subtraction of the health) now ON this line, you do the asm code injection wiird code type, then write your routine, and as the LAST line, you put what was originally there so the game continues as planned?
yes, first searched by breakpoint the location which writes to health memory position, and found the sub r0,r0,r3 on the previous line in disassembly.
In original game RAM its located in "8008049C sub r0,r0,r3"
C208049C 00000007
C2-codetype means that we want to inject 7 lines of ASM code at that memory position.
CST1 : Insert ASM code in the game
C2XXXXXX NNNNNNNN = insert instructions at XXXXXX+ba (ba=80000000)
And Gecko OS basicly just overwrites 8008049C memory location so "sub r0,r0,r3" is replaced with "b 0x800027xx (or something similar, dont remember the excact place where gecko os memory is)" branch to Gecko OS memory location where custom codes are executed, ie memory are which is free. You dont need to put sub r0,r0,r3 in your injection code unless you want to have it there, on some situations you just want to replace some routine totally, but in my case I wanted the sub to be runned on other situations than my cheat.
7C030050 00000000
The last 00000000 is obligatory, since gecko OS replaces that one with branch back to code that you were injecting ie. "b 0x800804A0". So basicly C2-code just overwrites the wanted memory location with branch jump to gecko OS (free memory/blank memory), inserts wanted number of lines of ASM code, and automaticly calculates branch back to next memory location where execution would normally be running over the last 00000000-code.
Hopefully that one helps on your questions. Please ask more details if I was unclear.
excellent thats exactly what i needed to know, thank you for that!
So in theory you could write the entire routine with just the "write" code type, by just changing the (sub r0, r0, r3) to a( b CODE CAVE) and then writing your routine at the code cave and then just branch back to where we were? I guess it is just easier using c2 though as geck os does most of the work for you lol.
Thanks Dr Pepper
Do you have a large knowledge of ASM or did you lookup what was needed?
Did you already know what sub, lis, cmpw did etc?
I had some basic understanding of arm-based assembly hacking, like NOP, b, and bne's. Basicly I just googled "powerpc instruction set" and dag out what I needed, pretty simple just to look for add, subtraction and load in/from address and some basic compares.
Thanks dude
If you have any good sources/docs that would be much appreciated
Will have a google as well
this code makes the game crash at the 'Licensed by Nintendo' screen.
I'm using Ocarina and i've also tried the Rebooter with the same results
Have you tried the updated code, with the 20-code line in it? As I updated it today?
It only works with rebooter and Disc Channel. Are are you able to start the game without the code?
Yes i've tried that, with both Gecko OS 7.a and 7.b
i also exported the GCT file using Code Manager (Wii hombrew version not pc)...dunno if that would change anything
One of the registers that I though was free, was used during animations. Now I fixed the registers that ASM uses, code should work now.
I even tested with GeckoOS1.07(Ocarina) and worked for me.
Still no luck with the codes, it still freezes at 'Licensed by Nintendo' screen.
has anyone else been able to use them
Wierd, it should only freeze if you start the game with A-button (since its multidol game), but should work if you press B-button (rebooter mode) and start game through Disc Channel. Atleast works fine for me when I tested with GeckoOS1.07 rebooter yesterday.
I found the problem, it was Code manager wii version, i made the GCT file with the pc version and it worked fine
Dr.Pepper, first of all - big thanx for your codes! Works great with Gecko OS 1.07b + ocarina + rebooter. But some episodes... I can't finish it, coz I killin' some important NPC's. How I can to disable "Max Damage to enemies with any weapon" option? =8-0)
Excuse for my bad english, I'm from Russia. =8-0)
You can disable max hit by changing the following line: 40820008 386000FF -> 48000008 386000FF
thanx! I'll try it soon. =8-0)
hey, just wondering, Dr.Pepper, would you allow me to mod the code a little. If i get some free time, I could add a button control to the ONE HIT KILL, so like if you're holding Z and you shoot, it kills in one hit. I'd just need the Control address, and the button you think would be most suitable and I could whip it up if you'd like!
Hackers usually prefer that you don't modify their codes just to do something like that (unless it's just for yourself). :)
Dr.Pepper, the new code works perfect! really big thanx! :)
lol i'd give full credit to him, I just know that a few people would like that option. Honestly I'm just bored waiting for my gecko, just wanna write some asm really.