Click here to buy some Tibia gold in our shop

Results 1 to 3 of 3

Thread: [Linux][Tutorial]Reading Memory, Bypassing BattleEye and defeating Dma Tibia 12.31

  1. #1
    Join Date
    Nov 2018

    Default [Linux][Tutorial]Reading Memory, Bypassing BattleEye and defeating Dma Tibia 12.31

    Note: You must use python 2.7 for this , something changed in 3.7 that makes the code not work , im not sure what it was. I get no errors but the code just fails to find addresses so its probly some module change somewhere.
    In linux when we load a process a folder with the process id is created in


    Inside this folder we have a bunch of files that contain info on the process two of them are extremely useful to us.


    This contains the map of all memory addresses and points to classes/modules within our process lets take a look at tibias map:

    00400000-014ee000 r-xp 00000000 08:15 6441562                            /home/steven/.local/share/CipSoft GmbH/Tibia/packages/Tibia/bin/client
    021f6000-0a2a2000 rw-p 00000000 00:00 0                                  [heap]

    The actual file is alot bigger than this , but for now thats not to important. Next I used a tool called GameConqueror. This a simple tool just like cheat engine but without debugger stuff so its not detected. I wont talk your through how to find a address with this , its easy as pie and you should know this already. Anyway I am going to look for mana address in this tutorial so lets find it in GameConqueror for me it was at:


    Now of course if we reload tibia , this address will change and we cant attach a debugger without battleye blocking us. But heres the thing , we now know that
    5afe708 was used once to store our mana address. We also have a list of ranges in which memory is allocated and these ranges never change. So if we find the range that 5afe708 is in this range will always contain our mana so using the above we can at least narrow our search down to only hundreds of thousands of adresses rather than billions. Progress! Lets find the range below that contains "5afe708"

        def find_target_range(self):
            target = int("5afe708",16)
            maps_file = open("/proc/{}/maps".format(self.processid), 'r')
            for line in maps_file.readlines():  # for each mapped region                            
                    splitter = line.split(" ") #Split the line into spaces
                    region_low = int(splitter[0].split("-")[0],16) #region low of chunk
                    region_high =  int(splitter[0].split("-")[1],16) #region high of chunk
                    if target > region_low:
                          if target < region_high:
                                    returndata = {"region_low" : region_low,
                                                    "region_high" : region_high}
    this gives us:
    {'region_low': 35610624, 'region_high': 178696192}

    I am converting values to ints , rather than there hex offset just because its easier to do math on however if you convert them to hex you can see we have out memory range.

    Now stick with me. This will seem convuluded at first:
    Next I used GameConqueror to find my mana address. I then browsed memory on that location and copied backwards as much of the hext data as I could this gave me a long hex string. I made a new python script like so:
    import textwrap
    hexstring = """F8 CD 0D 20 6D 7F 00 00 2B 00 00 00 00 00 00 00
    F0 AE A3 38 6D 7F 00 ..........""" ###This is trimmed so I dont hit the char limit on forum
    hexstring = hexstring.replace(" ","")
    thelist = textwrap.wrap(hexstring, 16)
    for item in thelist:
    All this script does is to take my bytes from memory and spit them out in 8 byte chunks. I now used this site:

    to remove the duplicates and then saved the none dupes in 1.txt I then closed the game and repeated the above for the new mana address and saved as 2.txt. I did this again , 3.txt.

    Now i combined all 3 text files into one single text file list and used to count duplicates. I was looking for entrys with 3 counts. I got these:
           3 | 3900000000000000
           3 | 4800000000000000
           3 | 70D0780100000000
           3 | 9B18000000000000
           3 | A100000000000000
           3 | F0AA780100000000
    If you are confused what I just did , I just found the memory addresses near the address I want (mana) that never change. Even if we open a new client. All will become clear as to why shortly:

    the last value we extracted above seems the best to use for now:

    Infact this value can be found -120 bytes of our target mana address.

    remember earlier I said there was two interesting files in /proc/ ? The second one contains all our memory values! This is /proc/processid/mem.

    This is a raw byte file so we cant use it like a normal file , we have to use .open (as rb) .read() and .seek

    so our plan of attack is this:
    1.Get the address range from the map file, our target mana address is in there somewhere!
    2.We open our .mem file and jump to range start.
    3.We search every 8 bytes for F0AA780100000000.
    4.Once we find this we add the distance to our mana value (its exactly 120) this is our mana address.
    5.Read the above value.

    lets goo...

        def find_mana_address(self,heapdata):
            print("Scanning memory , this could take a few seconds....")
            mem_file = open("/proc/{}/mem".format(self.processid), 'rb')
   #Goto the start address of our heap
            memoryposition = region_low #Just a buffer so we know what address we are at currently
            while memoryposition<region_high: #Stop searching when we exit end of heap
                memoryposition = memoryposition +8
                count = 0
                while count<8: #Read every 8 bytes and stick them into a string
                    chunk = binascii.hexlify( 
                    chunks = chunks + str(chunk)
                    shifted_bytes = chunks.upper()
                if shifted_bytes == "F0AA780100000000":
                    print("Signature found at - " + str(memoryposition))
                    int_memory_address = (memoryposition+120)
                    print("Memory address is - " + str(int_memory_address))  
                    return int_memory_address
    This prints:
    Scanning memory , this could take a few seconds....
    Signature found at - 94777736
    Memory address is - 94777856
    94777856 is just the int for 5afe708 I added this to GameConqurer and indeed it works Below I have added a function to read this address and a loop that prints whenever our mana changes:

    Final Code:

    I ran out of space so stuck it on pastebin.

    The important thing about this is:
    We never interact with the game client at all. We are reading files from the operating system we call no functions what so ever on the game!
    Last edited by Darkbyte; 03-02-2020 at 04:14.

  2. #2
    Join Date
    Feb 2015


    Thanks you so much mat ei want to make a bot for myself this will help

  3. #3
    Join Date
    Feb 2015


    im having problem running you script i have instaled the python verson 2.7 ubuntu 18,.04

    rata@la-rata:~$ ./
    Traceback (most recent call last):
    File "./", line 85, in <module>
    heapdata = (testhandler.find_target_range())
    File "./", line 10, in find_target_range
    maps_file = open("/proc/{}/maps".format(self.processid), 'r')
    IOError: [Errno 2] No such file or directory: '/proc/14982/maps'

    Last edited by felipe93; 05-05-2020 at 05:55.

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts