Deprecated: The behavior of unparenthesized expressions containing both '.' and '+'/'-' will change in PHP 8: '+'/'-' will take a higher precedence in /home/iano/public_html/tpforums-vb5/forum/includes/class_core.php on line 5842

PHP Warning: Use of undefined constant MYSQL_NUM - assumed 'MYSQL_NUM' (this will throw an Error in a future version of PHP) in ..../includes/init.php on line 165

PHP Warning: Use of undefined constant MYSQL_ASSOC - assumed 'MYSQL_ASSOC' (this will throw an Error in a future version of PHP) in ..../includes/init.php on line 165

PHP Warning: Use of undefined constant MYSQL_BOTH - assumed 'MYSQL_BOTH' (this will throw an Error in a future version of PHP) in ..../includes/init.php on line 165

PHP Warning: "continue" targeting switch is equivalent to "break". Did you mean to use "continue 2"? in ..../includes/functions_navigation.php on line 588

PHP Warning: "continue" targeting switch is equivalent to "break". Did you mean to use "continue 2"? in ..../includes/functions_navigation.php on line 612

PHP Warning: Use of undefined constant archive_postsperpage - assumed 'archive_postsperpage' (this will throw an Error in a future version of PHP) in ..../archive/index.php on line 456
Addresses: Automatic Updates [Archive] - Forums

PDA

View Full Version : Addresses: Automatic Updates



Blequi
01-15-2014, 05:47 AM
Addresses: Automatic Updates




Abstract

After a few months programming my cheats for Tibia, I knew how to find several addresses I was using
and each update, it was just a repetitive task of searching for specific things in Cheat Engine (www.cheatengine.org (http://www.cheatengine.org)) to find such addresses.

Moreover, whenever a update comes, Blackd releases a list of addresses (http://www.blackdtools.com/forum/showthread.php?61387-10-31-Blackd-Tibia-addresses-10-31) which he is currently using and since my first days of tibia cheating, I was thinking:

Why every list he begins with:



; [[[[[[[[[[[[[[[[[[[[[[[[[[[
; BEGIN AUTOMATIC UPDATE ZONE


and ends with:



; ]]]]]]]]]]]]]]]]]]]]]]]]]]]
; END - AUTOMATIC UPDATE ZONE

?

Back in the time when I was starting out, I didn't know that was possible to update addresses just by scanning the Tibia's memory like CE (Cheat Engine) does.

So, this is our goal at the end of this tutorial: learn how to search for some addresses we want and update them automatically.

Scanning the Tibia.exe memory looking for a byte (or bit) array, we can find our desired address.


Requirements

As any programming task we need to complete, we have to assume a few constraints:



You do understand the basic programming concepts like what an array is.


To follow the examples, you might previously know some information about them and the region around the address you are trying to "automatically" find (will be discussed in details in the main portion of the tutorial).






Introduction



Common data types



What is a bit?
Basically, an option: 0 or 1.


What is a byte?
An array of 8 bits, i.e., { (0 or 1), (0 or 1), ..., (0 or 1) } in the left-right order (assume this order from now on). It leads to any number n in the 0 <= n <= 255 = (2^8 - 1)


What is a unsigned short (or word)?
An array of 16 bits (consequently, an array of 2 bytes). Ex: Any number n in the 0 <= n <= 65535 = (2^16 - 1) range


What is a unsigned int (or dword)?
An array of 32 bits (consequently, an array of 4 bytes or an array of 2 words). Ex: Any number n in the 0 <= n <= 4294967295 = (2^32 - 1) range


What is a unsigned long (or qword)?
An array of 64 bits (consequently, an array of 8 bytes or an array of 2 dwords). Ex: Any number n in the 0 <= n <= 18446744073709551615 = (2^64 - 1) range


What is a string? (raw data)
An arbitrary array of bits (its raw data relies upon the character encoding, but for our purposes, each character of the Tibians string is uniquely translated to (and from) a byte, so it's an array of bytes for our purposes)


Example:


"hello" <-> { 'h' <-> 104, 'e' <-> 101, 'l' <-> 108, 'l' <-> 108, 'o' <-> 111, 0 }
<-> { 104, 101, 108, 108, 111, 0 }

0 at the end of the array is there to tell it's the end of the string.






How does a memory scanner work?



As we have seen, all the data comes down to an array of bits or bytes. In most cases, the scanner will convert the input (word, dword, qword, string, whatever) to a byte array and perform a search for this byte array.

So, a memory scanner works by searching for a byte array in the memory. In rare cases like storing data as flags [EX: player status (Is Poisoned, Is Electrified, Is Burning, etc)] (or any other manner to store data directly in bits), we need to find the address of the correct bit (not byte).


Our problem is often to find an int (dword), a boolean, a byte, a flag-like value. From our previous experience using CE, we know that trying to find an int in the memory
often leads to several addresses rather than a single address (our desired address). The reason is that two (or more) variables have the same value at some point




int shielding = 100;




int hp = 100;




.
.
.




int mana = 100;


and if we search for 100 to get the shielding address, we will get a ton of addresses to guess the right one.


Have you ever tried to find yours character name in the battle list? It was pretty easy to find or not? I guess your answer was "Yes, it was easy like to steal a kid's candy!".
But did you think why it was so easy? If not, the answer is pretty simple. In general, it's an array of bytes with size other than 4 (probably higher).



you: Hmm, but why the heck this 4 is so special?


me: Well, in the study-case, int is the most used data in Tibia and another games as well, I guess. Also, Tibia is a x86 process. I don't cheat in x64 processes, but probably they have the same "problem" when you are trying to find values 8-bytes long due pointers length.


you: Hmm, so the solution is to search for anything with size higher than 4 to avoid several addresses. But hey, my data is 4-byte long, what do I do?


me: Don't search for your data. Instead, look the region around your address, find something you are confident will be there and is longer than 4 bytes (strings are lovely candidates as also sequence of ints) and search for it. Later, just offset your result to the data you want.




The procedure above described the key point of how to decide the correct address. The most important is not the data itself, but the region around it, because things are kept (or grouped) in structs most of the times.

Blequi
01-15-2014, 05:47 AM
Solution

The sketch of the method can be summarized as follows:

Steps



Read the static memory from the Tibia.exe module into your internal byte array. Do it in a single step, otherwise your app could spend a lot of time reading the whole memory, since it is a huge region. Let this internal byte array be named buffer



Get the Tibia.exe module.


Get base address from the module. ("lpBaseOfDll" field of MODULEINFO structure http://msdn.microsoft.com/en-us/library/windows/desktop/ms684229%28v=vs.85%29.aspx or "modBaseAddr" field of MODULEENTRY32 structure http://msdn.microsoft.com/en-us/library/windows/desktop/ms684225%28v=vs.85%29.aspx)


Get module size from the module. ("SizeOfImage" field of MODULEINFO structure or "modBaseSize" field of MODULEENTRY32 structure)


At the base address, the count of bytes you must read from Tibias memory is the module size (cache the whole static memory). This step uses the following concept: Every address in the static memory can be seen as an offset like "baseAddress + offset". (It is the same when you get the address from Cheat Engine: "Tibia.exe" + address)




Now that you know the basic theory to properly choose your good candidates to search for, you will just pick by hand a very specific byte array (with size higher than 4).


Search in the buffer for the existence of the byte array from the previous step.


Now you are supposed to have just a few addresses. Let's say you ended up in 3 addresses always. Well, you'll have to use additional (simple) logic to decide between them.





Since the step 1) and 3) I will be using frequently and aren't address specific (together, they form the scanner core) , I'll leave it here: ((2) & (4) you have to think apart)



1)


[DllImport("kernel32.dll")]
static extern int ReadProcessMemory(
IntPtr processHandle,
IntPtr address,
[In, Out] byte[] buffer,
int size,
out IntPtr numberOfBytesRead
);

[DllImport("user32.dll")]
static extern IntPtr FindWindow(
string className,
string windowTitle
);

[DllImport("user32.dll")]
static extern int GetWindowThreadProcessId(
IntPtr windowHandle,
out int processId
);

byte[] GetBuffer()
{
IntPtr tibiaWindow = FindWindow("TibiaClient", null);
if (tibiaWindow == IntPtr.Zero)
throw new Exception("Tibia not found");

int processId = 0;
GetWindowThreadProcessId(tibiaWindow, out processId);

Process process = Process.GetProcessById(processId);

ProcessModule module = process.MainModule;
IntPtr baseAddress = module.BaseAddress;
int moduleSize = module.ModuleMemorySize;

IntPtr processHandle = process.Handle;

byte[] buffer = new byte[moduleSize];

IntPtr numberOfBytesRead;
ReadProcessMemory(processHandle, baseAddress, buffer, moduleSize, out numberOfBytesRead);

module.Dispose();
process.Dispose();

return buffer;
}

3)



bool BufferContains(byte[] buffer, int index, byte[] value)
{
int end = index + value.Length;
for (int i = index; i < end; i++)
if (buffer[i] != value[i - index])
return false;

return true;
}
int GetNextAddress(byte[] buffer, int offset, int end, byte[] value)
{
for (int address = offset; address < end; address++)
if (BufferContains(buffer, address, value))
return address;

return -1;
}
List<int> Scan(byte[] buffer, byte[] value)
{
List<int> addresses = new List<int>();

int address = -1;
int offset = 0;
int end = buffer.Length - value.Length;

do
{
address = GetNextAddress(buffer, offset, end, value);

if (address == -1)
break;

addresses.Add(address);
offset = address + 1;
}
while (offset < end);

return addresses;
}

Blequi
01-15-2014, 05:48 AM
Concrete Examples



You can find samples in C++/C# at the end



Battle List



How do you manually find the battle list start address?



A common (and pretty easy) way to find it is:



Open CE and find yours character name address (it can lead to 2, 3 or even more static addresses).


Then you have to browse memory and look to the memory and "recognize" from previous updates. (Creatures disposed in an array where each creature has its id, name, position and so on)


If you got the right one, scroll up the memory viewer until you find the first creature id, located -4 bytes from the creature name.








So, we will apply a similar procedure to find the battle list start address:



As I have shown in the solution above, apply step 1) and move on to step 2) from the solution.


Strings are good enough to find as explained before and we need our character's name to mimic the manual procedure. Moreover, in the latest updates, our character name is written in the Tibia window title once we are logged in. Then we are going to grab our characters name from there (of course, supposing you are logged in). Step 2) done.


Search for it and find a list of addresses. Step 3) done.

http://i.imgur.com/w5BW7sQ.png


Luckly, we found a single address, otherwise we will have 2+ addresses and that's bad, because we must have a single address. This is time to apply our additional logic (step 4). We know that right after the creatures name, there are 3 numbers (known as creature position): z, y and x, respectively (Tibia 10.31). Before the name its id. It seems to me a valuable data to put certain conditions and decide if the address we are analysing is good enough.

http://i.imgur.com/1Z1hAlP.png

That being said, if these supposed z, y and x satisfy the following condition together with the number at -4 (creature id) != 0:


(id != 0) && (0 <= z && z <= 15) && (30000 <= y && y <= 35000) && (30000 <= x && x <= 35000)


I feel confident enought that we are, indeed, inside the battle list. Note it's my logic, it's up to you find a way to solve the puzzle.


All in all, we have the address which points to the battle list. So, loop the battle list in the opposite way (decreasing the index) and stop when we don't find creatures anymore. (loop until the first creature id)


At the end, you'll have the battle list start address.







Tiles Pointer



We have found an useful address that is Battle List start. If the way to reach the battle list start address was a bit fancy for you, you'll like how tricky might be to find the Tiles Pointer to the array of tiles, because the array is not in the static memory. Then, this time we need to loop through each address and check for some array in the next level containing our characters id or something like that, right? Who knows.

First, take a look at the region around the pointer:

http://i.imgur.com/FPwDK8e.png

Good news, plenty of useful information. The best info for our searching purposes are dimensions X followed by Y followed by Z, because we can group these 3 numbers (4-byte long each) and it forms a 12-byte long array (remember, arrays with size higher than 4 bytes are cool, then 12 is amazing).



18 = { 0x12, 0, 0, 0 } as byte array
14 = { 0xE, 0, 0, 0 } as byte array
8 = { 0x8, 0, 0, 0 } as byte array



-> dimensions = { 0x12, 0, 0, 0, 0xE, 0, 0, 0, 0x8, 0, 0, 0 }. Then it's our desired "very specific array" from step 2).

If we still found many addresses in the scan pointing to a data like this, we can just check if the value at -0x14 == 2016 to make sure we are right. Once found, do TilesPointer = address - 0x10.



Experience


I'll describe in just one phrase for you: search for the .pic file name in memory, because your exp is really close.







Conclusion

As we have shown, using a cache of the Tibia static memory and looping through the cached memory looking for a smartly chosen array we can reach our desired address, even if not a single address has been found.

I have written two sample code (working at the present date for Tibia 10.31) coding these 3 given examples, C++ (http://pastebin.com/vGJFaGvG), C# (http://pastebin.com/zehnkL2i) if you want to have a source to lookup and get some help.

Now, I think you have a lot of addresses to auto update and for sure you'll code them. Have fun practicing on your own addresses.

The main purpose is to do the update faster, not to make something auto update forever. As a notice, you should notice that I used some specific constants like offsets, battle list step and a lot of specific things, but the core idea is still the same. For example, my update before these things were like 1 hour long, now it's from 5 to 10 minutes in a small update, because I need to double check all the addresses.


Acknowledge

Blackd: for his "BEGIN AUTOMATIC UPDATE ZONE" / "END AUTOMATIC UPDATE ZONE"

DarkstaR
01-15-2014, 06:03 AM
Good tutorial.

You might want to look into using debug strings to find addresses, though. Insanely OP. I have a fuckton of addresses, so I've not converted all of mine to them yet, but using the debug strings with a simple CheatEngine lua script can work wonders. Scan for the strings, then search for those addresses after PUSH operations, then, depending on what you're looking for, you can backtrack to the first INT3, look for specific function calls, detect switches, etc.

jah
01-15-2014, 01:16 PM
Respect for posting :)

I agree with DarkstaR that going through the code file seem to be the most obvious way to do it. Still, there are some issues that show up with any method so making a bot that auto detects the memory locations independant wont be possible so easily and we wouldnt gain something by allowing the crackers to have less work to crack the bots and reuse them without paying, if its a commercial one.
If you might want some inspiration, gimme a private message and I could help you out with auto address topic.

wgrzelak
01-15-2014, 01:57 PM
Thanks

Way to check gui addr


byte[] value = ASCIIEncoding.Default.GetBytes(module.FileName.Rep lace(".exe", ".spr"));
//find this address + 168


Conncted


if (gui != -1 && BitConverter.ToInt32(buffer, gui + 0x937C) == 11) //we find connected adress


Containers


byte[] value = ASCIIEncoding.Default.GetBytes("c:\\clients\\tibiaplayer_bugfixes\\GUI.h");
//find this address + 0x18

Blequi
01-15-2014, 02:11 PM
Thanks

I'm glad it's actually helping someone.

Indeed, once you know how to find all the addresses, it's just matter of applying a simple logic to update them all at once and let the update day really easy / fast.

jo3bingham
01-15-2014, 09:30 PM
Nicely written.

wgrzelak
01-15-2014, 09:58 PM
Messages on screen


#region Proxy Text
int GetProxyText(byte[] buffer)
{
byte[] value = new byte[12] { 0x1, 0x0, 0x1, 0x0, 0x80, 0x02, 0x0, 0x0, 0xE0, 0x1, 0x0, 0x0 };

List<int> addresses = Scan(buffer, value);
int count = addresses.Count;
int dimensions = 0;

for (int i = 0; i < count; i++)
{
dimensions = addresses[i];

if (BitConverter.ToInt32(buffer, dimensions - 0x20) == 65536)
return dimensions + 0x27C;
}

return -1;
}
#endregion


How to find player id? find ur pos on battlelist, get your id, find addresses by your id and try to find array like id,x,y,z

btw, Blequi : how you find connected address?

Blequi
01-15-2014, 10:09 PM
Good tutorial.

You might want to look into using debug strings to find addresses, though. Insanely OP. I have a fuckton of addresses, so I've not converted all of mine to them yet, but using the debug strings with a simple CheatEngine lua script can work wonders. Scan for the strings, then search for those addresses after PUSH operations, then, depending on what you're looking for, you can backtrack to the first INT3, look for specific function calls, detect switches, etc.

Yes, you, Sketchy and szulak have pointed me this out. For sure I'll try more advanced ways in the future when I get some free time.


by allowing the crackers to have less work to crack the bots and reuse them without paying, if its a commercial one.

Yes, this was the main point I took into consideration when releasing this work. However, I thought that a so simple way to such annoying task should be shared regardless the user bad/good usage.


Messages on screen


#region Proxy Text
int GetProxyText(byte[] buffer)
{
byte[] value = new byte[12] { 0x1, 0x0, 0x1, 0x0, 0x80, 0x02, 0x0, 0x0, 0xE0, 0x1, 0x0, 0x0 };

List<int> addresses = Scan(buffer, value);
int count = addresses.Count;
int dimensions = 0;

for (int i = 0; i < count; i++)
{
dimensions = addresses[i];

if (BitConverter.ToInt32(buffer, dimensions - 0x20) == 65536)
return dimensions + 0x27C;
}

return -1;
}
#endregion


How to find player id? find ur pos on battlelist, get your id, find addresses by your id and try to find array like id,x,y,z

I can bet your next update you will just hit a button and puff, done. :D

wgrzelak
01-15-2014, 10:16 PM
I can bet your next update you will just hit a button and puff, done. :D

Yes, in my project i can find very fast addresses what i needed but if i can faster so why not? :D

Blequi
01-15-2014, 10:28 PM
btw, Blequi : how you find connected address?

It's right after the hotkey items id array (+ 0xC4). Set some sequence of hotkeys (Use With...) at your client and you're done.

astra
01-26-2014, 01:18 AM
How to find this vv addresses with this method ?



public static int SendStreamLength = 0x9E9768 - 0x400000 + (int)baseAdress; //10.32
public static int SendStreamData = 0x7C8D20 - 0x400000 + (int)baseAdress; //10.32
public static int SendPacketCall = 0x525640 - 0x400000 + (int)baseAdress; //10.32
public static int PrintFps = 0x46E566 - 0x400000 + Convert.ToInt32(baseAdress); //10.32
public static int PrintName = 0x4D5070 - 0x400000 + Convert.ToInt32(baseAdress); //10.32
public static int ShowFps = 0x96C761 - 0x400000 + Convert.ToInt32(baseAdress); // 10.32


Ps. It's awesome idea, thanks Blequi and wgrzelak for other methods :)

aluwama
01-30-2014, 03:11 PM
Just search for byte patterns, as in Olly...


bool DataCompare(const BYTE* pData, const BYTE* bMask, const char* szMask)
{
for(; *szMask; ++szMask, ++pData, ++bMask)
{
if(*szMask == 'x' && *pData != *bMask)
{
return false;
}
}
return (*szMask) == NULL;
}

DWORD FindPattern(DWORD dwAddress, DWORD dwSize, BYTE* pbMask, char* szMask)
{
for(DWORD i = NULL; i < dwSize; i++)
{
if(DataCompare((BYTE*)(dwAddress + i), pbMask, szMask))
{
return (DWORD)(dwAddress + i);
}
}
return 0;
}

FindPattern( dwBase, dwSize, "\x55\x8B\xEC\x8B\x00\x00\x00\x00" /*byte pattern to scan*/, "xxxx????" /*x for known bytes, ? for unknown*/ ) + 0x2 /*if you need to offset from that address*/;

DarkstaR
01-31-2014, 04:30 PM
I made this a while ago, might be a good starting point for some of you

https://code.google.com/p/codereload/

Blackd
03-20-2014, 11:02 PM
Nice forum thread.
Yes, patterns with some wildcard bytes -Olly style- That is the best solution for autoupdating any address.
If you can do something manually then a code can always do it for you automatically. An autoupdater just needs the right patterns.

A hint to people who would like to start working in his own private autoupdater:
- get some knowledge about assembly language
- get some experience at Ollydbg or similar programs
- for your first steps first disable ASRL with Microsoft EMET
- understand how to handle ASRL correctly until you don't need EMET

Have fun programming!

DarkstaR
03-20-2014, 11:20 PM
Nice forum thread.
Yes, patterns with some wildcard bytes -Olly style- That is the best solution for autoupdating any address.
If you can do something manually then a code can always do it for you automatically. An autoupdater just needs the right patterns.

A hint to people who would like to start working in his own private autoupdater:
- get some knowledge about assembly language
- get some experience at Ollydbg or similar programs
- for your first steps first disable ASRL with Microsoft EMET
- understand how to handle ASRL correctly until you don't need EMET

Have fun programming!

No need to do it with EMET, you can run a command in VS command prompt to disable it. You can also set a flag in PE header.