COF Plugin: Part 4

So hopefully by now you have a working source plugin that will make your server’s cone of fire a straight line. Today I am going to explain a bit about sigs, and show you the signature needed to find the correct location of the shot code.

A signature, in this case, is a string of bytes that (hopefully) only occur once in a program. This bytes should be very close, if not on top of the location you are trying to edit. For example, the signature I used in my cof plugin to find the correct location is this:

8B0D207454228B01680000803F68000080BFFF5004D95C24108B0D
207454228B11680000803F68000080BFFF5204D9542414D84C2414

If I remember correctly, this string will point my program at the exact location that the code prepares to call the random function from COF Plugin Part 1. Now if you are reading he source code you will see that I actually set many different sigs, one for the shot code, one for the return address, and 2 more for linux. In linux, the code looks a bit different so I needed 2 different sigs.

Now a sig like this, by itself is no more safe then using direct address manipulation. Lets say that 2 months from now a program update comes out and jump locations are changed to accommodate the new code. Lets say, 1000 more bytes of code were added in front of this location, now all of a sudden an address that pointed to the right location in the old version is now different.

There would be no way for our simple program to decide this or not (easily), and the sig scan would pass over the correct location without even knowing it.

By the way, sig scanning is what you use this sig for. What you basically do is start at the beginning of a binary in memory and scan through all the code looking for bytes that match your sig completely. I will post code to do this later.

So, how we improve our simple sig is to add a mask to it. A mask is a wondering thing, it tells the scanner to ignore certain parts of the sig, but still verify that its the correct order of instructions. If you are looking at my source code, you see I setup masks for each of the sigs, in fact, I made the mask and sig one in the same data structure to avoid confusion. I will not bother posting the mask, but here is the sig with the mask overlay to show what the scanning is actually searching for.

8B0D????????????680000803F68000080BF???????????????????????
???????680000803F68000080BFFF????D9??????D8??????

And this, translated into sudo assembly is

mov ???????????
???????
push 1
push -1
????????
????????
????????
????????
????????
push 1
push -1
call ???
fst ????
fmul ????

The question marks represent the bytes the scanner will not look at. In this way, the scanner will only search for this specific sequence of commands, not dealing with any data that can be changing by a recompile.

Technically speaking, the order of instructions can also change each recompile, especially if they make changes to the specific cpp file that hold FX_FireBullets. That would force the compiler to recompile the file and possibly alter the order of these commands. However I never said this was a fool proof way to scan, its just the one of the simplest and best ways. The chances of the instructions moving are very low, and if you plan to support this project in any way shape or form during its lifetime its an easy fix to change the sig a bit. In fact, if you have to change it often it is a good thing, you will learn how to make good sigs. So far I have not had to edit this sig since day of defeat source has not had an update since I made the plugin, but its always a possibility. Just remember, if you ever have to reconfigure a sig, make sure to keep it working for the older version as well, that way you can learn what you need to scan for and what you can skip.

So now that you know all about sigs I will post the sig scanner

bool bDataCompare(const BYTE* pData, const BYTE* bMask, const char* szMask)
{
for(;*szMask;++szMask,++pData,++bMask)
if(*szMask==’x’ && *pData!=*bMask )
return false;
return (*szMask) == NULL;
}

DWORD dwFindPattern( DWORD dwAddress, DWORD dwLen, BYTE* bMask, char* szMask)
{
for(DWORD i=0; i < dwLen; i++)
{
if( bDataCompare( (BYTE*)( dwAddress+i ),bMask,szMask) )
return (DWORD)(dwAddress+i);
}

return 0;
}

Fairly simple really, which is why sig scanning is the best cheap form of address retrieval. At each address we run the sig through the data comparer to see if this address matches the sig, if not, we forward to the next address. Not to efficient, but the scans are only done once as the program starts.

After the sig scanning we (hopefully) have the right addresses, if the sig was not found, then we print an error, if the sig was found in another location and we write there, then we break the program and the server crashes. Hopefully neither happen, but once we have the address its just a simple matter of writing our detour, which I will explain next time.

Tags: , , , ,

12 comments

  1. Jon’s avatar

    I’m loving these tutorials. One part that I’m unsure of is how you created the signatures/masks. Is there a certain debugger that has some sort of signature creator, or am I totally missing out on something?

    I know this is a very, very old post, but if you don’t mind helping me out a bit, I would love it :]

  2. admin’s avatar

    They are not that old =p

    You create the sig by reading the bytes at the instruction location. Switch into hex view in your disassembler and you will see the byte codes for the instruction. From there you copy the byte codes into your program and remove specific codes that will change when the program changes.
    An example would be a jump instruction, 752B, you can use 75, but use your mask to erase 2B, otherwise when the program is compiled again there is a chance that distance will change and your sig will break.

  3. Bill’s avatar

    But if i want to create a stand alone scanner, ho can i write this code?

  4. Charles Solar’s avatar

    To build a stand alone exe that can scan another processes memory you will have to write some code to get access to that process’s memory first. This can be accomplished by some simple dll injection, unfortunately I do not have any tutorials online for that, but a simple google search will get you good examples. Once you have access to that process’s memory you can use this code to scan the memory for certain signatures.

  5. Bill’s avatar

    I know i can use Windows Native API ReadProcessMemory cause I want to keep myself external. I have like 100 more memory address: I am hacking this game http://warrock.gamersfirst.com/ . By the way i googled the function you used dwFindPattern and I found nothing. I know that this original concept was developed by some patrick guy. Thanks for your answer and I am looking forward to see another reply!

    PS. Sorry for my mistakes but I am italian :D

  6. Charles Solar’s avatar

    Well be careful when keeping yourself separate since it would not be to much of a stretch for the game to detect and kill your attempts.

    You said you have 100 memory addresses, what exactly are you trying to do? Looking at the game it seems like it is an online game, and unless the game is very broken modifying your client data will not do much.. well, I should not say that because you could install some graphics hacks for transparent walls or bright skins, but that is way above the skill level of a simple sig scanner.

    But anyway, dwFindPattern is code that was posted in a forum that I have forgotten the name of.
    If you want to scan the other processes memory for signatures you can use this code I posted, but the logic must be changed a little bit.

    If you want to scan the process for a signature first use readprocessmemory to read in a chunk of memory, then use dwFindPattern posted above to scan that chunk of memory. Continue pulling more chunks of memory out of the program till you find your signature.
    This will take a bit longer thanks to all the memory copy operations, but you should be able to deduce where your signatures are in due time.

  7. Bill’s avatar

    Look at this http://rafb.net/p/wsv75q84.html . The game is very very client sided with PunkBuster anti-hack protection. I managed to write this, but I cant really understand those signatures. I tried with a Player Pointer address but it doesnt return my desired address… If you can help someway :D

  8. Charles Solar’s avatar

    I looked at your code a week ago but did not have enough time to post a good reply. It seems that the code got deleted from this paste site but I did get the general idea.
    The only sig I found in that code was to find the player pointer. If I remember the instruction correctly it was finding a location where the pointer is loaded for processing and using that location to reference the object itself.
    If the code does not return the correct player address then there is probably something wrong with your sig. Most likely it is too short, if I remember correctly it was only 5-6 bytes long. Usually I make my sigs around 20 bytes long with a good mask.
    However in order to fix the sig you need to know where the sig is in the program which will be hard since you had the sig and masked merged. Hopefully you have the expected address stored somewhere.

    The other elements of the program seemed fine, your scanner was using readprocessmemory exactly as I thought it would so there should be no problem there.

    How do you know you are receiving the wrong player pointer? Does the scanner not find the sig or does it find a false sig? Either way it seems like you need to go back into the program and find a better location to pull the pointer, or improve the sig around the point you chose.

  9. Bill’s avatar

    It used to work for 2 months but now it seems that every sig i put in doesn’t work… dunno >_> do you have msn or something? if you have msn my contact is in the email box…

  10. Charles Solar’s avatar

    No I do not really have any contact info other then email or this site. I only used IMs for work at the moment.
    How are you creating these sigs? Are you picking them out of the binary or are you pulling them off some site?
    This scenario sounds a lot like the game just updated ( or punkbuster is blocking your scans ). Do you have a section of the binary that you pull these sigs from? If so post 2 copies, one where you know where the player pointer is and the current one and I can help find your sig.

  11. dirty’s avatar

    Don’t you still have the problem that the client has the original code so they will see bullets hit how they normally do, when on the server they are hitting in different places?

  12. Charles Solar’s avatar

    Yes you do still have that problem when you only edit the server side code in source. But in this case it was preferred to not have the client download any patch and I never got a complaint about bullets hitting/missing.
    Supposedly the server is written so if you hit them it squirts blood so users still knew if they hit their target or not, regardless of where the dust cloud was in their game.

Comments are now closed.

Charles Solar is Stephen Fry proof thanks to caching by WP Super Cache