Hello all, this is a thread that will show you an in-depth look at a simple hack. This thread will go farther under the surface than some regular tutorials, but will crack down on the basics of what the beginners need to know -but sometimes lack the knowledge of. Since this thread is going to be somewhat lengthy, I may have some mistakes, so please let me know of things to add or improvements to what I say here in the comments. So, lets get started.
Section 1: An Overview
This section will cover an overview of the hack, it's general purpose and how it works. I coded two memory hacks for this tutorial, Superbullets and Nametags, so that I can explain their differences, but that will come in a later section. The hack solution is given at the bottom of this thread, so download it now and continue. The general purpose of this hack is to initiate the hack commands by copying the given bytes to the given address defined inside the solution.
How it works:
1. The hack in injected, and all thread calls to the DllMain function are disabled.
2. The dwThread thread is created, and it waits for the game to load the given modules defined in the IsGameReady() function.
3. Once the game
is ready, it calls the InitHacks() void, which initializes an infinite loop which is needed for the hacks inside to be called each cycle.
4. When the user goes inside a game and presses one of the hotkeys (Numberpad 1 or 2), then the given hacks will be initialized by the WriteToMemory function.
5. When one of the two things inside the "if" statement for lets say Superbullets for example are not true, then the hack jumps to the else statement, which will copy the default bytes of the game and place them on the address given.
Now that the hack has been over-viewed, lets move on to more specific things inside.
Section 2: Memory Editing
This is a sort of fuzzy topic for some members on this forum, while others have it completely down. Because of this, I will go over it like I am explaining it to someone with just a little knowledge of C++ (knows about variables such as integers, booleans, etc).
The memory function we will be using:
Code:
void WriteToMemory(PVOID address, void* val, int bytes)
{
DWORD d, ds;
VirtualProtect(address, bytes, PAGE_EXECUTE_READWRITE, &d);
memcpy(address, val, bytes);
VirtualProtect(address, bytes, d, &ds);
}
Should be renamed to ModifyOpCode as that is what it really does. also you have a pointer to the old value on the second protect which stores in ds that is useless as it's not really used in the scope.
At first glance, you may have seen a familiar function called "memcpy". This function has 3 parameters, destination (first), source (second), and size (third). What it does is the trick to how our memory functions work; it copies the number of bytes from the source and places them on the memory block of the address we described, or destination. Once we know exactly what memcpy does, this function of ours is easy to understand. The first virtualprotect call makes the memory writable, so we can access it with memcpy. When memcpy does its function, the next virtualprotect call re-protects the memory.
Lets now look at some code from the hack, to explain what it does specifically.
Code:
WriteToMemory((PVOID)SuperbulletsAddress, "\x90\x90\x90", 3);
We know how the memory function works, so this should be easy as well. Since we defined the address, but the function takes a type PVOID, we need to cast the address (which is an integer), which is why we have "(PVOID)" in front of the address we defined. The "\x90\x90\x90" are the bytes that will be placed on the address. The "3" is just the length of the bytes that will be placed. The "\x90" we have in the source code is just the NOP instruction, known as No Operation (Don't do anything at that place of memory). You may be wondering why the Nametags hack has two calls to the memory function, and it's because the result we want will not occur unless we edit the memory at those two specific address locations.
Section 3: DllMain and the Connections
Our DllMain function is pretty straight forward, so I won't go too in depth with it. It looks like this:
Code:
BOOL APIENTRY DllMain(HMODULE hModule, DWORD dwReason, LPVOID lpReserved)
{
DisableThreadLibraryCalls(hModule);
if(dwReason == DLL_PROCESS_ATTACH)
{
MessageBoxA(NULL, "The hack has injected!", "A Simple Hack", MB_OK);
CreateThread(NULL, NULL, dwThread, NULL, NULL, NULL);
}
return TRUE;
}
Should be int __stdcall DllMain as you are using the typedefs well that is a personal choice i guess and you should return NULL by default and 1 if the dll process attach succed. just a tip
When windows links a dll with a program, windows calls the library's DllMain function. This is why DllMain is so necessary in hacks. The APIENTRY in the function name is just something windows uses internally. The HMODULE hModule is just a handle for the library to use. the DWORD dwReason is what will be used to tell us if a new program has linked to the dll for the first time, which is why it is compared to DLL_PROCESS_ATTACH in the "if" statement. Inside the "if" statement is just a messagebox that displays text that you want, which also lets you know that dwReason did indeed equal DLL_PROCESS_ATTACH (The dll did link to the process). The CreateThread does just as is shows; it creates the dwThread thread which contains our void, which contains our hacks and such.
Section 4: Variables and the Extras
As you may have seen in the base, our variables are located inside a struct in Main.h. We can call our booleans like bSuperbullets and bNametags by creating an object of our struct, which is what "sVariables Variables" shows. To access the variable inside the struct, we use the dot operator (.) on the object we created.
Since this would be a somewhat short section, I'll also go over some of the minor "extra" features that would also create a short section. One extra is the GetAsyncKeyState function. It's used for getting a current key's state on your keyboard, like if it's up or down at the time. In the hack, it's used for toggling our variables on or off, according to their state at the time.
Section 5: Tips and Tricks
Now that you know how this hack works, you should know how to work it if it becomes outdated. If the off bytes for a hack function change for some reason, then the simplest way to check for the new ones is to just locate the address in OllyDBG. Here are the steps to find the original bytes for any hack function (the on bytes will be hack specific, like NOPing a section).
1. Open OllyDBG and have open a CA Dump. If you don't know how to get a CA dump, then look at
this thread, which includes a cshell dumper and a brief overview on how to do it.
2. Once the dumped cshell is open, press the "run" triangle located on the top bar of the program
3. Once you press the blue triangle, press CTRL + G and enter your address (without the 0x).
4. When you click "enter", it will bring you to the address that you entered. After the address is a line that shows "75 05", and those are the bytes located at that address.
5. Congrats, you now have your new off bytes (\x75\x05).
Section 6: Conclusion
There are some comments inside the actual hack as well, but if you read this thread then you will know everything written down inside. I hope you enjoyed this information, and help me improve by commenting on your thoughts of this, what to add or remove, and other things.