Jump to content




Welcome to dEViATED. We provide game trainers, cheats and gamehacking tutorials and a gamehacking forum for discussions and help. We have pc game trainers for various old and new games to download and will expand to other platforms. Go ahead and have a look around, you will love our pc trainers!.

Not interested in trainers ? socialize with us, we talk about girls, booze, movies, music and basically anything and everything.


These are some of the latest trainers released by us and supported fully.
Alien Isolation Trainer
Wolfenstein The New Order Trainer

Photo

Codeshifting - Intro - Techniques - Solution


  • Please log in to reply
6 replies to this topic

#1 STN

STN

    Founder

  • The G-Man
  • 5,715 posts

Posted 12 January 2011 - 06:29 PM


Code Shifting

Author: spookie

Written: Saturday 11th Nov, 2003
--------------------------------
Revised: Thursday 8th July, 2004
--------------------------------
Subject: Code Shifting
----------------------
Author: spookie
---------------

CodeShifting happens simply when a DLL is dynamically loaded with LoadLibrary() by the game,
and inside this DLL is the game code that you need to edit. This is becoming more and
more common these days because of the amount of games coming out based on generic engines.
To name a few, Max Payne 2, Splinter Cell, Tron 2.0 and Counter-Strike: Condition Zero.
Out of these four chart topping games, only two working trainers were released. There was
an additional obstacle with Tron 2.0, being based on the Lithtech engine, as not only is the
game code in a dynamically loaded dll, it drops this dll in the temp files with a random
name before loading.

Now, to get around this problem we've got to find the address at which our game code dll
has been loaded, and with the help of the ToolHelp32 APIs it's not a hard task. First of
all, you need to know what dll your code is inside...

So for example lets say our cheat address is 008C3627 - We need to find a dll in the
currently running target game that's loaded at an address lower than 008C3627, but with an
image size of more than 008C3627. If you have LordPE handy (http://protools.cjb.net/) you
can get a list of loaded dlls and their base address and image size by selecting the game
process in the upper list and the dlls will then be displayed in the lower list. Or, you
could use a small tool, codeloc, I created for this, available at http://spookie.rom.cd/.
codeloc takes 2 parameters, the first is the game window text or the game window class
name, the second is your cheat location. e.g...

--------------------------------------------------------------------------------code---
codeloc "MaxPayne2" 8C3627

...will result as...

<008C3627> is inside module "X_GameObjectsMFC.dll" with base address <008B0000>
-------------------------------------------------------------------------------/code---

Now we know what dll we're working inside, we have to offset our given cheat address by
the current base address. Given the above example, my cheat address was 8C3627, and the dll
that contains it was loaded at 008B0000, so our cheat address offset would be 13627...

Cheat Address - Base Address = Cheat Offset
8C3627 - 8B0000 = 13627

So now we have our new cheat address we have to get the base address of the dll within our
trainer at runtime. To do this we'll use the ToolHelp32 APIs to cycle through all the
loaded "Modules" of the target game until we find ours.

Here is the code to do so in Delphi...

--------------------------------------------------------------------------------code---
uses TlHelp32;

function GetModuleBaseAddress(iProcId: Cardinal; DLLName: String): Cardinal;
var
hSnap: THandle; // Process snapshot handle.
xModule: ModuleEntry32; // Module information structure.
begin
Result:= 0; // If the result of the function is 0, it didn't find the base address.
// i.e.. the dll isn't loaded.
hSnap:= CreateToolHelp32Snapshot(TH32CS_SNAPMODULE, iProcId); // Creates a module
// snapshot of the
// game process.
xModule.dwSize:= SizeOf(xModule); // Needed for Module32First/Next to work.
If Module32First(hSnap, xModule) Then Begin // Gets the first module.
While Module32Next(hSnap, xModule) Do // Loops through the rest of the modules.
If xModule.szModule = DLLName Then // If this is the module we want...
Result:= Cardinal(xModule.modBaseAddr); // Save the base address it in result.
End;
CloseHandle(hSnap); // Free the handle.
end;
-------------------------------------------------------------------------------/code---

...and here is the same thing in C...

--------------------------------------------------------------------------------code---
#include <TlHelp32.h>

DWORD GetModuleBaseAddress(DWORD iProcId, char* DLLName)
{
HANDLE hSnap; // Process snapshot handle.
MODULEENTRY32 xModule; // Module information structure.

hSnap = CreateToolhelp32Snapshot(TH32CS_SNAPMODULE, iProcId); // Creates a module
// snapshot of the
// game process.
xModule.dwSize = sizeof(MODULEENTRY32); // Needed for Module32First/Next to work.
if (Module32First(hSnap, &xModule)) // Gets the first module.
{
while (Module32Next(hSnap, &xModule)) // Loops through the rest of the modules.
{
if (strcmp(xModule.szModule, DLLName) == 0) // If this is the module we want...
{
CloseHandle(hSnap); // Free the handle.
return (DWORD)xModule.modBaseAddr; // return the base address.
}
}
}
CloseHandle(hSnap); // Free the handle.
return 0; // If the result of the function is 0, it didn't find the base address.
// i.e.. the dll isn't loaded.
}
-------------------------------------------------------------------------------/code---

...and finally in masm...

--------------------------------------------------------------------------------code---
GetModuleBaseAddress proc iProcID:DWORD, DLLName:DWORD
LOCAL hSnap:DWORD
LOCAL xModule:MODULEENTRY32
invoke CreateToolhelp32Snapshot, TH32CS_SNAPMODULE, iProcID
mov hSnap,eax
mov xModule.dwSize, sizeof xModule
invoke Module32First, hSnap, addr xModule
test eax, eax
jnz getdll
mov eax, 0
ret
getdll:
invoke Module32Next, hSnap, addr xModule
test eax, eax
jnz checkdll
mov eax, 0
ret
checkdll:
invoke lstrcmpi, DLLName, addr xModule.szModule
test eax, eax
jnz getdll
mov eax, xModule.modBaseAddr
ret
GetModuleBaseAddress endp
-------------------------------------------------------------------------------/code---

These functions require the ProcessID of the game (GetWindowThreadProcessID()), and the
name of the dll you want the base address of. I've learnt the hard way that you should
use this function before doing any injection, not when the game has first started,
because some games like to reload the game dlls when you change level (Counter-Strike: CZ)

In the end, the lpBaseAddress parameter you will send to WriteProcessMemory will be...

--------------------------------------------------------------------------------code---
GetModuleBaseAddress(GAME_PROCESS_ID, "X_GameObjectsMFC.dll") + 0x13627
-------------------------------------------------------------------------------/code---

Any problems just email me at: [email protected]

- spookie

#2 satanclaus

satanclaus

    Getting Tamed

  • Full Members
  • PipPip
  • 18 posts

Posted 19 March 2012 - 05:57 PM

I hate being the noob that bumps up an over-a-year-old-topic but that's why my post needs approval right? :D

This is a genius method, why is it not famous? What I've been learning is finding pointers to eventually crawl my way to a static address, but that is one hell of a pain in the ass especially when you've got 3-4 level pointers!

Then let's say an update comes out and all your pointers become junk, you gotta go to the beginning and find all your pointers for every hack.

I'm about to put this method to practice, cheat engine's disassembler actually shows you all the modules loaded within a game if you go to:
View ---> Show module names
And then turn off
View ---> show symbols
Your addresses will now indicate the module name+offset

That even allows you to view the base address at which the module was loaded that particular time by
right click ---> go to address
and symply typing out your "ModuleName.dll"
then you symply turn off
view ---> show module names

That's a completely useless practice though, simply there to quench your curiosity. You can do it mathematically too by subtracting the offset from your hack address (duh)

Anyway here it goes, making another trainer using this method, fuck pointers

#3 satanclaus

satanclaus

    Getting Tamed

  • Full Members
  • PipPip
  • 18 posts

Posted 19 March 2012 - 08:35 PM

Hmmm interesting. Interesting, interesting, interesting.

Does lpBaseAddress, second parameter of WriteProcessMemory() need to be in hexadecimal?

Edited by satanclaus, 19 March 2012 - 08:35 PM.


#4 emptieness

emptieness

    Rookie

  • n00b
  • PipPipPipPip
  • 80 posts

Posted 20 March 2012 - 12:15 PM

Yep. Write it in masm like 0040000h.

#5 satanclaus

satanclaus

    Getting Tamed

  • Full Members
  • PipPip
  • 18 posts

Posted 20 March 2012 - 05:27 PM

Thnx emptieness.
I'm writing this in C++, failed to mention that.

My GetModuleBase() function that I wrote:
DWORD GetModuleBase(LPSTR lpModuleName, DWORD procId)
{
   MODULEENTRY32 lpModuleEntry = {0};
   HANDLE hSnapShot = CreateToolhelp32Snapshot( TH32CS_SNAPMODULE, procId );
   if(!hSnapShot)
	  return NULL;
   lpModuleEntry.dwSize = sizeof(lpModuleEntry);
   BOOL bModule = Module32First( hSnapShot, &lpModuleEntry );
   while(bModule)
   {
	  if(!strcmp( lpModuleEntry.szModule, lpModuleName ) )
	  {
		 CloseHandle( hSnapShot );
		 return (DWORD)lpModuleEntry.modBaseAddr;
	  }
	  bModule = Module32Next( hSnapShot, &lpModuleEntry );
   }
   CloseHandle( hSnapShot );
   return NULL;
}

Returns the correct base address but in decimal notation (I think unsigned long?)
For example it would return:
9036112
which, when converted to hex, would be:
8E0000
and that would be the correct base address of my module (that particular time the game is launched)

WriteProcessMemory() does not detect a problem with that, and returns true after it's executed
However, the end result is that the value at the memory address that I'm writing to (base+offset) remains unchanged, I checked the assembly code myself after running my trainer.

Bottom line is:
I need to convert the unsigned long value returned by my GetModuleBase() function:
9036112
To hexadecimal notation before I send it to the lpBaseAddress parameter of WriteProcessMemory():
0x8E0000

Anyone have any tips on how to achieve this?

Edited by satanclaus, 20 March 2012 - 05:32 PM.


#6 emptieness

emptieness

    Rookie

  • n00b
  • PipPipPipPip
  • 80 posts

Posted 21 March 2012 - 10:45 AM

Your GetModuleBase function returns a dword value. So you need to convert nothing. My function looks similiar to yours and is working perfectly.
Just declare a dword value to store the base address. Then add the offset (dword 0xoffset) to it and you should have the correct address. Don't forget that you have to declare your offsets with a 0x standing before the actual address.

DWORD dwBaseAddress, dwOffset;
DWORD dwRealAddress;
dwBaseAddress = GetModuleBase(szModuleName, ProcID);

dwOffset = 0x400000;

dwRealAddress = dwBaseAddres + dwOffset;
Then call WPM.

#7 satanclaus

satanclaus

    Getting Tamed

  • Full Members
  • PipPip
  • 18 posts

Posted 21 March 2012 - 03:18 PM

Yeah I quickly realized I don't need to convert anything, unfortunately I couldn't edit my post.

Everything I had was all correct from the beginning, WPM just wasn't doing its thing.
It's a bummer that I'm at work right now but I just remembered what I'm missing from my trainer, and that's VirtualProtect( ). I'm quite certain that everything will work out as soon as I get back to my source and call VirtualProtect( ) on my addy.



Official Trainer Hosters:  
Affiliates:
 

Like our work ? Why not follow us on deviatedhacking youtube facebook page deviated twitter +deviatedhacking page