Heres tutorial #2
Please post comments and questions in this thread.
Evox Trainer Tutorial.
Tools needed:
Computer Xbox Latest Evox CXBX (http://www.caustik.com/cxbx/) Network connection between xbox and computer brain
Useful tools:
Ida Pro (any will do, 4.30-current is ideal)
Tutorial #2... NBA Jam 2k4 (USA/NTSC)
I assume that you have read the TMNT tutorial, so you are at least slightly familiar with the tools referenced, if not, please go read it first.
Convert your xbe to an exe, load it into Ida Pro, or whatever your perfered disassembler is..
Our goal is to add an option so that you can buy any attribute for free, regardless of how much money you have, and hopefully go on by yourself to extend it to cover all purchases on unlockable items.
I started out doing a traditional search for values, but came up empty, so I looked for another way to train the game. I noticed when you start a new career that you begin with 10,000 jam points to spend on upgrades for your player. So I took 10,000 and converted it to hex (I used the calculate in A.X.E hex editor, but windows calc will do just fine) and got 2710h, so I search using the text search tool for (spc)2710h
(spc) being a blank space, so that I wouldn't get matches for 42710h, etc.
The first occurance I come across is:
.text:0001A2EF mov dword ptr [esi+2Ch], 2710h .text:0001A2F6 mov al, 0FFh
.text:0001A2E0 00 00 89 7E 14 66 A1 A8-5E 2B 00 66 89 46 38 C7 "..ë~¶fí¿^+.fëF8¦" .text:0001A2F0 46 2C 10 27 00 00 B0 FF-88 86 E6 03 00 00 88 86 "F,'..¦ êåµ..êå" ^^^^^-- Value..
So I poke 0001A2F2 with a value (ff) and start a new player, what do ya know, instead of starting with 10,000 I started out with 10,239.. So now we know we have found what initially load the value into some memory location.
*** So I exit out of the menus, and set a 'bpx 0 0001A2EF' and re-enter the jam store. I instantly get a break...
BP 0 @ 0001a2ef EAX : 00000019 EBX : 00000000 ECX : 011eaaf4 EDX : 011eabdc ESI : 011eaaf4 EDI : ffffffff EBP : d00648c8
(yours may be different)
so I take ESI (011eaaf4) and add '2c' to it and get 11EAB20, this is where the money is stored (at least at first). so I clear my break point (bpc 0) and choose a profile.
I then go to the create a player screen, and look for somewhere to spend money. If you hit the 'R' trigger until you are at the guy flexing his muscles you will see you can buy attributes..
So I hit a, and see a bar below, I hit right, and see that my pts decreases, so I hit left, then set a breakpoint on the address I learned.
bpmb 0 11EAB20 w
(we only care about writes at this point)
Now hit right again, you should get a break..
!!!! If you don't then choose the menu option discard and exit, go to the create a player option, then turn back on the bpx 0 0001a2ef and use the new offset, sometimes it changes on me, sometimes it doesn't..
I had to follow my advice above, and reget the address
BP 0 @ 00084d32 EAX : fffff830 EBX : 00000003 ECX : 012dfb90 EDX : 00000fa0 ESI : 012d4750 EDI : 00000002 EBP : 00000000
Now go to 0084d32 in your disassembly..
.text:00084D26 mov eax, [esp+arg_0] ; Get value to subtract (negative number) .text:00084D2A add edx, eax ; Take our value (edx) and sub above # .text:00084D2C mov [ecx+0E0h], edx ; move new value to where we store money .text:00084D32 retn 4
We have multiple options, we can fix the game to always send '0' or a positive number when you buy an item to this function, or we can make it not subtract, or we can let it do all that, and just not update our value, I chose to do the third option since it makes it easier for me to find other writes to that address (less uf'ing)
So we
poke 00084D2C 90 poke 00084D2d 90 poke 00084D2e 90 poke 00084D2f 90 poke 00084D30 90 poke 00084D31 90
yay, now it doesn't cost anything to buy attributes..
But wait, we aren't done, as you keep hitting right eventually it will stop, since we don't have enough money to purchase!
Okay, so now that we have the write taken care of, lets see where it reads (since its probably getting the value, comparing it, then if there is enough, going on)
so set your break point just as you did above (bpmb 0 11EAB20 w) but this time do a bpmb 0 11EAB20 r (be sure to use the address YOU got, since it will likely be different)
Oh my, as soon as we set this we got a break, but we didn't hit any key...
.bpmb 0 12DFC70 r .Break BP 0 @ 00085be5 EAX : 00000fa0 EBX : 3c88b0f0 ECX : 012d4750 EDX : 00000002 ESI : 012dfb90 EDI : 3c88b0f0 EBP : d00648c8
.text:00085BDF mov eax, [esi+0E0h] .text:00085BE5 push eax .text:00085BE6 lea ecx, [esi+4C8h] .text:00085BEC push offset aJamPtsD ; "Jam Pts: %d" .text:00085BF1 push ecx .text:00085BF2 call sub_1B37FD
What this is doing is effectively in C is something like sprintf(ecxlocation,"Jam Pts: %d", eax) eax being our pts, so this is likely JUST doing the screen update stuff, and not effecting our compare..
So we have two options, put something else in eax, so we don't break, or just live with it and hold right on our controller and keep entering 'uf's (up enter)
Sooner or later, you should get a break thats different.. It took me 3 uf's.
BP 0 @ 000c0c81 EAX : 00001f40 EBX : 00000003 ECX : 012dfb90 EDX : 000000dc ESI : 012d4750 EDI : 0000000b EBP : 00000000
.text:000C0C73 call sub_C0200 .text:000C0C78 mov ecx, [esi+14h] .text:000C0C7B cmp [ecx+0E0h], eax .text:000C0C81 jl short loc_C0CC6
So this is getting our value with the ecx+0e0h and comparing it to eax, if we are less then, then it jumps..
So we want to remove that..
poke 000C0C81 90 poke 000C0C82 90
Hmm, but we still didn't get the item, lets try that again.
BP 0 @ 000c04fe EAX : 012dfb90 EBX : 00001f40 ECX : 00000001 EDX : 00000001 ESI : 012d4750 EDI : 0000000b EBP : 00000000
Oh, a second check, but since we patched the first one, now we get to this one.
.text:000C04F5 mov eax, [esi+14h] .text:000C04F8 cmp ebx, [eax+0E0h] .text:000C04FE jg short loc_C0513
This looks a bit different, but you can see how its similar, now its going to jump if the value of the attribute is greater then what we have (ebx - cost, [eax+0e0h] - our $$)
so
poke 000C04FE 90 poke 000C04FF 90
Now clear your breakpoint (bpc 0) and try out your new patch.. Yay it works!
Now for extra credit, attempt the same process with the unlock options =)
If you do go on to do that, remember there ARE multiple checks, and in odd spots I think there are 11 total checks, I always just nop'd the 'jl'
Hope this helps you out with non value searching usage of the debug tsr.. |