*********************************************************************************

                    ммммллмммммм
                     лВллллллн
                  пл лВлллллл лпп п
                   л лВлллллл л мммммм   nmls^bafh
             мммммм  лВлллллломмллллВлл         мммммм           мммммм
мммлпппплммлпп мм пп ллВлллллппппппппп      ммлпп мм ппплммм ммлпп мм ппплммм
  мммллммммммлллллллммопплллл лпппппппп  млпп ммлллллллммм пп мммлллллллммм ппп
А нллллллллнппллллВлллллопллл мммлппппплм ммлллпппллллллВлллопллпнпллллллВллм
А  лВлллллл А нллллллВлллолллол мммлллммммопВлнА ннлллллллВллолн А пллллллВлл А
БА лВлллллл ААнлллллллВллоллл Б нллллллВлллоВлоБА млллллллллпол ААБнллллллллн А
ББ лВВллллл БА лллллллВллоллл БВ лллллллВллнпллммммммммопо нмлл АБВ ммммммм  БА
ВБ ллВлллллоВБ лллллллВллолллоВВолллллллВллнонпппппллллллллмоплоВВ оллллллллм Б
ВВоллВлллллоВВолллллллВллолллоВомлллллВллллоВмоВВ ооллллллВллоВо ВомллллллВлл В
ВВоллллллллоВ олллллВллллоВллммллллллллпппомлллмммлллллллВллп ллмомллллллВллп В
В пппппллпп м пппппппппп мммммммм ппп мм ппппппплллллпппппп м ппплллллллппп ммм
ппппплммммлп ппппппппппппп      ппппппп пппппплмммммммлпппппппплмммммммммлппп

               Training Games on PCДs (Windows specific)
                   written by [NtSC] over/2001/2002

*********************************************************************************
Disclaimer:
-----------
If you request Nuke for People,when they release a Trainer with the same Options
you have,just delete this Tutorial,and kill yourself.It was in Case not written
for kiddie Morons wich make 50% of the todays Internet.

About me..
----------
 I am doing Trainers / Reverse Engineering of code since 1986...
 C-64,Amiga,SuperNES,GameBoy Advanced and Pc now..

 Began training Games on PC in January 2001

Tools I use to train:
---------------------
 - W32Dasm
 - SoftIce
 - GameHack v2.0
 - MagicTrainerCreator
 - BlindFind (my own Tool,for Alt-Tab protected Games..)
 - Icedump < for Mem-Dumps + Anti-Debugging Features >

Language I code in:
-------------------
 - No Masm,just Tasm.. (Borland Turbo Assembler v5.0)

Lets start our little Tutorial..

--------------------------------------------------------------------------------------- 

The Search:
-----------

(with SoftIce useable)

 - Fastest Way is to use a GameHack-Tool and search for the Option
   Adresses.When Adresses are found set an Breakpoint on Region with
   Softice. (Adress: 4df000 / bpr 4df000 4df001 w) this means...
   SoftIce will break up when a (w)rite Access appears to that 
   Adress.When SoftIce pops up,you should be at the Decrement for
   the Adress.

(SoftIce unuseable,due to GFX-Setup of Game)

-  Find Adresses with GameHack-Tool.Start W32Dasm and disassemble
   the Game.exe.Go to search Option and search for the Adress your
   GameHack-Tool provided.You should find Inits, or Decrements when it uses 
   static Memory Adresses. DMA Adressing would end in no Results (normally...)..!

W32Dasm Problems:
-----------------

- SomeTimes when you try to disassemble an Program with W32DASM
  you will not get any Code Line.This is done via an manipulation
  of the PE-Header Section Flags. The fucked up Flags look
  like: 400000C0 or 600000C0..you have to patch these Flags,in case
  you want to disassemble it correctly.With these Flags set,
  the .code Section is declared as an Data Section and W32Dasm
  will not disassemble them correctly.Change the Flags to: E0000020
  for most of the normal Sections,and just give the code section
  20000060 and try then...should work....if the Program is packed,
  W32Dasm will give no correct Informations anyway.YouДll have to
  depack it first.

  * Note:  Nowadays,for Shareware mangled Section Flags are 90% of 100 done
           through Pe-Crypters or Packers like for example Asprotect..
           In that Case you will have to find some Depacker for that
           Crypter/Packer used on that Program..
           Or just dump and rebuild...Can you?..

Alt-Tab Protections:
--------------------
Some Things i found through the Time are: 

  a) check the existing Windowname / WindowClasses / .exe Names of running Processes 
     for known GameHack-Tools.
     WindowName or WindowClass  = one of known GameHackTool = shutup Game
     Name of an running Process = one of known GameHackTool = shutup Game
     Solution                   = change WindowName / WindowClass/ .exe Name of your Tool

  b) Key Combination setup.
     Variants:
               ...Alt-Tab disabled
               ...no switch back to Game,after Alt-Tab
               ...if Alt-Tab pressed,quit Game

     See Examples for more Info on that....
    
  c) poor Game coding...the Game isnt able to restore the Screen after Task-Switching.
     At this time,you have only the Chance to use SoftIce-Plugins.

  d) Auto-Setback Game Window to Foreground-Window
     Check Actual ForeGroundWindow,if it is not the GameWindow,set GameWindow 
     back to actual ForeGroundWindow. 
     Done with a nice Timer,itll make the lil Trainerguys dizzy I think...

Alt-Tab-Protection-Examples:
----------------------------

Example from Game: The Smurfs,lets get loose
Dll: wkeykill.dll 
--------------------------------------------------------------------------------------

Header from wkeykill.dll / W32Dasm Output

+++++++++++++++++++ IMPORTED FUNCTIONS ++++++++++++++++++
Number of Imported Modules =    2 (decimal)

   Import Module 001: KERNEL32.dll
   Import Module 002: USER32.dll

+++++++++++++++++++ IMPORT MODULE DETAILS +++++++++++++++

   Import Module 001: KERNEL32.dll

 Addr:000020B0 hint(00FE) Name: GetModuleHandleA
 Addr:00002094 hint(0051) Name: DisableThreadLibraryCalls

   Import Module 002: USER32.dll

 Addr:000020D2 hint(00D7) Name: GetAsyncKeyState
 Addr:000020E6 hint(0011) Name: CallNextHookEx
 Addr:000020F8 hint(0248) Name: UnhookWindowsHookEx
 Addr:0000210E hint(0234) Name: SystemParametersInfoA
 Addr:00002126 hint(0225) Name: SetWindowsHookExA

+++++++++++++++++++ EXPORTED FUNCTIONS ++++++++++++++++++
Number of Exported Functions = 0001 (decimal)

 Addr:10001210 Ord:   1 (0001h) Name: Kill

+++++++++++++++++++ ASSEMBLY CODE LISTING ++++++++++++++++++
//********************** Start of Code in Object .text **************
Program Entry Point = 10001000 (wkeykill.dll File Offset:00001800)

This Nice dll kills just the Alt-Tab switching..
But no big Deal...

Number of Exports = 1, Function-Name: Kill ...uhhh..ph3aR!!!!

Load the Exe into W32Dasm...
Use StrnRef and look up WkeyKill.dll
You land here...

* Referenced by a CALL at Address:
|:0041509D   
|

* Possible StringData Ref from Data Obj ->"WKeyKill.dll"
                                  |
:00431E60 6820EB4C00              push 004CEB20

* Reference To: KERNEL32.LoadLibraryA, Ord:01C2h
                                  |

Obfuscatlly,when training and not using SOftIce-Plugins, we need to remove the Alt-Tab 
Protection... Notice that :Referenced by a CALL at Address:|:0041509D
Lets hook that one up.....

:00415094 A1D4CF6300              mov eax, dword ptr [0063CFD4]
:00415099 85C0                    test eax, eax
:0041509B 7405                    je 004150A2
:0041509D E8BECD0100              call 00431E60

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:0041509B(C)
|
:004150A2 FF05CCCF6300            inc dword ptr [0063CFCC]

Hmm... Loads an Dword-Adress into Eax,and tests..If Pointer Value = 0 WKeyKill,dll
will not be loaded..Fine..
So,no big Deal,..change the conditional Jump at Adess 41509b to an Jmp,and we are done..

:0041509B EB05                    jmp 004150A2  <-- Should look like this..

Fine,ready,go and Train...Alt-Tab switchable now...

--------------------------------------------------------------------------------------

GameHack-Tool-Protections:
--------------------------

- just checking for WindowNames,WindowClasses / active Processes of known GameHack-Tools.
  Means...Check...if Window "GameHackTool V1.0" is active,fake Adresses or
  Shutup...Solution = change GameHackTool-Title,same for WindowClass,Tool .exe Name... 

Option-Hint #1 (with SoftIce):
------------------------------

- lets say you find an Adress at d93200 wich offers the Lifes you have 
  in an Game.Set a Breakpoint on Region with SoftIce 

  bpr d80000 db0000 w  ; this means, SoftIce pops up when there is an 
                         (w)rite access to an Adress in the Area from
                         d80000 db0000..In case most Options are stored
                         in the same Area of Game-Memory, just loose 
                         something (Wepon-Shot,Energy...)..if SoftIce
                         pops up, you may have found a new Adress.
                         To search up the Decrement/Increment use the
                         Technic already descibed above.

Option-Hint #2 (with SoftIce):
------------------------------

- you need at least one Option-Adress..
  Set a Breakpoint on your found Adress..and press Escape or whatever to go back to
  Game-Menu..Start a new Game..Softice should in 70% of 100 cases popup at a nice 
  init-Routine where the Games sets up the Values,..Lives,Level,..whatever..
  Just write down the ADresses that are initialized,and check em Ingame..
  Set them to 0/1 or whatever,and check what the change Affects..

Advanced Training #1(without SofIce/GameHackTools):
---------------------------------------------------
- needed : some knowledge of Assembler Programming (Instructions)

- use W32Dasm to disassemble the Game (if protected read Section above)
  lets say you have 300 Minutes of Time in the Game,just look for an 
  Assembler Instruction that movДs the Hexadezimal-Value to an Memory
  Adress ( 300 dezimal = 012c hexadezimal)...write down MemoryAdress
  were Value is stored,or Adress of Instruction that movДs the Value.
  In most cases you should find only some Instructions/Adresses and 
  you can check them via Patching in the Code.Adresses outside the
  Memory can be checked via an Beta-Ingame-Key Tester.

-----------------------------------------------------------------------
Avoiding the Failure to take DMA as an direct Memory Adress:
------------------------------------------------------------
- DMA Memory is alloctacted by the Game..Its mostly used when the Game has an
  Save-Option,or either is big in Size..These Adresses change..That means,
  every time you start your Game, it normally has changed Adresses....
  If you just access the Dma-Adresses as direct ones,your Trainer prolly
  would not work..

Getting a useable Pointer to DMA-Adresses:
------------------------------------------
- Find at least one Option Adress..Just say Lives....
  Go on,and set a breakpoint on the Adress..
  Lose 1 Life,and our Numega Friend (SoftIce) should pop up...
  what do we see now??...

  Lets say...The Instruction on your actual EIP-3 is..
  dec [ecx+14] .. What does this tell us?
                  It prolly decrements from Memory Adress ecx+14...
  On easy Cases ecx just contains your DMA-Baseadress...
  fine...how do we find the actual store Adress of it??
  ecx = 02213567
  s 0 l ffffffff 67 35 21 02 <-- we search for that Adress in Memory
    |       |                    (Adress is BACKWARDS,notice that...)
    |       |___ EndAdress
    |___StartAdress (program Base-Adress,normally,400000,not ever..)     

  If SoftIce says: Pattern found at 0030:004bc4f6

  It will mean...the Pointer to your DMA is stored at Adress 4bc4f6 by the
  Program..

Example on How to access our found DMA-Adress:
----------------------------------------------
PAdress1     equ   004bc4f6h                        <-- the SoftIce ДPattern foundДone

call ReadProcessMemory,PHandle,PAdress1,edx,Byte4,0 <-- Read 4 Bytes (DMA-Base)
add dword ptr [edx],014h                            <-- Add Value to get to Option-Adress
                                                    (remember dec [ecx+14])
                                                                        |__= Value
mov dword ptr ecx,[edx]                 
mov [AdressStore],ecx                          
call ReadProcessMemory,PHandle,ecx,edx,Byte4,0      <-- Read our ДUpdateД Dma-Adress
                                                     (should contain Adress of Lives now) 
add dword ptr [edx],001h                            <-- Add one Life                             
mov ecx,[AdressStore]                               
call WriteProcessMemory,PHandle,ecx,edx,Byte4,0     <-- Store Updated Adress

Thats it..
No Mythos...Just a bit Experience..
It was an easy Example..there are also Games wich store an Adress over another Adress,
you would have to read out both Adress,before you can modify your one..

-------------------------------------------
No valueable DMA-Pointer found,what now?
-------------------------------------------
Lets say,you found an Memory Adress,for Example 1ab3d00.
It holds Money you have in the Game...: $1.000.000
You put a Memory-Breakpoint on it,bpm 1ab3d00.
Buy something,so hopefully SoftIce will pop up,since the Adress will get changed.
SoftIce pops up at: 4432a3: mov [ecx+14],edx
[Ecx+14] = Adress 1ab3d00 , and we have not found a valid Pointer to the DMA-
Adress to read it out in our Trainermenu. 
Edx holds the new Value to be inserted ($1.000.000 - what we bought...)
So,we do an Maximum Money Option for it...
How?..We just change the code before that mov [ecx+14],edx.
I guess a Subtract will be done,before the mov [ecx+14],edx.
Change the Subtract to: mov edx,$5f5e100 = maximum Money [$5f5e100 = 100.000.000]
Make sure the Instructions have the same Length,otherwise Nop out the obfuscating shit.
That means now...
Everytime the Game would normally Subtract our Money,
We fill up the Money Adress with maximum Value [$100.000.000]

--------------------------------------------------------------------------------------

-------------------------------------------------
Examples of Different-Routines,stolen from Games:
-------------------------------------------------

Example from: Pearl Harbor - Strike at Dawn German [Energy]
------------------------------------------------------------
Mainly, you can handle Energy Adresses like an Normal Value.
That means,..Energy = 05 Hex,wsprintf -> decimal -> Display -> Energy: 05
Most non Shareware-Games use other Display Methods like
for an Example a Bar that fades out, moving Display...
These Routines mostly have an look like the Routine below,
as they are mostly handled through float operations.

:004312FF D9442418                fld dword ptr [esp+18]
:00431303 D8642410                fsub dword ptr [esp+10]
:00431307 DEC9                    fmulp st(1), st(0)
:00431309 D8442410                fadd dword ptr [esp+10]
:0043130D D95C2418                fstp dword ptr [esp+18]         <-- Store float Adress

Example from: Sega Bass Fishing [Line]
---------------------------------------
* Referenced by a (U)nconditional or (C)onditional Jump at Addresses:
|:00478414(U), :00478421(C)
|
:0047842B D90560A77501            fld dword ptr [0175A760]
:00478431 D80D00064B00            fmul dword ptr [004B0600]
:00478437 D8C1                    fadd st(0), st(1)
:00478439 D80DF0034B00            fmul dword ptr [004B03F0]
:0047843F D91D60A77501            fstp dword ptr [0175A760]       <-- Store float Adress
:00478445 A160A77501              mov eax, dword ptr [0175A760]
:0047844A 50                      push eax

Example from: Sega Bass Fishing [Time]
---------------------------------------
:0045CA5B A148AD7501              mov eax, dword ptr [0175AD48]
:0045CA60 40                      inc eax
:0045CA61 83F83C                  cmp eax, 0000003C               <-- Time/Milliseconds
:0045CA64 A348AD7501              mov dword ptr [0175AD48], eax 
:0045CA69 7C77                    jl 0045CAE2                     <-- if not 60 go away
:0045CA6B A150AD7501              mov eax, dword ptr [0175AD50] 
:0045CA70 48                      dec eax                         <-- if 60 = dec Seconds
:0045CA71 A350AD7501              mov dword ptr [0175AD50], eax

Example from: Sega Marine Fishing [Time]
-----------------------------------------
:0044A6C6 F6C308                  test bl, 08
:0044A6C9 752F                    jne 0044A6FA                    <-- eb and go...				
:0044A6CB 8B0D680B6500            mov ecx, dword ptr [00650B68]
:0044A6D1 85C9                    test ecx, ecx
:0044A6D3 7408                    je 0044A6DD
:0044A6D5 D905E4C24C00            fld dword ptr [004CC2E4]

Example from: Sega Marine Fishing [Line]
-----------------------------------------
The tricky Part was here,the Line itself was splitted into 2 Counters.

:004ABC6C 890D04FE6400            mov dword ptr [0064FE04], ecx
:004ABC72 D91510FE6400            fst dword ptr [0064FE10]       <-- needs to be erased	
:004ABC78 7C06                    jl 004ABC80
:004ABC7A 893D04FE6400            mov dword ptr [0064FE04], edi

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:004ABC78(C)
|
:004ABC80 D91D14FE6400            fstp dword ptr [0064FE14]      <-- needs to be erased
:004ABC86 E895B4FCFF              call 00477120
:004ABC8B D90514FE6400            fld dword ptr [0064FE14]

Example from: Shark Hunting the Great White [Energy / shark_game.dll]
----------------------------------------------------------------------
:100124B4 8B86A0000000            mov eax, dword ptr [esi+000000A0]
:100124BA D986040F0000            fld dword ptr [esi+00000F04]
:100124C0 8B4830                  mov ecx, dword ptr [eax+30]
:100124C3 D986800F0000            fld dword ptr [esi+00000F80]
:100124C9 8B5034                  mov edx, dword ptr [eax+34]
:100124CC 894C2408                mov dword ptr [esp+08], ecx
:100124D0 8954240C                mov dword ptr [esp+0C], edx
:100124D4 DC4C2408                fmul qword ptr [esp+08]
:100124D8 DEE9                    fsubp st(1), st(0)
:100124DA D99E040F0000            fstp dword ptr [esi+00000F04]    <-- Store float Adress


Example from: Hunting Unlimited [Time / ho_game.dll]
-----------------------------------------------------
:100416A7 D944240C                fld dword ptr [esp+0C]
:100416AB D88608010000            fadd dword ptr [esi+00000108]
:100416B1 D99E08010000            fstp dword ptr [esi+00000108]
:100416B7 D98604010000            fld dword ptr [esi+00000104]
:100416BD D864240C                fsub dword ptr [esp+0C]
:100416C1 D95C240C                fstp dword ptr [esp+0C]
:100416C5 D944240C                fld dword ptr [esp+0C]
:100416C9 8B44240C                mov eax, dword ptr [esp+0C]
:100416CD D81D54990710            fcomp dword ptr [10079954]
:100416D3 898604010000            mov dword ptr [esi+00000104], eax <-- Store float Adress
:100416D9 DFE0                    fstsw ax

Example from: MegaMan Man Legends [MegaMan.exe / Energy]
---------------------------------------------------------
* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:004AD9CE(C)
|
:004AD9D9 668B516E                mov dx, word ptr [ecx+6E]        <-- Load Energy
:004AD9DD 6685D2                  test dx, dx                      <-- already zero, or - ?
:004AD9E0 7E1A                    jle 004AD9FC                     <-- if yes,bye..
:004AD9E2 89D0                    mov eax, edx                      
:004AD9E4 29D8                    sub eax, ebx                     <-- otherwise subtract
:004AD9E6 6689416E                mov word ptr [ecx+6E], ax        <-- and store new Value   
:004AD9EA 6685C0                  test ax, ax                      <-- Zero now?
:004AD9ED 7F15                    jg 004ADA04                      <-- if not,jump....
:004AD9EF 66C7416E0000            mov [ecx+6E], 0000               <-- otherwise clear up..
:004AD9F5 E88A8FF8FF              call 00436984
:004AD9FA EB08                    jmp 004ADA04

Example from: Autobahn Total - Die Verfolgungsjagd *German* - [Track Unlocker]
-------------------------------------------------------------------------------
* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:00419058(C)
|
:00419235 85DB                    test ebx, ebx
:00419237 7513                    jne 0041924C
:00419239 F744241000000100        test [esp+10], 00010000          <-- Track unlocked?            
:00419241 0F84EC050000            je 00419833                      <-- no,go away locked
:00419247 E9C8000000              jmp 00419314                     <-- yes,enable to click ;)

On this,we just change:
:00419239 F744241000000100        test [esp+10], 00010000          <-- Track unlocked? ==>
to
:00419239 C744241000000100        mov  [esp+10], 00010000          <-- Track always unlocked!

Ok,the Track will prolly not be enabled now...We need to kill the jmp at adress
00419241 too...I did it by writing EB04 to adress 00419241,this will insert a Jump
419247...but,you can also insert 6 Nops (6 x 90) to clear the instruction..
Main Idea is the same,writing my jump is 2 Bytes,noping is 6 Bytes...Choose
yourself...!

Example from: From Dusk till Dawn *GERMAN* - [Energy] / Code Fake
-----------------------------------------------------------------
:005119CB A804                    test al, 04
:005119CD 7409                    je 005119D8
:005119CF 5F                      pop edi
:005119D0 B801000000              mov eax, 00000001
:005119D5 5E                      pop esi
:005119D6 59                      pop ecx
:005119D7 C3                      ret

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:005119CD(C)
|
:005119D8 8B8FF74D0000            mov ecx, dword ptr [edi+00004DF7]
:005119DE 2BCA                    sub ecx, edx
:005119E0 898FF74D0000            mov dword ptr [edi+00004DF7], ecx

The Test al, 04 at Adress 5119CB checks for any Sprite Collision.
This can be an Enemy or You. We see the sub ecx,edx at Adress 5119de
but if we erase it, we AND our Enemies will also be invincible.
So,CHECK your Register when you enter the Sub-Routine at Adress
5119d8. If an Collision was detected Register ESI sets the Flag to
compare between us,and Enemy.We land at, an Collision that would
decrease our Energy would be Register ESI = 0.
What to do now?

:005119CB A804                    test al, 04
:005119CD 7409                    je 005119D8

We simply change that to:

:005119CB 85f6                    test esi, esi
:005119CD 7509                    jnz 005119D8

And thats it,...If a Collision on our Player is counted,well will simply
not conditional Branch to the Sub-Routine wich subtracts the Energy.
If its an enemy Collision <ESI not 0> it will still branch.

Example from: DownTown [Game Init] / Delphi-Game,High Adresses + Alt-Tab Protected
----------------------------------------------------------------------------------
:0049C262 C705A001EE05C8000000    mov dword ptr [05EE01A0], 000000C8
:0049C26C C705A401EE05C8000000    mov dword ptr [05EE01A4], 000000C8
:0049C276 C705A801EE05C8000000    mov dword ptr [05EE01A8], 000000C8

Ok,quick Step...000000C8 = Decimal 200,a Value I found in the Game.
I used W32Dasm and searched 00c8,initiated by a mov instruction.
[To land in the Game init]...Works..Alt-Tab would close the Game btw!

Example from: Dexters Laboratory: Science AinДt Fair [Energy]
--------------------------------------------------------------
:00417BFC 754F                    jne 00417C4D				<-- change to EB
:00417BFE D9460C                  fld dword ptr [esi+0C]
:00417C01 D82584494700            fsub dword ptr [00474984]
:00417C07 D9560C                  fst dword ptr [esi+0C]
:00417C0A D81D14454700            fcomp dword ptr [00474514]
:00417C10 DFE0                    fstsw ax
:00417C12 F6C401                  test ah, 01
:00417C15 0F84DB000000            je 00417CF6
:00417C1B 68DC050000              push 000005DC

Example from: Trade Empires *GERMAN* [Money]
---------------------------------------------
Original Code was:

0177:004B11CF  90                  NOP                                          
0177:004B11D0  55                  PUSH      EBP                                
0177:004B11D1  8BEC                MOV       EBP,ESP                            
0177:004B11D3  8B510C              MOV       EDX,[ECX+0C]           <-- Adress Money            
0177:004B11D6  8B4508              MOV       EAX,[EBP+08]           <-- Adress Inc/Decrease            
0177:004B11D9  03D0                ADD       EDX,EAX                

eax can here now be an -,or + Value. That means our add instruction
can add a Value,but if the Value eax is negative it can also sub a Value.
            
0177:004B11DB  89510C              MOV       [ECX+0C],EDX           <-- Store new Money            
0177:004B11DE  5D                  POP       EBP                                
0177:004B11DF  C20400              RET       0004                               
0177:004B11E2  90                  NOP                                          

The Code i came up with for my Trainer:

0177:004B11D0  55                  PUSH      EBP                                
0177:004B11D1  8BEC                MOV       EBP,ESP                            
0177:004B11D3  8B4508              MOV       EAX,[EBP+08]           <-- Get Inc/Decrease                      
0177:004B11D6  85C0                TEST      EAX,EAX                <-- is it 0?             
0177:004B11D8  7E04                JLE       004B11DE               <-- or a - Value?            
0177:004B11DA  01410C              ADD       [ECX+0C],EAX           <-- if not,let it add            
0177:004B11DD  90                  NOP                                          
0177:004B11DE  5D                  POP       EBP                                
0177:004B11DF  C20400              RET       0004                               

--------------------------------------------------------------------------------------
         
Hints on Values:
----------------

Options search:
---------------

Suche Wert: 5 -------->
            5
            4/-1  
            6/+1

Unlock:
-----------
Gamestart:  0 -------->
            1
            not equal
             
Cars/Tracks:
-------------
Gamestart:  0 -------->
            1
            not equal
            Datafields /1/ne

Invincible:
-------------
Gamestart:  0 --------> Flicker Timer
            greater than
            less than
            equal

General Unlocking:
--------------------
Manipulate the Game, for example racing Games to always be first.
Play the Game,until a new Car/Track is unlocked and examine the
Changes.

Invincibility:
**************
- first 0
  After a Collision some Timer gets initialized,wich is counted down afterwards.

Level-Skip:
***********                
 - most Games offer an defined Ammount of Items to get/destroy
   (Example: 40 Items to destroy/Zero the Byte,and Level is skipped)

Timers:
*******
 - can be stored as 2 Bytes (0801)  

Lives:
******
 - can be stored -1 (Display says 5 / 4 in Memory)
 - can be stored as obfuscating Values 3/3 (use MemChange-Trainertool)
    
Weapons (Selector):
*******************
 - there is mostly an Range of compares to the Adress
   0001,0002,0003.....use W32Dasm to find multiple Adress compares

Cheat-Mode enable:
******************
 - use W32Dasm to check for CheatMode-Text. If found, a CheatMode
   is often made through a Password typed in.Patch the Password-Routine
   to always enable/disable Cheat.Use a Memory-Compare-Tool to find the Byte wich
   is set to enable/disable CheatMode.

Difficult Values:
-----------------
 - Hard to find Timers / Level-Skip-Value Adresses can best be found
   with an GameHack-Tool that has an ДMemchangeД-Option like ДMTCД

***********************************************************************

Error-Fixing on Trainer-Programming:
-------------------------------------
This is an OpenProcess-Routine wich enables you to read and write to the
specified Game.The Flags are w9x/me + w2k tested.

 	call	GetWindowThreadProcessId,eax,offset Pid		

	call    OpenProcess,PROCESS_VM_READ OR PROCESS_VM_WRITE OR PROCESS_VM_OPERATION,0,Pid
	mov	 PHandle,eax
      cmp     eax,0
      jz      Error

Avoid to do ReadProcessMemory into Registers!
----------------------------------------------
Under W9x/me it worked well,but w2k messed it up..
So,this is how it should look like < Example => Check that Toggle1 >

      call   ReadProcessMemory,PHandle,0077e7a0h,offset Toggle1,Byte4,0
      add	[Toggle1],064h
      call	WriteProcessMemory,PHandle,0077e7a0h,offset Toggle1,Byte4,0

***********************************************************************

For any Contact or Exchange of Stuff: Trainerdude@hotmail.com