• 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
Tutorial Signature // Pattern scanning
dEViATED/KEMiCZA crack cocaine...
Signature scanning: a better solution

x.x) Requirements
Before you attempt to read this tutorial I suggest that you at least have a good understanding of some subjects related
to gamehacking. I'm not saying you should't read it, but some parts might be hard to understand if you lack basic knowledge.
This is what is required & recommended:

- Programming, code injection, assembly, DLL injection, basic windows API's(msdn).
- 'How to update your trainers real quick and easy' by STN (tutorial)

1.0) Introduction
One day I was working on a small trainer for Supreme Commander 2. Before I wanted to release it I saw an update had been
released, and I didn't mind much and instantly applied the patch and made a new trainer for that version. A few days after
the release another patch came out, and some people requested an update for the trainer. I thought to myself: well okay, I
guess I can do it quickly. But this time I didn't bother using a memory searcher. I just used ollydbg to find a "sequence
of commands", which I had from the previous update. And luckily it did find the address that matched with the assembly
instructions. So I just changed the addresses in my source code (the caves were still the same), and the trainer would work.

As you can guess a few days/weeks later another update came out, and I started thinking if I could come up with a method that
could automatically search for the "sequence of commands", which were rather "sequence of bytes", just like ollydbg does. The
only data necessary would be a sequence of a certain amount of bytes that relate to the assembly instructions at a location in
games memory. I just thought of the idea, but I'm not even sure if I released a trainer for that particular patch. I started
thinking about how I could implement it and maybe after a few weeks I got a basic template that could do exactly this. Over
the time I've updated the engine a lot of times, fixed small bugs etc, but these were more related to the control of hotkeys
and visuals than the actual scanning engine. After this, the method has been applied to other games by fellow dEViATED members
and by myself with only positive feedback from trainer users.

Infact I almost forgot to say that I have used this method before this game actually. And that was to patch the xlive memory
checking. Since there were updates getting released for xlive, you couldn't guarantee that the address would always be the same.

What you can expect from this tutorial is that I'll show you the basics and perhaps even some more advanced tips and
technique's to help you on the way. I'll add some source code as well to help you understand.

1.1) Advantages & Disadvantages
There's a couple of good reasons why I prefer this method rather than the traditional static address patching. The first
one is that there's no difference in speed if you design your signature scanning properly. So enabling a trainer would happen
in less than a second. The second reason why you want to use signature scanning is because your trainer will not only
work on different updated game versions, but might also work on different versions of the game like cracked,retail,steam,etc
A disadvantage is that it DOES NOT always work, and you can't guarantee your trainer users that it will work 100% of all the
options within your trainer. But this can be solved by applying a good method of reverse engineering, and not using random
values to for example distinguish player from enemy, but rather going deeper outside the calls and trying to find some kind
of structure that selects players. This is atleast what I did for Supreme Commander 2. And since then I haven't had any
comlaints regarding the trainer not working, even though there's still patches being released. Saved me a lot of time. And
this should be a reason enough to use this method. If it works you'll save time, if it doesn't then you lose NOTHING, because
your trainer will still work for the version it was released for.

1.2) Signature patterns
You should recall that I talked about the sequence of commands and bytes. In essence all instructions are made out of a
sequence of bytes (or one byte), which is the smallest 'packet'of memory that can be controled directly by your system.
This still aplies if you have more than one instruction, that will still only be a certain sequence of bytes. An example:

PHP Code:
004790E9   0306             ADD EAX,DWORD PTR DS:[ESI]
004790EB   8956 FC          MOV DWORD PTR DS:[ESI-4],EDX
          004790EE   8A10             MOV DL
The first column is the address location, second is the instruction at byte level and the third is the actual instruction on
a readable level, the assembly level. The traditional way of creating a code injection would be based on the address(es), but
in our case we'll be using the instructions themself from the byte level to find the address. How many bytes we actually need
depends on your choice. I've developed a tool that will scan a given pattern in the given module of a process and will return
the address where it was found. If your address does not match, then that means that the sequence of bytes are NOT unique, and
you need to take some more bytes. You can also scan this with ollydbg. A signature pattern is a unique byte pattern that will
be used in your trainer engine to find a match within the games code. When it finds the match you'll have found your address.
From this point you can inject and create a code cave if necessary.

A little addition to this matter is that your signature doesn't have to start with the first byte of a certain instruction.
Let's say your signature was "06 89 56 FC 8A 10" instead of "03 06 89 56 FC 8A 10", your engine will still be able to find
the address which will be 4790EA(4790E9+1). But you will need to compensate this with a shift operation which will add the
shifted amount. In this case it would be -1, because your engine will return 4790EA as the found address, and if you add a
-1 to it, you'll get your correct address.

2.0) Programming the engine
In this chapter I'll try to explain how you can program and implement this in your own trainer engine. But before we can begin
we need a design on how to do it. There's two possible ways that I know of, because I've used them both. The first one is you
can use ReadProcessMemory(RPM) and WriteProcessMemory(WPM) API. RPM will be used to read the byte from the games code and then
use that to compare it with your signature. If the byte doesn't match, then read the next one, etc If eventually a byte matches
then you need to compare the second byte from your signature with the next byte in the games code. Repeat this loop until you're
at the end of your signature's length. The length can be a parameter that's given to the function. Eventually you can use WPM
to create a jump to the cave. This is probably the worst method you can use, because you'll be calling RPM so many times that it
might take a few minutes before the scanning is done. A better alternative is to use RPM only once, and copying the complete
module in a buffer within your trainer. Then use this buffer as a mirror to the actual games code. This will be significantly
faster, and the process won't take more than a few seconds. But there's even a better method and this is to use a DLL. And
this is the method I personally recommend you use, because after injection of the dll you'll have control over the process
and thus using RPM or WPM is out of the picture. Another advantage is that you can write your assembly code caves within
your DLL, and use local flags. This eliminates the search for empty caves in a games location or allocation of memory
within the game for code caves. Do note that writing direct assembly is not supported in all programming language's. This is
why I use mASM to code my trainers. C/C++ also have inline assembly support. For other language's it's still possible if you
convert your instructions into bytes and would use that as your cave.

2.1) Finding the address
These are the functions you can use to build your engine:

a) ComparePattern(pat1,pat2,length)
pat1 and pat2 are pointers to the data of the patterns to be compared. One is the one you're looking for and the other
one is the currently loaded one from the game. This function returns TRUE if there's a match, else a FALSE.

PHP Code:
ComparePattern PROC Pat1:DWORDPat2:DWORDLength:DWORD
                        mov ecx
                        mov edx
                        mov esi
xor eax,eax
.while eax esi
                            mov bl
byte ptr [ecx+eax]
cmp byte ptr [edx+eax],bl
inc eax
                         mov eax
xor eax,eax
                 ComparePattern ENDP 

b) SearchPattern(SigData,Length,ModuleName,ShiftAddr)
This function will scan the whole module looking for the signature, which is the first parameter SigData. The second
is the length of the sig data, the third is the ModuleName for example "Game.exe", and the last is an optional shift address
parameter that was explained in section 1.2. If this function succeeds then it returns the address that matched with the
given signature pattern. If it fails it returns 0.

PHP Code:
SearchPattern PROC SigData:DWORDLength:DWORDModuleName:DWORDShiftAddr:DWORD
                  LOCAL RetAddr
                  LOCAL ModSize
                  LOCAL BeginAddr
                        invoke GetModuleHandle
,ModuleName              ;get the base addr of the module
                        mov BeginAddr
                        invoke GetModuleBaseSize
,ModuleName            ;get the size of the module
                        mov ModSize
                        mov ecx
,BeginAddr                              ;ecx is our beginning address
                        mov edx
,Length                                 ;edx is the length of the data
                        mov ebx
                        add ebx
                        mov ModSize
,ebx                                ;calculate end, final address
.while ecx ModSize
                            mov BeginAddr
                            push ecx
                            invoke ComparePattern
                            cmp eax
pop ecx
                            inc ecx
xor eax,eax
pop ecx
                        mov BeginAddr
                        mov eax
                        add eax
                 SearchPattern ENDP 

Note that I didn't supply the functions for getting the base address nor the size of the module. I'll leave that up to you.

These are the most important functions. This is the core of your signature scanner, because this is the part that does all the
searching and comparing.

2.2) Creating the jumps
Since we're using an injected DLL you could just as well use calls instead of jumps to execute your injection. But in this tutorial
we'll be using jumps. After you've found an address you want to do something with it. For trainer makers the found address will mainly
be used to create a jump to a code cave where other code is located that changes the way the game works. Luckily for us we don't need
to find an empty spot in the game, because we already have our own filled spot in the dll. There's 4 things we need (in order):

1) Address to jump from (game->cave)
2) Address to jump back (cave->game)
3) A jump from the cave
4) A jump to the cave

We first create a jump from the cave, because there's a super small chance that in between the time we create a jump to the cave and
the jump back to the game, the second jump won't be written yet.
The way you calculate the jump is as follows: Address To - Address From. This is the relative value we need to implement in the
instruction. Here's an example:

PHP Code:
mov ecx,AddressTo
                 mov edx
                 sub ecx

The register ecx will now hold our relative value. To implement this in a jmp instructions we need to do a little more:

PHP Code:
mov ebx,ecx
                 shr ebx
                 mov eax
,offset hE9
                 mov byte ptr 
[eax+1],cl     ;We store our jump hex codes into a buffer which we will use as a pointer to inject
                 mov byte ptr 
                 mov byte ptr 
                 mov byte ptr 

We copy the value of ecx to ebx. We shift ebx 16 bits to the right, which is 2 bytes. We all know a jump instruction start with
the hex value of 0E9h. The weird thing is that the values are stored in reversed order in a register. So we'll save cl which is the
lower byte of ecx. Then we save ch which is the higher byte of ecx. And we have two more left, which are actually stored in the two
lower bytes of ebx since we shifted the bits. Those are again stored in the same way. We now have our data to be injected and you can
use a simple WriteMem function to inject it:

PHP Code:
WriteMem PROC Address:DWORD,Data:DWORD,Length:DWORD
                        invoke VirtualProtect
,Address,Lenght,PAGE_EXECUTE_READWRITE,offset dProtect
                        cmp eax
                       invoke RtlMoveMemory
                        invoke VirtualProtect
,Address,Length,dProtect,offset dProtect
                 WriteMem Endp 

In our case it would be WriteMem,Address,offset hE9,5. hE9 is a pointer to the data, which is 5 bytes and can be declared in the
.data section as: hE9 db 0E9h,00h,00h,00h,00h

2.3) Thinking outside the box
The above idea's are just the very basics. The ultimate goal is to make your engine as automated as possible. Reducing your own time
and effort for creating a trainer. I might dedicate this subject for another tutorial, but I still want to talk about it briefly.

Here's what you'll need to do next. First create a DLL injector and this will also be your GUI(graphical user interface) of the
trainer. Designate a hotkey to activate the trainer (ex. F1). If F1 is pressed inject your DLL, and the dll should automatically
initialize all jumps/caves etc and make a confirmation sound if it succeeds.

You should distinguish two idea's. The first idea is that you need a function that can execute all your signature patterns and create
the jumps to the cave. The second idea is that your caves should hold flags for enabling and disabling options. These flags can then
be controlled by another function that checks for any pressed hotkeys. Also make a difference between toggled and normal types.
Additionally at the startup of the DLL you can implement a check for a hotkey file. If the file exists then load the hotkeys from
that file. You'll need to supply a hotkey editor to your users.

I hope this will make gamehacking a bit more interesting now. You'll need time to develop such an engine, but eventually you'll gain
more time and freedom in creating new options rather than copy/pasting, error & trial, recompiling etc. Plus don't forget your trainer
might support multiple versions, sparing you even more time to smoke crack cocaine.

3.0) Outro

Finall words:
Kids don't do drugs.

Quote: Greets:
team dEViATED: STN, eXtreme and iNTANGIBLE
#gamehacking veggy, tokes, nh2, sbn, POiZN, svenzzon...
masterscar, brzi, risico, aspras, attilathedud, SB, CJB(happy bday)
ksbunker,sheep,apache,micral, L. Spiro
[-] The following 2 users say Thank You to d0h! for this post:
  • triggerhappy, zxz0O0

Possibly Related Threads...
Thread Author Replies Views Last Post
  [Request] rotceh_dnih signature rotceh_dnih 24 4,724 08-20-2012, 18:53
Last Post: Lemon
Photo Preview It'sMods Store Signature 3v0lu710n 10 2,465 12-27-2011, 13:59
Last Post: Rendflex
  @skata3000's new signature Pozzuh 8 1,701 10-03-2011, 06:58
Last Post: Lemon
  LOOK AT MY BIG ASS SIGNATURE JariZ 0 864 09-24-2011, 14:32
Last Post: JariZ
  [News] @4funplayin's New Signature aosma8 12 2,986 09-20-2011, 13:36
Last Post: 4FunPlayin
  LEMON'S SIGNATURE JariZ 13 8,761 08-24-2011, 10:24
Last Post: Lemon
Rainbow [Service] Custom Signature Request Thread Ace 30 9,761 07-19-2011, 03:17
Last Post: Ace
Tongue fuckin signature =D Arteq 1 974 03-28-2011, 21:58
Last Post: d0h!
  [Tutorial] Video Tutorial - Memory Pattern Scanning d0h! 0 2,172 01-02-2011, 12:05
Last Post: d0h!
  [Release] Byte Spy v. 1.0 (Signature finder // Memory Scanner) d0h! 0 2,937 12-16-2010, 09:41
Last Post: d0h!

Forum Jump:

Users browsing this thread: 1 Guest(s)