• There is NO official Otland's Discord server and NO official Otland's server list. The Otland's Staff does not manage any Discord server or server list. Moderators or administrator of any Discord server or server lists have NO connection to the Otland's Staff. Do not get scammed!

Use cheat engine to find chat pointer address in Cheat Engine

Evil Mark

Active Member
Joined
Nov 23, 2008
Messages
1,707
Reaction score
32
I'm having problems finding the static pointer for the tibia chat in CE. I've tried typing a word that nobody has typed and then I get 2 values IN CE that match. I test them and eventually there is only 1 correct value.

So I go through the process of a pointer scan to get the static value but when i reset Tibia the static value always seems to be wrong. Could someone make a tutorial for this? I'm having problems.
 
You didn't mention the client.
Your static is relative to the module's base address which may change due to ASLR. Did you take that into account?
 
You didn't mention the client.
Your static is relative to the module's base address which may change due to ASLR. Did you take that into account?

Thanks for this information. I will look into it and see what information I can find.

@EDIT
So basically instead of looking for a dynamic base address which will change each time the application restarts. I just look for the function that executes the code where i "type" or "send" messages in-game?
 
Last edited:
Anyone got an idea why I can't get my lighthack to work?

C#:
    {
        const int PROCESS_ALL_ACCESS = 0x1F0FFF;

        [DllImport("kernel32.dll")]
        public static extern IntPtr OpenProcess(int dwDesiredAccess, bool bInheritHandle, int dwProcessId);

        [DllImport("kernel32.dll", SetLastError = true)]
        static extern bool WriteProcessMemory(int hProcess, IntPtr lpBaseAddress, byte[] lpBuffer, int dwSize, ref int lpNumberOfBytesWritten);


        static void Main(string[] args)
        {
            Process process = Process.GetProcessesByName("processnamehereobv")[0];
            IntPtr processHandle = OpenProcess(PROCESS_ALL_ACCESS, false, process.Id);

            var baseAddress = process.MainModule.BaseAddress;

            var lightChangeWithFloors = baseAddress + 0xD5D58;
            var lightChangeWithSpellsOrTorch = baseAddress + 0xCE0F5;

            int bytesWritten = 0;
            byte[] memoryInjection = { 0x66, 0xB8, 0xFF, 0xD7 };

            WriteProcessMemory((int)processHandle, lightChangeWithFloors, memoryInjection, memoryInjection .Length, ref bytesWritten);
            WriteProcessMemory((int)processHandle, lightChangeWithSpellsOrTorch, memoryInjection, memoryInjection .Length, ref bytesWritten);
            Console.ReadLine();
        }
    }

All the offsets are correct but I can't for the life of me figure out why this isnt working. It's my first time working with CE and would love some feedback on how to continue to get this process to work.

All the tutorials and guides I've read have said this is the way and that this is right but I'm missing something, I must be.
 
Last edited:
Try using IntPtr for handle.

What do you mean? The handle is already of type IntPtr when declared?

C#:
IntPtr processHandle = OpenProcess(PROCESS_ALL_ACCESS, false, process.Id);

@Edit oh you mean in the WriteProcessMemory. Let me check

@Edit It did nothing. @kay
 
Last edited:
What do you mean? The handle is already of type IntPtr when declared?

I meant here:
static extern bool WriteProcessMemory(IntPtr hProcess, IntPtr lpBaseAddress, byte[] lpBuffer, int dwSize, ref int lpNumberOfBytesWritten);
and remove int cast when calling.

You should also specify what exactly doesn't work. You're not getting handle? Calculated address is incorrect? Bytes are not written? Or it doesn't get your LH to work?
In case WriteProcessMemory returns 0 you can call GetLastError.
 
I meant here:
static extern bool WriteProcessMemory(IntPtr hProcess, IntPtr lpBaseAddress, byte[] lpBuffer, int dwSize, ref int lpNumberOfBytesWritten);
and remove int cast when calling.

You should also specify what exactly doesn't work. You're not getting handle? Calculated address is incorrect? Bytes are not written? Or it doesn't get your LH to work?
In case WriteProcessMemory returns 0 you can call GetLastError.

F29jKkJ.png

bXl7hEQ.png

I8ylXDH.png


Program.cs
C#:
    class Program
    {
        const int PROCESS_ALL_ACCESS = 0x1F0FFF;

        [DllImport("kernel32.dll")]
        public static extern IntPtr OpenProcess(int dwDesiredAccess, bool bInheritHandle, int dwProcessId);


        static void Main(string[] args)
        {
            Process process = Process.GetProcessesByName("client_ogl")[0];
            IntPtr processHandle = OpenProcess(PROCESS_ALL_ACCESS, false, process.Id);
            var baseAddress = process.MainModule.BaseAddress;

            Light.FullLight(processHandle, baseAddress);

            Console.ReadLine();
        }
    }

Light.cs
C#:
    public static class Light
    {
        [DllImport("kernel32.dll", SetLastError = true)]
        static extern bool WriteProcessMemory(IntPtr hProcess, IntPtr lpBaseAddress, byte[] lpBuffer, int dwSize, ref int lpNumberOfBytesWritten);

        public static void FullLight(IntPtr processHandle, IntPtr baseAddress)
        {
            IntPtr lightFloorChange = baseAddress + 0xD5D58;
            int bytesWritten = 0;
                
            //byte table representing assembler code to "call a function and insert new parameters/values"
            byte[] floorCode = { 0x66, 0xB8, 0xFF, 0xD7 };
            WriteProcessMemory(processHandle, lightFloorChange, floorCode, floorCode.Length, ref bytesWritten);
        }
    }

I'm getting a handle, not sure what you mean by calculated address is incorrect? Bytes might not be written because then I would expect it to work. Will look into it further with your feedback, thanks.
 
@Evil Mark you're using client_ogl, whilst CE shows client_ogl.sprintf_s module as a base.
That's why I asked if your address was correct. In CE add it to the list, so it shows the actual address and then check if the one passed to WriteProcessMemory actually matches.
 
@Evil Mark you're using client_ogl, whilst CE shows client_ogl.sprintf_s module as a base.
That's why I asked if your address was correct. In CE add it to the list, so it shows the actual address and then check if the one passed to WriteProcessMemory actually matches.

1wVMf2B.png
 
Use the same module shown by CE as a base, it doesn't necessairly have to be client_ogl.exe.
Also, if it's a pointer (judging by screenshot) you need to read where it points to first, and then write your bytes there. Otherwise you're writing to the pointer instead of the actual value.
If your WriteProcessMemory returns non-zero, it means your bytes were written but in a wrong place.
 
Use the same module shown by CE as a base, it doesn't necessairly have to be client_ogl.exe.
Also, if it's a pointer (judging by screenshot) you need to read where it points to first, and then write your bytes there. Otherwise you're writing to the pointer instead of the actual value.
If your WriteProcessMemory returns non-zero, it means your bytes were written but in a wrong place.

Having you answering my questions is gold, because I'm learning a lot right now just by googling the things you are talking about, thanks. Let's see what happens in next attempt :)
 
Back
Top