Go Back   FileForums > Games > Game Coders
Register FAQ Community Calendar Today's Posts Search

 
 
Thread Tools Search this Thread Display Modes
Prev Previous Post   Next Post Next
  #1  
Old 15-04-2007, 19:00
کunβeam کunβeam is offline
Banned
 
Join Date: Apr 2007
Location: Romania
Posts: 18
Thanks: 0
Thanked 0 Times in 0 Posts
کunβeam is on a distinguished road
Cool Infernal - Trainer & Gadgets

Starting with a basic trainer, and evolving/expanding the project in time once I discover more. I'll keep a diary of what I did, so others benefit from this experience. Also, adding some stuff I discovered while analyzing the game or its files. Hope this board allows constant editing of same post (I'd hate to double/triple post)

First off, let me say that I've tested all the trainers available for this game and all of them have only one option available (Unlimited ammo), and even so, that option is global (works for both player and enemy). Well, if they also had god mode, it wouldn't have been a pain in the ass to have enemies with Uzis shooting constantly on your ass

Therefore, I've been trying to conceive an ammo feature for the last few hours, and since I couldn't find a base pointer for my player (it shifts like mad, even though the game doesn't use code-shifting), I decided to call in for ingenuity and use another method :X Kinda g4y, but it works pretty nice.

Let me show you what I'm talking about...


[ Diary log #1 ]


Both the enemy and I are using the same function, located here :



That's the code that would normally appear amongst others in your debugger window, when you're trying to see what writes to your ammo address.
Quote:
sub [eax+538], ecx

// eax = player ammo pointer
// 538 = weapon slot offset
// ecx = the amount deducted from your weapon's ammo
All nice and fine till here. If you nop that sub, both you and your enemies will have unlimited ammo. That's what all the trainers available on gamecopyworld (haven't checked if CH has one - sheep might beat the crap out of this game) do...

We want it one sided, and for that, also taking into account that I wasn't able to find a base pointer for the weapon pointer, I used something else. Noticed this :



Interesting - "enemy" - that word appears whenever the enemy uses that sub. Problem is the syntax is not always in the same manner. For instance, the pistol will always be "Enemy-pistol-ammo-..." while testing for Uzi, I saw "UZI-ammo-enemy-..."

In case you don't follow so far, I'll use word comparing So far - I'm at level 3, where you have to gain access in a cathedral by blowing its walls, right after Doctor Wolf flies out in a chopper - I haven't encountered a weapon to have the letter y in its description, therefore, the script - I hope you have Cheat Engine 5.3 installed !
Quote:
[ENABLE]

alloc(cave,256)
label(back)
label(loop)
label(out)
label(enemy)

//9B8140:
cave:
pushad
loop:
mov bl, [eax+14]
cmp bl, 79
je enemy
cmp bl, 0
je out
inc eax
jmp loop
out:
popad
jmp back
enemy:
popad
sub [eax+538],ecx
jmp back

5CC158:
jmp cave
nop
back:

[DISABLE]

5CC158:
sub [eax+538],ecx

dealloc(cave)
Time to explain what it actually does, and I'm going to sparse it in pieces, so you get the whole idea :

---
[ENABLE]/[DISABLE]

This is common CE syntax, pretty much and quite similar to ON/OFF. What's below the [ENABLE] tag will work as enabling the cheat/turning on the feature. The script will perform, once assigned to your cheat table, what ever is written below the [ENABLE] tag. How far ? Till the [DISABLE] tag. Same thing goes for [DISABLE]. What ever's under it will be written once you deactivate the script (tick/untick in your table). [DISABLE] works as "restore all" feature, except it restores only what you assign under it.
---
alloc(cave,256)

CE allows users to allocate memory of different sizes, which is pretty easy to work with, removing the worry to have to find an empty cave to write your code in. The syntax is as follows : alloc(name,size)
---
label(back)
label(loop)
label(out)
label(enemy)


The use of labels is also possible. Using labels you can set "waypoints" in your code to work faster and easier. Syntax : label(name) - note that numbers aren't supported in any name.
---
dealloc(cave)

The memory you allocate can be easily deallocated. It's also useful to use this code at the end of your script, since the allocated address will always be the same. If you don't use it, CE will keep allocating different addresses to your cave.
---
[DISABLE]

5CC158:
sub [eax+538],ecx

dealloc(cave)


This is the original code, and that's what CE will write when I disable the option. It's the equivalent for a "turn off the cheat" option.
---

Now to the main "plot" :

cave:
pushad
loop:
mov bl, [eax+14]
cmp bl, 79
je enemy
cmp bl, 0
je out
inc eax
jmp loop
out:
popad
jmp back
enemy:
popad
sub [eax+538],ecx
jmp back

5CC158:
jmp cave
nop
back:


What will the code do is to copy the string I mentioned earlier (Enemy-pistol-ammo-standard-8237) letter by letter and move it in a register, then compare it against the letter y. If that letter is encountered when scanning the string, perform normal code. If not, skip the sub [eax+538],ecx instruction. If the sub is skipped, we don't get anything deducted from out ammo, therefore one-sided unlimited ammo...

---
cave:

That is the address I've allocated at the beginning. The syntax for writing to it is : name: Basically, you tell CE to write at address "name", in my case at address "cave"
---
pushad

Saving the state of the registers, since we'll perform operations and use them. It's always nice to save the state, as the game might crash if one of the registers you use is overwritten.
---
loop:

This is the first label I declared. Labels can be used as addresses, or part of a code. In this case, "loop" will be an address located immediately below the "pushad". You'll see how the full code looks like in the end.
---
mov bl, [eax+14]
cmp bl, 79
je enemy


I chose to work with ebx, and since I'm operating with letters (bytes), I'll use the lower part of ebx (32b), which is bx (16b) and can be sparsed in 2 (bl, bh - both on 8b). 'l' for lower, 'h' for higher. The text string you saw in the 2nd picture is located at eax+14. The pointer is eax, eax+14 is the address holding the string. So - move in bl the first byte found at address eax+14 -> mov bl, [eax+14].

Further on, on the 2nd line, we compare bl with 79 (letter "y" in hexa). If they match (if y is found within the string), jump to label "enemy", where the game will allow their ammo to decrease
---
cmp bl, 0
je out
inc eax
jmp loop


If bl is not 79, compare it against 0. In case you haven't noticed, we only need to compare the string and stop after it. Or we'll hit an endless loop, and game will freeze. So, the cmp I added will check if the whole string has been "scanned" and stop at first 0 that's encountered. If bl is 0, jump to label "out", where the game executes a code that misses the "sub", therefore we don't get any ammo deducted. If bl is not 0, increase our pointer to move on to the next spot, and return to label "loop" to go through the function again, till the whole string is read.
---
out:
popad
jmp back
enemy:
popad
sub [eax+538],ecx
jmp back


Label "out" defines another address in the cave, at which we land from the jump mentioned above. We use "popad" to restore the state of the registers and allow the game to get back in "flow" Once the code is used, we jump back to address "back" (you'll see below)

The other label does the same thing, except it does it for the case in which the letter "y" is found in the string.
---
5CC158:
jmp cave
nop
back:


Our original address 5CC158: at which we write what's below it. The original code has 6 bytes (count them in the 2nd pic). A jmp uses only 5 bytes, so we'll use a nop to even out the code. 5+1=6. As I said above, once the out/enemy labels are used, at the end of each other you see "jmp back". Well, if you look at the code, I used in the function "back:" which defines an address located below the "nop". Therefore, "jmp back" means - jump to the address located below that nop. Since the sub had 6 bytes, "jmp back" means jump to 5CC158+6. Hope it's clear...
---

Phew. Long article. Once you copy the script, open up Memory View, press Ctrl+A and paste it the auto-assembler window. From the top menu (in that window), choose "Assign to table". Then check you table. You'll see what I meant with ON/OFF Ticking the checkbox in front of the script means ON/ENABLE. Unticking it equals OFF/DISABLE.

Time to show you how it all looks like :



Hope now it's understood.

Last edited by کunβeam; 15-04-2007 at 20:15.
Sponsored Links
 


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

Similar Threads
Thread Thread Starter Forum Replies Last Post
Rainbow Six Vegas v1.04 Trainer Doesn't work mfw41 Game Trainers 7 30-03-2007 22:13
The best (and fun) NFS:Carbon trainer available intoksicated General Gaming 3 22-12-2006 04:55
Gothic 2 Trainer prb Dark3lement General Gaming 3 17-08-2006 15:50



All times are GMT -7. The time now is 15:08.


Powered by vBulletin® Version 3.8.11
Copyright ©2000 - 2026, vBulletin Solutions Inc.
FileForums @ https://fileforums.com