Introduction
I'm going to introduce to you some tools to code your own Zoom Hack.
I will use "League Of Legends" for this example, but you can reproduce those steps with any other games. That should work similarly.
We will need :
> CheatEngine (free :
)> League Of Legends in game client
> A langage which is able to use win32 API. (C, C++ or C# are the most common languages for that, there is some extensions for the other langages as lua, python, perl, etc., look for it on google)
Zoom Value
First of all, open a custom game with a smurf account, so you can do everything without disturb anything.
Go in the settings window, and change settings to set your client in windowed mode with the minimal resolution. We are going to switch very often between the LoLClient and CheatEngine, so it will be more comfortable.
Alright, we are ready to work.
Let's open CheatEngine, and open the League Of Legends.exe process.
The first step will be to find the zoom value.
Let's talk this value; We know some facts about it :
(1)- We don't know its exact value.
(2)- When we zoom out, its value increase
(3)- When we zoom in, its value decrease
(4)- Even when we move the camera, its value doesn't change
CheatEngine is a very powerful tool that will find for you any value in the memory of a process.
All you have to do is to find a way to tell to CheatEngine how the variable you are looking for is modified.
If you don't understand this, don't worry, you will understand with the following example :
First of all, go to your LoLClient, and zoom in, the most as you can.
Go back to scan all the variables with the setting "Unknown initial value" (1).
Then, go back to your client, and zoom out just a little.
Now, go back to CheatEngine, and do a "Next Scan" with the setting "Increased value" (2).
As you can see, there is +1,000,000 results, and we still don't know what is the value of our zoom.
Repeat this process (zoom out, scan decreased value) 5 or 6 times so we filter more values.
Now we get something like that :
Still 5,000+ results. This is not good yet. Now, reverse the process :
Zoom in a bit, and scan "Decreased value" (3). Repeat that 5 or 6 times again.
Now as you can see, when you zoom in / zoom out, you can see the values increasing or decreasing correctly, but there is still a lot of results (147 here, but it may differs everytime you launch a game)
Notice that if you try to move the camera position, some of those values will be modified; We don't want to work with those values, they are related with the zoom, but they are not the zoom value.
To filter them, move your camera position, but *dont touch the zoom*, and do a next scan with the setting "Unchanged Value" (4).
Only 14 results, with 2 differents values!
Let's try to change the value of the variable at the address 00B475A0, from 1148846080 to 1168846080.
Victory ! We got the address and the current value of our zoom.
But if you try to zoom in / zoom out in the client, you will see that it doesn't work.
Why ? Because we only modified the *current zoom* value, but not the variable which defines what is the *maximum zoom* value allowed.
Max Zoom Value
Somewhere in the code, there is a variable defining the maximum value of the zoom.
All we have to do for finding it, is to zoom out the most possible to find the value of the max zoom.
Now we know that "1158455296" is the value of the max zoom, let's do a new scan of this value with the setting "Exact Value".
We find our zoom address at 00B475A0, but also a new one at 00B38C48 !
This is our Max Zoom address. You can modify it to something like 1168455296, go back to your client, and enjoy the unlocked zoom.
Coding
Even if we got the address of the maxzoom, this address may change everytime you launch the game, and probably when a new patch is released.
We don't want to launch CheatEngine everytime we want to hack the zoom, so we are going to code something for that.
How to do that ?
In the memory, some bytes around the max zoom value *never change* everytime you play a game. We will call those bytes the "pattern".
Basically, all we have to do is to parse the memory of League Of Legends.exe, find the pattern, so we got the address of our max zoom.
First of all, we have to get a correct pattern.
Right click on the address of the current value (00B475A0), and chose "Browse this memory region".
It will opens a new window of the dump of the current memory at this address.
Keep a look at this window, and, in the client, try to zoom in / zoom out : The values in the dump will be colored in red when they change:
It seems that only 3 bytes are modified, all the other are always the same when we play.
Let's keep a track of those bytes : select them, and copy them in notepad.
Do the same thing for the max value address (00B38C48).
We got that :
Code:
Zoom Value (00B475A0) : 00 40 CE 44 34 4B A3 00 18 9C A7 00 04 9C A7 00 00 00 00 00 24 4B A3 00 5C 9C A7 00 20 9C A7 00 Max Value (00B38C48) : 00 A0 0C 45 25 24 59 46 00 00 70 41 00 00 FA 43 01 00 00 00 00 00 60 42 00 00 34 43 00 00 80 3E
We need to :
- Open the League Of Legends.exe process
- Write our new max zoom value at the right address
There is a lot of manners to do it.
I will chose the simpliest one :
1- Get the handle of the window
2- Get the pid of the process
3- Open that process
4- Get the address of max zoom with the pattern
5- Modify the memory at this address
Code:
int pid; HWND window = FindWindowA(NULL, "League of Legends (TM) Client")); // 1 GetWindowThreadProcessId(window, &pid); // 2 HANDLE process = OpenProcess(PROCESS_ALL_ACCESS, 0, pid); // 3
We need a pattern finding function.
I use this one, feel free to copy it (this is a well known piece of code that you can find everywhere on internet)
Code:
DWORD
find_pattern_process (HANDLE process, DWORD start, DWORD end, unsigned char *pattern, char* mask)
/*
* Exemple :
* char *pattern = "\x00\xC0\xB7\x44\x00\xC0";
* DWORD address = find_pattern_process(process, 0x800000, 0xC00000, (PBYTE) pattern, "xxx??x");
*/
{
DWORD size = end - start;
unsigned char *buffer = (unsigned char *) malloc(size + 1);
if (ReadProcessMemory(process, (PVOID) start, buffer, size, NULL) == FALSE)
{
warning("ReadProcessMemory failed.");
return 0;
}
else
{
DWORD address = find_pattern(buffer, size, pattern, mask);
if (address)
return start + address;
}
return 0;
}
int
compare_pattern (const unsigned char *buffer, const unsigned char *pattern, const char *mask)
{
for (;*mask;++mask, ++buffer, ++pattern)
{
if (*mask == 'x' && *buffer != *pattern)
return 0;
}
return (*mask) == 0;
}
DWORD
find_pattern (const unsigned char *buffer, DWORD size, unsigned char *pattern, char *mask)
{
for (int i = 0; i < size; i ++)
{
if (compare_pattern((buffer + i), pattern, mask))
return i;
}
return 0;
}
- You have to create a mask (x = i want to find the same byte, ? = I don't care about this one)
- You create a buffer containing your pattern.
So, for our example, if we want to find the max zoom address:
Code:
DWORD
get_max_zoom_offset (HANDLE process)
{
char *mask = "????xxxxxxxxxxxxxxxxxxxxxxxxxxxx";
char *pattern = "\x00\xA0\x0C\x45\x25\x24\x59\x46\x00\x00\x70\x41\x00\x00\xFA\x43\x01\x00\x00\x00\x00\x00\x60\x42\x00\x00\x34\x43\x00\x00\x80\x3E";
return find_pattern_process(process, 0x800000, 0xC00000, (PBYTE) pattern, mask);
}
Now that we got the address, all we have to do is to write at this address.
I use this function to write an int in a process at a chosen address :
Code:
int
write_memory_as_int (HANDLE process, DWORD address, unsigned int value)
{
unsigned char buffer[sizeof(int)];
DWORD bytes_read;
int32_to_bytes(value, buffer);
if (!WriteProcessMemory(process, (PVOID) address, buffer, 4, &bytes_read))
{
warning("WriteProcessMemory failed.");
return 0;
}
return 1;
}
Code:
int pid; HWND window = FindWindowA(NULL, "League of Legends (TM) Client")); // 1 GetWindowThreadProcessId(window, &pid); // 2 HANDLE process = OpenProcess(PROCESS_ALL_ACCESS, 0, pid); // 3 DWORD max_zoom = get_max_zoom_offset(process); // 4 write_memory_as_int(process, max_zoom, 1168455296)); // 5
And here is it !
Now everytime you have a League Of Legends.exe opened and in game, if you launch this program, it will find, and patch for you the zoom max value !
Of course, this tutorial is only about League Of Legends, but as I said, the process is similar for the other games.
- Find the current zoom value
- Zoom out
- Find the max zoom value
- Patch it.
Enjoy !






