Exercise "Dummy Program": Coding Our Dummy Target Program: Time To Show Off !!
Exercise "Dummy Program": Coding Our Dummy Target Program: Time To Show Off !!
Exercise "Dummy Program": Coding Our Dummy Target Program: Time To Show Off !!
harakirinox From coding to hacking: An introduction guide to practical (external) game hacking
Eternal newbie
A major step in the path of an apprentice hacker (game hacker or not) is to go from learning a programming
language to getting started in practical hacking, using this new knowledge in practice.
There are lots of material available, tutorials and guides, but we are then facing an information overload, a lack of clear
path which can be felt like an impassable gap.
This is in my opinion one of the reasons why we see people knowing how to code asking in hacking communities what to
do then from where they are.
This article has for objective to fill this gap and provide a clear path for anyone having learned to code to get
started in (external) game hacking.
This will be a first experience of practical hacking so the reader understands the crucial steps of game hacking with a
practical example.
Recognitions ... And the cherry on the cake: I will make you code all this as good as possible so you can reuse all this to
hack other games.
Former Staff In other words: You are going to code your own cheat toolkit !!
Member of the Month (1)
The first part is essentially an RPM/WPM tutorial, very verbose, very slow paced for an inexperienced
Donator (2) audience (e.g. people still trying to wrap their head around pointers and such).
The second part is an applied example of cheat development, including the reversing part.
The last part is devoted to an introduction to anti-cheat bypass.
Points: 122,598, Level: 50
I am devoting a lot of my spare time to this project and therefore I will release all this exercise by exercise and not in
Level up: 33%, 3,502 Points needed one go.
Activity: 11.3%
You are free to use the programming language of your choice, however, I will provide solutions to the
exercises in C/C++ only.
Last Achievements
Requirements / Target audience
This tutorial is aimed at anyone having learned a programming language suitable for game hacking (e.g.
C/C++, C#, ...).
You are not required to be a master at this language, but you should not be struggling on the most basic things
either, otherwise I advise you to go get more experience on it, or have a second go thought the lessons, or read another
tutorial to consolidate your knowledge first.
I will numerous times cover important principles in one sentence with one or more links to supporting materials, if you
do not fully and truly understand what I am discussing, you are required to follow the links and read the
suggested material, otherwise you will not build strong knowledge.
This type of cheat is doable by being able to read the game's memory exactly as we will do in the second exercise,
obviously combined with additional code to draw the shapes and text (that I will cover in a another guide).
We can also overwrite the target memory to change values, such as maintaining your player's health points to the
maximum, giving unlimited ammunition, etc...
As you understand getting access to the game's memory is the gateway to any sort of hack we want to do then, this is
why most anti-cheat bypass techniques aim at giving you this access, and why this guide focuses on this task.
We call "External Cheats" any cheat that runs in a separate process than the game/program it hacks.
Oppositely, "Internal Cheats" are executed from within the hacked game/program, therefore, the methods used to read
and write data to the hacked target differ between these two paradigms, among many other differences.
Microsoft Windows operating system provides a set of functions that allow us to read and write another program's
memory self-explanatory named ReadProcessMemory and WriteProcessMemory (abbreviated to RPM and WPM).
Using the RPM function can be imagined as asking your Operating System (OS):
"I would like to read X bytes of data at the memory address 0x12345678 of this process and put the result at the
address 0x87654321 in my process memory"
Same thing for WPM, but instead you ask to write what is at a specific address in your process at an address in the other
process.
Here's an extra diagram in case this is not clear:
Note that this is not the only way and external cheat can read another process memory.
It is possible to read and write another process memory without these functions, for example by using a driver
(functioning in kernel mode, a higher privileged mode of your operating system. Read Wikipedia's "Protection ring"
article for more information)
However, since the hack program still runs as another process, it is still by definition an external cheat.
Directions:
You are going to code a simple console program everything will go in main() that does the following things:
- Declare a variable named varInt of type integer equal to 123456
- Declare a variable named varString of type string with the text "DefaultString" (C++ only, ignore if writing in C)
- Declare an array of char named arrChar of size 128 with the text "Long char array right there ->" (you can put the size
in a declared constant)
- Declare a pointer to integer named ptr2int pointing to varInt
- Declare a pointer to pointer to int named ptr2ptr pointing to ptr2int
- Declare a pointer to pointer to pointer to int named ptr2ptr2 pointing to ptr2ptr
Once this is done you will create an infinite loop in which you will:
- Print to console "Process ID: " followed by the process ID of the program using the Windows API function
GetCurrentProcessId() (Therefore, don't forget to #include <Windows.h> !!)
- Print to console "varInt (0x[ADDRESS OR THE VARIABLE]) = [VALUE OF THE VARIABLE]" (Remember that you can get
the address of a variable by prefixing it by "&")
- Same thing for varString and varChar
- Same thing for our 3 pointers, print for example "ptr2int (0x[ADDRESS OF THE POINTER]) = 0x[ADDRESS POINTED])
- Print to console "Press ENTER to print again."
- Put something to pause, you can either use getchar() or system("pause > nul")
- Print to console a line of dashes ("-") and then let it loop back to the beginning
Here is the expected output by the end of this exercise (after having pressed enter once):
You may have issues when printing to console the process ID or the memory addresses since the process ID should be
printed in decimal and the memory addresses in hexadecimal.
In addition to that, since I'm a bit OCD, I like my memory addresses to be in uppercase.
In C++ you can do like this to output in decimal:
Code:
1. cout << "In decimal: " << dec << 255 << endl;
Solution (C++)
Do not directly read the solution, you should succeed to write such a simple program.
If you have difficulties, do not hesitate to start over.
Code something satisfactory or spend at least 45-60 minutes trying before you decide to reveal the solution.
If you failed and had to look at the solution, read it thoroughly and then recode it yourself, you need more
experience.
Now that we have this dummy program we are ready to start hacking properly speaking.
We are now going to read the values in of these variables in the memory of this dummy program from
another program and overwrite them, just like you'll be going in your game hacks.
Okay, so let's go over the parameters one by one, here's the prototype so you don't have to switch back and forth on
MSDN while reading.
Code:
1. BOOL WINAPI ReadProcessMemory(
2. _In_ HANDLE hProcess,
3. _In_ LPCVOID lpBaseAddress,
4. _Out_ LPVOID lpBuffer,
5. _In_ SIZE_T nSize,
6. _Out_ SIZE_T *lpNumberOfBytesRead
7. );
The first parameter _In_ HANDLE hProcess will probably be tricky for anyone not familiar with Windows API.
One of the numerous roles of your operating system, Windows, is to manage various resources, access, and permissions.
In our case, we need to request an access to our target program, with enough permissions to read and write its memory.
This is what this first parameter of type "HANDLE" is, it's essentially an authorisation given by the operating system.
In order to avoid being confused just consider a HANDLE as an authorisation number given by the operating
system.
To get this required HANDLE, we are going to use the Windows API function OpenProcess.
Once again, click on the link and read thoroughly the function documentation and try to understand how it works.
If you don't understand what is the first parameter, you certainly didn't click on the link to the process access rights,
always follow these links to understand what to feed the function.
You should now understand what this is: It is the permissions we request.
Many permissions are available as you can see in the documentation, ranging from PROCESS_ALL_ACCESS (All possible
access rights for a process object) to PROCESS_QUERY_LIMITED_INFORMATION (Required to retrieve certain information
about a process) with many others, I encourage you to have a quick go through all these permissions, if you do not
understand what some of them allow you to do, it's fine, you are not expected to fully understand that today.
For the sake of simplicity, we are going to request all possible permissions on the target process with
PROCESS_ALL_ACCESS.
A good practice is to limit the permission requested to the minimum useful, but we'll take care of that later.
Otherwise even without that we could find it with this good old Task Manager or any administration software such as
Process Hacker or Process Explorer:
This image has been resized. Click this bar to view the full image. The original image is sized 654x152.
We can then add a simple check in our code to make sure that everything went well.
So our code should look something like that:
Code:
1. HANDLE hProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, [OUR DUMMY PROGRAM PID]);
2. if (hProcess == NULL) { // Failed to get a handle
3. cout << "OpenProcess failed. GetLastError = " << dec << GetLastError() << endl;
4. system("pause");
5. return EXIT_FAILURE;
6. }
This way if you have an error, you will also have the error code returned by GetLastError() that will help you solve the
problem.
In that case, simply go on MSDN error codes pages and look for your error code.
Okay at that stage we now have our precious handle that we can use with ReadProcessMemory, let's move on to the
second parameter of ReadProcessMemory "_In_ LPCVOID lpBaseAddress".
If you've learned C/C++ with the standard library, don't be afraid of Microsoft variable types, LPCVOID is simply a void*
const (LP stands for Long Pointer, C stands for Constant, VOID stands for ... yes, void)
The documentation is rather clear: "A pointer to the base address in the specified process from which to read."
So we'll give there the address that we want to read in the target process.
We print that to the console in our dummy program:
In case this is not clear now (but I really hope it is!), this line means that the value 123456 is stored at the memory
address 0x35AE3DFDE0.
That's what we will give to the function.
Your compiler might not like you to put the address directly as parameter, since it seems like just a number and the
function expects an LPCVOID, therefore, type-cast it as LPCVOID like that:
Code:
1. (LPCVOID)0x35AE3DFDE0
The last parameter, "_Out_ SIZE_T *lpNumberOfBytesRead" allow us to retrieve in a variable of type SIZE_T the number
of bytes read, as the function parameter indicates quite clearly.
We could therefore declare a variable SIZE_T named bytesRead initialised to 0 ( SIZE_T bytesRead = 0; ) and give
ReadProcessMemory its address (&bytesRead).
This can be useful for error checking for example, however, to keep things simple, since this parameter is optional (as
indicated in the documentation), we'll just set it to NULL.
Anyway ReadProcessMemory returns a BOOL (TRUE/FALSE) that let us know if everything went well or not that we can
use to check if the operation succeeded or not.
Okay we now have everything required to read our dummy program's memory.
That perhaps seems a lot to learn if you are beginner, but trust me after this exercise, things should be much clearer.
Exercise directions
Before starting this exercise, start our dummy program and let it run.
Troubleshooting
If OpenProcess fails:
Make sure your 2 processes run with the same privileges, if the dummy program is ran as administrator and not the
other it might fail.
If you run the dummy program from directly from Visual Studio (or your IDE), try running it normally by double clicking
the binary on disk instead.
If intRead is not equal to 0 but is not equal to the expected value either:
You most likely read the wrong memory address or have requested permission to the wrong process ID.
Check the PID and memory address.
Make also sure that in both programs you declared an int.
Try to compile and run them for the same architecture (either both x86 or x64, even if it should work cross-architecture).
If you have an error and have an error code, go on the error codes list on MSDN and use this additional
information on the error to try to solve the issue.
If it still doesn't work, everything else has failed, and you really spent time trying yourself to solve your
issue post your problem as reply of this tutorial with your complete code and the output you have.
Solution (C++)
One last time: Do not reveal the solution unless you have successfully written the program or have spent a
substantial amount of time trying (1-2 hours minimum)
Using the solution without having succeeded is essentially a fail.
In this solution I prompt the user for the PID and memory address to read instead of hardcoding the values, here's an
idea to improve your program
Congratulations !!
You might not realise it, but you now know the fundamental principle to make a complete external radar or
full ESP cheat !!
Obviously, you'll need to read other things than integers for that, for example you'll need to read pointer values, some
text for the nickname of other players for example, but worry not, I've got your back, you're going to do that now!
Reading a pointer
That's something you will definitely need in your cheats, so I strongly advise you to do this one.
You are going to read the value of the pointer "ptr2int" in our dummy program, then you will read the int at the address
pointed by this pointer, which will be our integer equal to 123456
Important thing to remember when dealing with pointers: x86 pointers are 4 bytes long (32 bits) and x64
pointers are 8 bytes long (64 bits) so adapt the parameter "nSize" or ReadProcessMemory depending on the architecture
of your target program.
An OpenProcess malpractice
We requested all permissions for our handle with PROCESS_ALL_ACCESS as first parameter, but we don't need that
much.
Since we only use ReadProcessMemory, read the documentation of that function and request the minimum required
permission in our OpenProcess call.
Pimp it up!
You can also modify your program output as you wish, prompt the user for the PID and memory address.
You could also ask the user what are we going to read: numbers or text and also ask for the lengh of text to read if the
user wants to read text.
Directions:
Obviously, you should have our dummy program running so we can write to it (duh!)
If you closed it after the previous exercise and have the PID and/or memory addresses hardcoded, don't forget to update
them.
Start by reading the entire documentation page of WriteProcessMemory on MSDN (take the habbit to do that for all new
functions we need to use).
Because the function is so similar to ReadProcessMemory, you can reuse our previous code (I advise you however to
create a new project to keep the last exercise saved in case you want to go back to it later).
The only differences are:
- You will rename the variable "intRead" to "intToWrite" ( I like explicit variables names ) and initialise it to 987654
(or the number of your choice)
- You'll obviously call WriteProcessMemory instead of ReadProcessMemory, you can keep the same error checking code
(just rename "rpmStatus" to "wpmStatus", change in the outputted text "ReadProcessMemory failed" to
"WriteProcessMemory failed" and other minor adjustments that makes the source cleaner and more explicit)
- For WriteProcessMemory the second parameter is not LPCVOID but LPVOID, therefore change the type-casting to
(LPVOID) instead
- Instead of printing to console "intRead = ..." just print "Overwritten successfully" (this and the final message "Press
ENTER to quit." will be the only things printed to the console)
Once this is done simply run the program, if you have no errors and see "Overwritten successfully" in the console as
expected, switch back to your running dummy program and press enter to print the variables addresses and values again
and you should see your varInt overwritten to the new value as shown on the following screen capture:
If you encounter problems, refer to the "Troubleshooting" section of Exercise 1, the same suggestions apply to the
current exercise.
Solution (C++)
Again: Try genuinely and only look at the solution if you have succeeded or have spend a substantial amount
of time trying.
Once again, in this code, I prompt the user for the PID, the memory address and the value to overwrite. You can
implement it yourself before looking at the solution as a little extra task to get a little bit more experience, it never
harms.
Going further
Once again, here is a set of sub tasks you can do to make this code better, experiment further and gain more and
MORE experience.
Overwrite text
You can overwrite the text in arrChar and in varString.
Since arrChar is of fixed size, you can overwrite a longer text, however, the object string of varString keeps the memory
used as small as required, you might have a problem if overwriting it to a longer string of text (but you can try to see
what happens, just for the lolz and the experience!)
Again:
You can apply the following subtasks from exercise 2 to this exercise: "An OpenProcess malpractice", "Another
OpenProcess malpractice", "Make some errors!" ( do other errors, play with your code, you won't break your computer
don't worry ) and "Pump it up!"
Congratulations (again) !!
If you've made it that far, a big CONGRATULATIONS to you.
I encourage you to once again show off and show us your code here!
You are now in possession of a set of skills that let you not only code radars and other ESP types of cheats
but you can now also do things like maintaining your health points to maximum value, have unlimited
bullets, money, or whatever else.
... And guess what? That's exactly what we are going to do in the next exercise !!
We are going to say goodbye to our dummy program for now and start hacking a real game: Assault Cube !!
It is free, open source, and unprotected: Perfect for us to learn.
I hope you are excited, because I am too !!
Hey, little question for you: What do you think happens when you do that?
Which Windows API function do you think is called when we "Attach" to the game in Cheat Engine?
We used it ourselves!
... If you guessed OpenProcess congratulations, you're right and you now understand more and more how Windows
programs are made:
There is no black magic and even programs impressive by their complexity like Cheat Engine are coded with the
functions that you are now learning to use!
And if you don't believe me you can verify that in Cheat Engine source, but let's keep that for later, when we will add a
bypass to Cheat Engine
Okay now we are going to repeat the procedure that I described previously, we are going to look for the value of our
ammos in the magazine of our assault rifle which should be 20 if you haven't shot yet.
In Cheat Engine, we are going to search for the value 20, exact value and of type 4 bytes (integers are traditionally 4
bytes longs, not that some values could be stored in 2 bytes shorts, or 8 bytes uint64_t, etc... we sort of have to guess,
but since 4 bytes is dominant, we start by that).
Leave the rest of the options by default, Cheat Engine has intelligent default values that work in most cases.
The scan will find you a few thousands results as shown in this picture:
This image has been resized. Click this bar to view the full image. The original image is sized 789x702.
Now go in the game, shoot a bullet (or 2 it doesn't matter, just make the value of the currently loaded ammos vary).
Scan for the new value (press Enter or click on "Next scan", "New scan" actually delete the current results)
You should now have fewer results, in my case, I have only 3 results in the left pane.
Let's repeat the operation, shoot or reload and scan for the new value.
You should be left with only 2 values, if that's not the case, repeat the operation until you only have 2 values.
You will notice that the 2 values change every time you shoot a bullet, that means we have most likely found what we
are looking for!
Double click on the 2 addresses on the left pane to add them to the list of saved addresses (shown in the bottom pane):
This image has been resized. Click this bar to view the full image. The original image is sized 788x700.
You can double click on "No description" and enter a more eloquent name, such as "Assault Rifle Loaded Ammos 1" &
"Assault Rifle Loaded Ammos 2", take this habit so you know what you've found later.
Now how to know which one is the right one?
We can experiment and play with the values, for example, check what happens when you change one value but not the
other (just double click on the value in the bottom pane and enter the new value) and shoot a bullet: the 2 values are
decremented, that's not really helpful.
You will also notice that one of the values doesn't change the number of bullets on screen.
Okay let's try to set the value stored at this memory address to 1 and shoot a bullet, which will set it to 0 and normally
should make us reload automatically.
Go ahead and try: The weapon doesn't reload and the value on screen shows the other value.
This image has been resized. Click this bar to view the full image. The original image is sized 791x699.
Therefore this memory address is not the one we want, it is the other one that stores the "real" value that is used when
shooting, reloading, etc...
You can remove the superfluous address so we only keep the one that we are interested in.
Let's check that we do have the right address: Double click the value and set 20, then check the box on the left of the
memory address in the right pane, which has for effect to "lock" the value (overwrite over and over again the value to
the one we want) and shoot in the game, the number of bullets should be maintained to 20.
And here we are! Unlimited ammos !!
Okay now let's have a look at what's in memory around that value.
Right click on the address in the bottom pane and click on "Browse this memory region".
This will open the memory explorer window with as first byte the value at the address you right clicked on.
Can you see something interesting in the memory view, especially on the right side ASCII view?
Normally you should see not so far away your nickname:
This image has been resized. Click this bar to view the full image. The original image is sized 1456x947.
That's very interesting, the fact that these 2 pieces of information are so close certainly means that there is some sort of
memory structure holding all our info.
Okay let's save the address where our nickname is stored in the list of saved addresses, to do so, simply right click the
first character of your nickname and select "Add this address to the list".
This image has been resized. Click this bar to view the full image. The original image is sized 1449x912.
We can also observe that the value of the Assault Rifle loaded ammos and the nickname are spaced by 0xD5 bytes (in
my screen capture, 0x278A768 - 0x278A83D), we will confirm that when we'll have reverse engineered the whole
structure.
If you can try to put the game on a side of the screen and the memory view on the other side (or on a secondary screen,
if you have one), scroll up a bit in the memory view, and do things in the game, move around, shoot some bullets, pick
up some ammos, armors and stuff you will see some addresses and values flashing red, which indicates changes.
This way you can locate your coordinates moving, your HPs, your armor, your bullets, etc...
We will take care of making sense of all that data later, don't worry about it for the moment.
Now I am going to show you something terrible... but don't worry I'll give you the solution right away
First, save the addresses you found in Cheat Engine (CTRL + S, or File > Save As, or click on the floppy disk/save icon)
and save it somewhere, just in case.
By saving your results you can reopen them later, quite practical.
Now, quit the game, entirely, and then restart it.
In your still open Cheat Engine click on the Attach button and reattach it to Assault Cube ("ac_client.exe").
Cheat Engine is going to ask you if you want to keep the current address list/code list, answer yes.
Check out the values of ammos and the nickname, it doesn't read the damn value anymore !!
This is because the final addresses at which the data is stored change every time you run the game.
The game's binary image loads at a base address and then allocate memory at addresses that cannot be predicted
before it runs.
Fortunately there is always a way to find this final address by following a chain of pointer that starts at a static address,
or at least relative to the base address that we can find procedurally.
To do this we are going to use a technique called pointer scanning.
If you haven't ticked "Show advanced options" you will have fewer options and that will most likely be fine, only go
tweak the options if you know what you are doing or are having a problem.
You can hover above the check boxes for additional help and information on what the options do.
Click Okay and Cheat Engine will scan (it might take a few seconds to a few minutes, depending on the configuration and
your computer)
You should have something like that:
This image has been resized. Click this bar to view the full image. The original image is sized 747x624.
As you can see, Cheat Engine has found in my case more than 600.000 paths leading to the targeted memory address
storing the value of our loaded ammos, that's a lot and most of them are unreliable, therefore we need to find pointer
chains that are consistent and work every time the game runs.
Keep this Cheat Engine open (both the main Cheat Engine window and the pointer scan window) and quit the game, then
restart it and reattach Cheat Engine to the game (it will ask you if you want to keep the address list, say No we don't
need the address where were the ammos last run, it won't work anymore).
Once again, find the memory address storing your loaded ammos with the same method (scan for value, shoot, scan for
new value, identify "real" address by changing value if need be)
Once you have the memory address of our loaded ammos, copy the memory address (you can double click on it in the
left pane to add it to the list then double click on the address in the bottom pane and hit CTRL + C)
Now go back to the window of the pointer scan and click Pointer scanner > Rescan memory - Removes pointers not
pointing at the right address
A new window opens asking you mainly which new address we want to find, paste here the new address where our
ammos are.
You can leave the options by default and click OK, Cheat Engine will scan again.
You should normally see the number of pointer paths decrease, repeat the operation until the number of pointer paths
does not decrease significantly anymore (close game, locate memory address of loaded ammos, pointer scan for this
address).
Once the number of pointer paths does not decrease at each scan sort the pointers by offsets, this way it will show us
first the shortest pointer chains and sort them with the smallest offset first.
This image has been resized. Click this bar to view the full image. The original image is sized 749x295.
We are going to use the first pointer chain starting from the base address of the game (selected/highlighted in blue in
the image)
Double click on it, this will add it to the list in the bottom pane of the main window.
Now on the main window, double click the address of this newly added address that should be named "pointerscan
result"
You can see that it's not just a direct memory address, this is a pointer chain to follow, with as base
"ac_client.exe"+00109B74 then the offset 148 (implicitly hexadecimal, 0x148)
Rename it to "Loaded ammos (pointer chain)" and click OK.
Now select it in the bottom pane and hit copy paste it (CTRL + C, CTRL + V, then click Paste).
Double click on the Description of the new copy of the address, rename it "My Player - Base", then double click on its
address and change the pointer 148 by 0
You might wonder "What the hell means ac_client.exe + some address, what's that?"
This is what we call the base address.
When windows create a new process, during initialisation it places the program's binary image at a specific address that
we call "Base address" to be executed.
By default Windows uses the address 0x00400000 as base address (this is not mandatory, but it's the default used in the
large majority of the cases).
You can even do the test yourself to check if you Assault Cube game has this base address very simply.
In cheat engine, simply click in the main window "Add Address Manually" then in the address field write "ac_client.exe"
(with the double quotes " on both sides) and click OK, you will see in your address list the address being 00400000:
There is no reason for the game to load at a different address, therefore, instead of using the address that we found
from the pointer scan ("ac_client.exe"+00109B74) we are going to use the address 0x509B74 (0x400000 + 0x109B74).
Double click the address of "My Player - Base" that is in our list of addresses in Cheat Engine and replace the base
address "ac_client.exe"+00109B74 by the direct address 0x509B74.
You can do the same thing for the "Loaded ammos (pointer chain)" address and you'll see, it still points to the right
address and we can still read the number of bullets loaded in our gun (29 for me as you can see in the following image):
Okay, we now know that at the address 0x509B74 there is a pointer and if we follow it ("dereference" it) we arrive at a
memory address where the number of ammos loaded is at +0x148
Chances are that this pointer lead us to a memory structure with lots of other valuable information (for example, our
HPs, armor, position, etc...)
Let's see that, right click on your address "My Player - Base" and click on "Browse memory region"
If you don't have it or you had a problem you can get it simply by click in the main window on Add Address Manually,
tick Pointer, and enter 0x509B74 as base address, leave 0 as first and only poniter and click OK. Name it My Player -
Base
Okay you are now in the Memory Viewer, this allows us to see the bytes in memory at the memory address we want,
with the address on the right, the hexadecimal representation of the bytes in the middle and the ASCII representation on
the right.
This can be helpful if you look of hexadecimal or string, but we are looking of decimal values, floating points values,
etc... (our health, armor, position, etc...)
Fortunately cheat engine has a tool that let us visualise memory structures better for that.
Click on "Tools" on the top menu then "Dissect Data/Structures", a new window will open with an address that is
normally the address pointed by our pointer chain.
Click on Structures, then Define new structure and name it "Assault Cube - Player"
Cheat Engine will ask you if you want it to fill in the most basic types of the struct using the current address, say Yes
(using the values, it will try to "guess" if the memory address is more likely to hold an integer, a float, a string of text,
etc... It can make mistakes but we'll correct them manually)
Leave the value by default for the size (4096) that should be enough.
Directly when you'll see the values, you will understand that we have lots of valuable data over there:
This image has been resized. Click this bar to view the full image. The original image is sized 823x564.
We can see a set of 3 floats consecutively and this is very interesting because it looks like 3D coordinates (X, Y, Z), we
call that a Vector3 (essentially a float[3])
Now put the window on the side and move in the game.
Do you see the values changing ?!
We're on to something of value there, this is undoubtedly our player's memory structure.
How to know what Vector3 is what?
Well, don't move in the game but just move the mouse, look around, the first and second Vector3 do not change but the
third does.
The third Vector3 is therefore our view angles!
You can double click the line in Cheat Engine and enter a description, name the 2 lines respectively "View X" and "View
Y" (the third is also part of the view but never change, for the view angle we also call X, Y and Z "Yaw", "Pitch", and
"Roll")
You should have that:
Okay once we have found everything we could and everything we want to code our cheat functions, we can transform all
this into a struct that we will use in our cheat.
If you have reversed the game with ReClass this software allow you to directly export your structure to C/C++ code,
however, I have made it by hand to make it very clear using the self-explanatory Windows types.
Here is what I have found put in a nice struct for you:
Code:
1. struct ACPLAYER {
2. BYTE unknown1[0x4]; // +0x0
3. POINT3D headPosition; // +0x4
4. BYTE unknown2[0x24]; // +0x10
5. POINT3D position; // +0x34
6. POINT3D view; // +0x40
7. BYTE unknown3[0x8]; // +0x58
8. INT32 jumpFallSpeed; // +0x54
9. FLOAT noClip; // +0x58
10. BYTE unknown4[0x14]; // +0x5C
11. INT32 isImmobile; // +0x70
12. BYTE unknown5[0xE]; // +0x74
13. INT8 state; // +0x82
14. BYTE unknown6[0x75]; // +0x83
15. INT32 hp; // +0xF8
16. INT32 armor; // +0xFC
17. BYTE unknown7[0xC]; // +0x100
18. INT8 dualPistolEnabled; // +0x10C
19. BYTE unknown8[0x7]; // +0x10D
20. INT32 pistolReserveAmmos; // +0x114
21. INT32 carabineReserveAmmos; // +0x118
22. INT32 shotgunReserveAmmos; // +0x11C
23. INT32 smgReserveAmmos; // +0x120
24. INT32 sniperRifleReserveAmmos; // +0x124
25. INT32 assaultRifleReserveAmmos; // +0x128
26. BYTE unknown9[0x8]; // +0x12C
27. INT32 doublePistolReserveAmmos; // +0x134
28. BYTE unknown10[0x4]; // +0x138
29. INT32 pistolLoadedAmmos; // +0x13C
30. INT32 carabineLoadedAmmos; // +0x140
31. INT32 shotgunLoadedAmmos; // +0x144
32. INT32 smgLoadedAmmos; // +0x148
33. INT32 sniperRifleLoadedAmmos; // +0x14C
34. INT32 assaultRifleLoadedAmmos; // +0x150
35. BYTE unknown11[0x4]; // +0x154
36. INT32 grenades; // +0x158
37. INT32 doublePistolLoadedAmmos; // +0x15C
38. INT32 knifeSlashDelay; // +0x160
39. INT32 pistolShootDelay; // +0x164
40. INT32 carabineShootDelay; // +0x168
41. INT32 shotgunShootDelay; // +0x16C
42. INT32 smgShootDelay; // +0x170
That is quite practical to have such a nice struct like that, because that way we will be able to retrieve from the game's
memory all the information in one read instruction for our cheat features (e.g. the ESP, GPS and radar).
But before we jump into ESP, GPS and radar, let's make a small home made trainer first!
All comments and feedback are more than welcome, I intent to improve this tutorial several times and your input would
be valuable for that.
__________________
Absolute beginners: Get started in game hacking here
Beginners & new coders: From coding to hacking: An introduction guide to practical (external)
game hacking
User-Mode Bypass: SilentJack: Stealth-aware handle hijacking | Handle hijacking with IPC
General Hacking: Window HiJacking (v2 with DirectX) | Bypass PPL (Protected Process Light) | LSASS Handles
Permissions Patcher | Access any protected games' memory | Overlay window non-TOPMOST & only above the game
DayZ SA: Ghost mode | Teleport to vehicle
Last edited by harakirinox; 18th April 2018 at 09:25 AM. Reason: Adaptation to new scope of the tutorial
harakirinox is offline
wagvan bruh you need a hobby other than writing these longass tutorials, go outside or something
Antiestablishmentarian
very well written, the sort of quality content this forum needs.
Posts: 795
Reputation: 25104
Rep Power: 169
Recognitions
Donator (6)
Activity: 4.4%
Last Achievements
wagvan is offline
Macul Quote:
Member
Originally Posted by wagvan
bruh you need a hobby other than writing these longass tutorials, go outside or something
very well written, the sort of quality content this forum needs.
He's the hero we (beginners) probably don't deserve, but luckily enough get.
__________________
Posts: 58
Reputation: 1150
Rep Power: 166
Activity: 11.3%
Last Achievements
Macul is offline
Posts: 13
Reputation: 307
Rep Power: 183
Activity: 0%
arnakena is offline
harakirinox Quote:
Eternal newbie
Originally Posted by wagvan
bruh you need a hobby other than writing these longass tutorials, go outside or something
very well written, the sort of quality content this forum needs.
Threadstarter
Posts: 1,412
Reputation: 81617
Rep Power: 250
Recognitions
Former Staff
Donator (2)
Let me know what do you think about this plan and any suggestion.
__________________
Absolute beginners: Get started in game hacking here
Beginners & new coders: From coding to hacking: An introduction guide to practical (external)
game hacking
User-Mode Bypass: SilentJack: Stealth-aware handle hijacking | Handle hijacking with IPC
General Hacking: Window HiJacking (v2 with DirectX) | Bypass PPL (Protected Process Light) | LSASS Handles
Permissions Patcher | Access any protected games' memory | Overlay window non-TOPMOST & only above the game
DayZ SA: Ghost mode | Teleport to vehicle
harakirinox is offline
Macul Quote:
Member
Originally Posted by harakirinox
https://i.imgur.com/zju3jeJ.png
I'm going to write the third exercise then I think I'm going to make an fourth exercise in which we will get
infinite health, ammos, etc... in Assault Cube.
The fifth exercise should be drawing a radar and the sixth should be coding the on-screen player ESP.
I'll skip the reversing by providing the reading with a Cheat Engine .CT table since reversing is outside the
scope of this guide but it'll make this tutorial EXTREMELY practical and I'm sure it'll be an exciting experience
to new game hackers.
Let me know what do you think about this plan and any suggestion.
I think it sounds like a great idea. One of the hardest part for beginners is self-motivation and feeling involved with the
thing they want to do (game hacking in this case)
__________________
Posts: 58
Reputation: 1150
Rep Power: 166
Activity: 11.3%
Last Achievements
Macul is offline
HyperReal The amount of time and effort you spend on your guides is truly appreciated. As a beginner this really helps motivate
n00bie me. Thank you, Harakirinox.
Posts: 2
Reputation: 10
Rep Power: 122
HyperReal is offline
arnakena
n00bie
Quote:
I'm going to write the third exercise then I think I'm going to make an fourth exercise in which we will get
infinite health, ammos, etc... in Assault Cube.
The fifth exercise should be drawing a radar and the sixth should be coding the on-screen player ESP.
Join Date: Sep 2015 I'll skip the reversing by providing the reading with a Cheat Engine .CT table since reversing is outside the
scope of this guide but it'll make this tutorial EXTREMELY practical and I'm sure it'll be an exciting experience
Posts: 13
to new game hackers.
Reputation: 307
Let me know what do you think about this plan and any suggestion.
Rep Power: 183
Points: 2,265, Level: 4 Your guide is certainly the real beginners guide @harakirinox
I totally agree that we have an information overload !! Especially for beginners.
Level up: 24%, 535 Points needed And your guide is simply amazing. You take all these pieces of crucial info for newbies, stick those together and arrange
them STEP BY STEP !
Activity: 0% I truely appreciate what you're doing here m8.
I am doing it atm and it helps me a lot to understand things I didnt got before.
I am saying it again but you are truely changing the world for beginners, this guide keeps me motivated. Amazing job,
waiting for the next steps
Oh forgot one thing @harakirinox , some suggestions for the next steps : maybe a guide for internals. Just saying. As
many cheats are made internally (smoother, more features, etc...).
Then at the very least (maybe) MAYBE talking a little bit about anti-cheats, counter measures.
arnakena is offline
Will do, I decided to go external first because it is more accessible for beginners in my opinion and I feel much more at
ease to explain that, I have a lot more experience with externals.
However, I will definitely do some internals guides in the future, when this guide is fully set, and certainly after I have
ventured in kernel-land, I am postponing that for too long now
__________________
Absolute beginners: Get started in game hacking here
Beginners & new coders: From coding to hacking: An introduction guide to practical (external)
game hacking
User-Mode Bypass: SilentJack: Stealth-aware handle hijacking | Handle hijacking with IPC
General Hacking: Window HiJacking (v2 with DirectX) | Bypass PPL (Protected Process Light) | LSASS Handles
Permissions Patcher | Access any protected games' memory | Overlay window non-TOPMOST & only above the game
DayZ SA: Ghost mode | Teleport to vehicle
Threadstarter
Posts: 1,412
Reputation: 81617
Rep Power: 250
Recognitions
Former Staff
Donator (2)
Activity: 11.3%
Last Achievements
harakirinox is offline
Macul Quote:
Member
Originally Posted by harakirinox
@arnakena Thanks for the support mate, really appreciated.
Will do, I decided to go external first because it is more accessible for beginners in my opinion and I feel much
more at ease to explain that, I have a lot more experience with externals.
However, I will definitely do some internals guides in the future, when this guide is fully set, and certainly after
I have ventured in kernel-land, I am postponing that for too long now
You mention that you're postphoning it. Just keep in mind that you don't owe us beginners any of this work XD. This is
turning into one of, if not, the best guides i've seen. Take your time and make it right as it's likely your stickies will be
here for a long time. Hell I linked stickies a decade old in my post.
__________________
Posts: 58
Reputation: 1150 Sometimes life makes us all feel like a paraplegic on skis
Rep Power: 166
Activity: 11.3%
Last Achievements
Macul is offline
harakirinox Quote:
Eternal newbie
Originally Posted by Macul
You mention that you're postphoning it. Just keep in mind that you don't owe us beginners any of this work
XD. This is turning into one of, if not, the best guides i've seen. Take your time and make it right as it's likely
your stickies will be here for a long time. Hell I linked stickies a decade old in my post.
Actually I surprised myself, when I first started this guide I intended to stop after the RPM/WPM exercises but then I
realised that we were only a few steps away from a true gem:
A guide that takes new coders to their first full real hack on a real game.
When I saw how far I could take my readers in just a few hours I just got amazed and decided to go for the full thing.
I am convinced that this has the potential to be one of the most valuable guide for beginner on UC and even outside.
So yes, I will take my time, I will do it well and work thoroughly on that.
Quote:
Activity: 11.3%
Last Achievements
harakirinox is offline
Macul Quote:
Member
Originally Posted by harakirinox
Actually I surprised myself, when I first started this guide I intended to stop after the RPM/WPM exercises but
then I realised that we were only a few steps away from a true gem:
A guide that takes new coders to their first full real hack on a real game.
When I saw how far I could take my readers in just a few hours I just got amazed and decided to go for the
full thing.
I am convinced that this has the potential to be one of the most valuable guide for beginner on UC and even
outside.
So yes, I will take my time, I will do it well and work thoroughly on that.
Posts: 58 If you're aiming to make one of the best guides on UC then you are well on your way there. Covering the gap between
learning a language and applying it to game hacking. I think the reason I, and many others, struggle to do something
Reputation: 1150
even with the knowledge is that we are overwhelmed by the information. Of course we could teach ourselves but these
Rep Power: 166
guides, I feel, will bring more people into it as it can be daunting otherwise.
__________________
Points: 4,559, Level: 7
Activity: 11.3%
Last Achievements
Sometimes life makes us all feel like a paraplegic on skis
Macul is offline
Posts: 184
Reputation: 2099
Rep Power: 126
Activity: 6.9%
Last Achievements
HHKB is offline
harakirinox Quote:
Eternal newbie
Originally Posted by HHKB
Can you recommend me basic network book?
I want to know enough level of network knowledges that will help game hacking.
You worked as a network security manager, i think you know good way to start learning network.
Sorry mate, since this is my main specialisation I've learned all this though education.
I had a quick look on Amazon and the book "Network Security Assessment: Know Your Network" published by O'reilly
has very good reviews and O'reilly books are generally of quality so I'd go for this one.
__________________
Absolute beginners: Get started in game hacking here
Beginners & new coders: From coding to hacking: An introduction guide to practical (external)
game hacking
User-Mode Bypass: SilentJack: Stealth-aware handle hijacking | Handle hijacking with IPC
General Hacking: Window HiJacking (v2 with DirectX) | Bypass PPL (Protected Process Light) | LSASS Handles
Permissions Patcher | Access any protected games' memory | Overlay window non-TOPMOST & only above the game
DayZ SA: Ghost mode | Teleport to vehicle
Threadstarter
Posts: 1,412
Reputation: 81617
Rep Power: 250
Recognitions
Former Staff
Activity: 11.3%
Last Achievements
harakirinox is offline
arnakena @harakirinox
n00bie here are the exercice 1 and 2 that I have worked on. I did it successfully without looking to the solution
Exercice 1 :
Code:
1. #include "stdafx.h"
2. #include <iostream>
3. #include <windows.h>
4. #include <string>
5.
6. using namespace std;
7.
Join Date: Sep 2015 8. int main()
9. {
Posts: 13 10. int varInt = 123456;
11. string varString = "DefaultString";
Reputation: 307 12. int const SIZE_OF_ARRAYCHAR = 128;
Rep Power: 183 13. char arrChar[SIZE_OF_ARRAYCHAR] = "Long char array right there ->";
14. //ptr2Int pointing to varInt
15. int *ptr2Int(&varInt);
Points: 2,265, Level: 4 16. //ptr2ptr pointing to ptrToInt
17. int **ptr2ptr(&ptr2Int);
Level up: 24%, 535 Points 18. //ptr2ptr2 poiting to ptr2ptr
needed 19. int ***ptr2ptr2(&ptr2ptr);
20.
Activity: 0% 21. do
22. {
23. cout << "Process ID : " << dec << GetCurrentProcessId() << endl << endl;
24.
25. //All prints
26. cout << "varInt (0x" << hex << uppercase << &varInt << ") = " << dec << varI
27. cout << "varString (0x" << hex << uppercase << &varString << ") = " << varStrin
28. cout << "arrChar[" << dec << SIZE_OF_ARRAYCHAR << "] (0x" << hex << uppercase << &
29. cout << "ptr2int (0x" << hex << uppercase << &ptr2Int << ") = " << ptr2Int <<
30. cout << "ptr2ptr (0x" << hex << uppercase << &ptr2ptr << ") = " << ptr2ptr <<
31. cout << "ptr2ptr2 (0x" << hex << uppercase << &ptr2ptr2 << ") = " << ptr2ptr2
32. cout << "Press ENTER to print again" << endl << endl << endl;
33. cout << "----------------------------------------------------------------" << endl;
34.
35. system("pause > nul");
36. } while (GetAsyncKeyState(VK_RETURN));
37.
38. return 0;
39. }
Exercice 2 :
Code:
1. #include "stdafx.h"
2. #include <iostream>
3. #include <windows.h>
4.
5. using namespace std;
6.
7. int main()
8. {
9.
10. int intRead = 0;
11. DWORD processID = NULL;
12.
13. cout << "Enter the Process ID (in decimal) : ";
14. cin >> dec >> processID;
15.
16. HANDLE hProcess = OpenProcess(PROCESS_VM_READ, FALSE, processID);
17.
18. if (hProcess == NULL)
19. {
20. cout << "OpenProcess failed. GetLastError = " << dec << GetLastError() << endl;
21. system("pause > nul");
22. return EXIT_FAILURE;
23. }
24.
25. uintptr_t memoryAddress = 0x0;
26. cout << "Memory address of the integer to read (in hexadecimal) : 0x";
27. cin >> hex >> memoryAddress;
28. cout << "Reading 0x" << hex << uppercase << memoryAddress << " ..." << endl;
29.
30. BOOL rpmReturn = ReadProcessMemory(hProcess, (LPCVOID)memoryAddress, &intRead, sizeof(int), NULL)
31. if (rpmReturn == FALSE)
32. {
33. cout << "ReadProcessMemory failed. GetLastError = " << dec << GetLastError() << endl;
34. system("pause > nul");
35. return EXIT_FAILURE;
36. }
37.
38. cout << "RPM succeeded. intRead = " << dec << intRead << endl << "Press ENTER to exit" << endl;
39.
40. BOOL closeHandleReturn = CloseHandle(hProcess);
41. if (closeHandleReturn == FALSE)
I know that some will say it is spoonfeed and the solution is already given
but ye at least I really feel that I am learning and I am more motivated.
Also I post that to let you know (harakirinox) that at least 1 person is
doing your exercises and you have not done that tut for nothing coz that is
a huge amount of time spent out here by making it. Alright I will post
more for the next exercices.
Keep on the amazing work !
Last edited by arnakena; 13th March 2018 at 10:42 PM.
arnakena is offline
MagicM8 I would advise you to remove the whole idea of reading std::string like you are suggesting. Also I'd bet that 90% of
Hacker Supreme people that read this thing will use c++ so changing up the code that it would involve less questionable practices might
be a good idea.
(btw in my opinion the stock images are cringeworthy and unsuitable)
Posts: 240
Reputation: 27381
Rep Power: 194
Recognitions
Member of the Month (2)
Activity: 2.4%
Last Achievements
MagicM8 is offline
harakirinox @arnakena Your code from exercise 1 is excellent, I absolutely love that you used GetAsyncKeyState !! (We will be
Eternal newbie using in in the next fourth exercise and the next ones as well!)
Quote:
The first exercise is very guided, more of an exercise, it is more an entry level test.
The second exercise is quite guided too, however, the subtasks are designed to start accelerating the pace and let you
Threadstarter code more autonomously to get real experience.
The third exercise has less instructions, the pace accelerates again, and in the next exercises I will keep increasing
Join Date: Nov 2016 reasonably the difficulty.
__________________
Location: UK & France
Absolute beginners: Get started in game hacking here
Posts: 1,412 Beginners & new coders: From coding to hacking: An introduction guide to practical (external)
game hacking
Reputation: 81617 User-Mode Bypass: SilentJack: Stealth-aware handle hijacking | Handle hijacking with IPC
Rep Power: 250 General Hacking: Window HiJacking (v2 with DirectX) | Bypass PPL (Protected Process Light) | LSASS Handles
Permissions Patcher | Access any protected games' memory | Overlay window non-TOPMOST & only above the game
Recognitions DayZ SA: Ghost mode | Teleport to vehicle
Former Staff
Activity: 11.3%
Last Achievements
harakirinox is offline
namazso Quote:
free(malloc(sizeof(int)))
Originally Posted by harakirinox
(e.g. people still trying to wrap their head around pointers and such).
...
This tutorial is aimed at anyone having learned a programming language suitable for game hacking
(e.g. C/C++, C#, ...).
You are not required to be a master at this language, but you should not be struggling on the most basic
things either, otherwise I advise you to go get more experience on it, or have a second go thought the
lessons, or read another tutorial to consolidate your knowledge first.
Quote:
wtf? drivers aren't processes. or if you meant a stub for drawing and shit:
Recognitions
1. Not all cheats need drawing
Member of the Month (1) 2. You can draw from kernelmode, although with a lot of suffering
Donator (3) 3. You usually want fast reading so you should attach to the process, which means you run in its address space, much
more like internals. You can even call functions if you disable SMEP (although PG might get angery for that)
Former Staff
Activity: 5.3%
you know reading / writing that is way too hard for beginners, right? STL structures and their memory layout are
volatile, even between modules. That's one of the reasons why you cannot (shouldn't at least) pass them between
Last Achievements modules. Even if you were to implement reading it it would certainly not be a beginner exercise, especially because SSO.
Did you even test your own guide?
Quote:
Please do not ever do this. Also, in the beginning you said language knowledge is required...
Quote:
Quote:
Quote:
That is just plain wrong, that is std::list you are thinking of.
Quote:
Would be noteworthy that you can use smart pointers for this so you get usual RAII.
In all honesty, i do find these threads unnecessary. People who you are trying to target do not learn because there is no
enough documentation but because they do not want to. They do not want to learn or read for that matter. I did not start
game hacking that long ago (2016 September to be precise), and all i started with was c++(98) knowledge. Without
knowing windows API either. Really all it takes is an hour or so for reading MSDN where everything here is perfectly
documented, and you get the glimpse that RPM and WPM is just an overly complicated memcpy (by the looks of it). I
also find it kinda unintuitive that you started with external, which is a lot harder for a beginner than internal. You can
already handle your own programs and your own code, and when internal you can just pretend the game is all your
program / code too, and can do the operations you are used to. All the sugar coated magic of RPM and WPM just
becomes plain and simple pointer arithmetics. My first experience of game hacking was externals unfortunately, and
finding out that internals exist was truly a relief, since i was able to use everything "normally", without relying on the
magic of random windows functions that i was really not knowledgeable of back then.
__________________
All original code posted by me is licensed under WTFPL unless stated otherwise.
Releases and stuff: avoiding internal detections | hdd serial spoofer | pdb_parser_lite | x64 retaddr spoofer | syscaller
| shellcode crafter
CSGO: sticker changer | dynamic skin parser | nSkinz
namazso is offline
harakirinox Quote:
Eternal newbie
Originally Posted by MagicM8
I would advise you to remove the whole idea of reading std::string like you are suggesting. Also I'd bet that
90% of people that read this thing will use c++ so changing up the code that it would involve less questionable
practices might be a good idea.
(btw in my opinion the stock images are cringeworthy and unsuitable)
@namazso tldr
__________________
Absolute beginners: Get started in game hacking here
Beginners & new coders: From coding to hacking: An introduction guide to practical (external)
game hacking
User-Mode Bypass: SilentJack: Stealth-aware handle hijacking | Handle hijacking with IPC
General Hacking: Window HiJacking (v2 with DirectX) | Bypass PPL (Protected Process Light) | LSASS Handles
Permissions Patcher | Access any protected games' memory | Overlay window non-TOPMOST & only above the game
DayZ SA: Ghost mode | Teleport to vehicle
Threadstarter
Posts: 1,412
Reputation: 81617
Rep Power: 250
Recognitions
Former Staff
Member of the Month (1)
Donator (2)
Activity: 11.3%
Last Achievements
harakirinox is offline
arnakena For me the first 3 exercices are clear. I am a beginner in C++ and do not master it yet. But still, I was able do the first 3
n00bie exercices easily.
About RPM/WPM, we just need some practice to understand that. There is nothing really complicated in it.
Exercise 3 :
Code:
1. #include "stdafx.h"
2. #include <iostream>
3. #include <windows.h>
4.
5. using namespace std;
6.
Join Date: Sep 2015 7. int main()
8. {
Posts: 13 9.
10. int intToWrite = 987654;
Reputation: 307 11. int wpmInt = 0;
Rep Power: 183 12. DWORD processID = NULL;
13.
14. cout << "Enter the Process ID (in decimal) : ";
Points: 2,265, Level: 4 15. cin >> dec >> processID;
16.
Level up: 24%, 535 Points 17. HANDLE hProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, processID);
needed 18.
19. if (hProcess == NULL) // failed to get a handle
Activity: 0% 20. {
21. cout << "OpenProcess failed. GetLastError = " << dec << GetLastError() << endl;
22. system("pause > nul");
23. return EXIT_FAILURE;
24. }
25.
26. uintptr_t memoryAddress = 0x0;
27. cout << "Memory address of the integer to write (in hexadecimal) : 0x";
28. cin >> hex >> memoryAddress;
29. cout << "Writing 0x" << hex << uppercase << memoryAddress << " ..." << endl;
30.
31. BOOL wpmReturn = WriteProcessMemory(hProcess, (LPVOID)memoryAddress, &intToWrite, sizeof(int), NU
32. if (wpmReturn == FALSE)
33. {
34. cout << "WriteProcessMemory failed. GetLastError = " << dec << GetLastError() << endl;
35. system("pause > nul");
36. return EXIT_FAILURE;
37. }
38.
39. cout << "RPM succeeded. Overwritten successfully.";
40.
41. BOOL closeHandleReturn = CloseHandle(hProcess);
arnakena is offline
Similar Threads
[Tutorial] Getting Started With Game Hacking: The Definitive 18th September 2018 12:08
Quicktime Programming for Beginners 71
Guide (Part 1) PM
[Discuss] New to Coding / Game Hacking theghost2905 Counterstrike Global Offensive 14 5th September 2017 10:56 AM
[Help] A Practical Place to Start into Gamehacking? givemehax General Programming and Reversing 3 6th December 2015 12:43 PM
[Discuss] Practical C++ Tatez C and C++ 2 7th July 2013 03:33 PM
Tags
process, memory, hacking, read, external, program, named, game, exercise, target
Forum Jump
Programming for Beginners Go