10. There are three important things at this window that we should pay attention to:
->The pointer is stored at Tibianic.dll
->The pointer’s address is "Tibianic.dll"+000FB10C;
->The pointer’s offset is 0x4 (hexadecimal number);
Remember what i’ve said before: the pointer is the string and the offset is the string’s length.
Well, now some explanation is needed.
Most of the data that Tibia uses is stored on its own process (Tibia.exe) as there isn't any DLL at Tibia's folder.
Well, Tibianic has one tricky thing over here.
As we’ve seem above, some data (including your character’s health) is stored at Tibianic.dll (which explain why we can’t just direct look for it using CheatEngine).
So, we’ll read some data from Tibianic.exe and some from Tibianic.dll. So, we need to save both base address.
On C# I’m using the following code to read both:
Code:
Process[] processes = Process.GetProcessesByName("Tibianic");
Process process = processes[0];
_tibianic.ProcessID = process.Handle;
_tibianic.ProcessBase = process.MainModule.BaseAddress;
ProcessModuleCollection modules = process.Modules;
foreach (ProcessModule i in modules)
{
if (i.ModuleName.ToLower() == "tibianic.dll")
{
_tibianic.DLLBase = i.BaseAddress;
break;
}
}
After saving this values, we’re about to see how to read a pointer value.
Recalling the example above, the pointer isn’t what we’re looking for (bacon). It just shows de path (string).
So, as we already know about that there is a string (pointer address we’ve got on CE), we need to hold it (read what is stored at this address).
This is my C# code:
Code:
//Address we’ve got from CE
static IntPtr HealthPointer = new IntPtr(0x000FB10C);
//This is the first pointer we must read
//It is located at Tibianic.dll + HealthPointer
int pointer = _tibianic.DLLBase.ToInt32() + HealthPointer.ToInt32();
//This useless variable is needed for ReadProcessMemory API
IntPtr bytesRead;
//Read the HealthPointer value
//Remember that this memory address will one store another address
//byte[4] = long
var buffer = new byte[4];
ReadProcessMemory(_tibianic.ProcessID, new IntPtr(pointer), buffer, 4, out bytesRead);
pointer = BitConverter.ToInt32(buffer, 0);
After the code above, we already found our string and hold it. But now we need to follow the string until find our precious bacon <3
Remember what I’ve said about string’s length? As we need to walk the string, we’ll sum that length to our pointer:
Code:
//Health Pointer Jump
static IntPtr HealthOffset = new IntPtr(0x4);
//Here we add the offset that we've found on CheatEngine
pointer = pointer + HealthOffset.ToInt32();
Jesus fucking Christ, we’ve found our fridge!
Now, we just need to open it and get bacon. Which means:
Code:
//Then, we read the memory again, now with the correct address
ReadProcessMemory(_tibianic.ProcessID, new IntPtr(pointer), buffer, 4, out bytesRead);
//And there is the final result!
Health = BitConverter.ToInt32(buffer, 0);
That is all, folks.
I’ve created a simple Console Application on Visual Studio 2012 (C#) that is doing exactly what I’ve explained above (check first post).
Hope this guide can help you guys.
Ash Katchup.