blackd
10-10-2016, 12:51
Ok, we need to get used to deal with this new kind of String. It is the one used by QT, the new system that Tibia 11 client uses now. The implementation of a QString is probably different depending OS and compiler. However, for us the only important implementation is the Windows implementation for the compiler that Cipsoft have choosen.
In our case, this is how a Tibia QString look:
08 00 00 00 06 00 00 00 07 00 00 00 10 00 00 00 5A 00 61 00 6E 00 65 00 72 00 61 00 00 00
Here we can read "Zanera"
Now, let's divide our example in parts:
PART0 = 08 00 00 00
PART1 = 06 00 00 00
PART2 = 07 00 00 00
PART3 = 10 00 00 00
PART4 = 5A 00 61 00 6E 00 65 00 72 00 61 00
PART5 = 00 00
You should understand the meaning of each part:
PART0 is usually the number of references at this moment.
- If PART0 is 0 then it means you are reading a destroyed string (invalid memory).
- Not confirmed: If PART0 is bigger than 1000 then it means this QString was moved to other memory place and then you should read PART0 as a pointer to the new start of the QString.
- In our example, we have a valid string and there are 8 memory structures that references this string.
- I only had 1 char in Zanera in my character list, however there must be 7 other places that reference it.
- For example: the structure that holds the current server that you are playing ("Qt5Core.dll" + 004555C8 > 8 > 320 > 18 > 60 > C)
- We still miss 6 places that references Zanera, but well, this is not really important here.
- However PART0 might be important in a future moment of your reverse enginering tasks.
PART1 is the size of the string. Well, this is easy to understand. In the case of Zanera the size = 6. This number is important so we can know how many positions we should try to read.
PART2 is the number of allocated positions. In this case it is 7. It means we can do an easy change of the string to something else with max size of 7 before we need to search a bigger place in memory to place the string. If you need to modify strings then you will have to check this.
PART3 is the offset. We should search the content at QString start address + offset. In our case offset = HEX 10 = 16 positions later. In most cases this is HEX 10.
PART4 is the string. It is unicode and Tibia does not really use it so you can ignore the 00 after each char.
PART5 are extra allocated memory positions (not part of the string) in this case PART2-PART1 = 1, that is, we still have enough memory to write 1 more character before this QString need a bigger memory place. Please be aware that we could have trash instead zeroes. Whatever you write in PART5 is not important because it is never read until PART2 says we should read up to this point.
In our case, this is how a Tibia QString look:
08 00 00 00 06 00 00 00 07 00 00 00 10 00 00 00 5A 00 61 00 6E 00 65 00 72 00 61 00 00 00
Here we can read "Zanera"
Now, let's divide our example in parts:
PART0 = 08 00 00 00
PART1 = 06 00 00 00
PART2 = 07 00 00 00
PART3 = 10 00 00 00
PART4 = 5A 00 61 00 6E 00 65 00 72 00 61 00
PART5 = 00 00
You should understand the meaning of each part:
PART0 is usually the number of references at this moment.
- If PART0 is 0 then it means you are reading a destroyed string (invalid memory).
- Not confirmed: If PART0 is bigger than 1000 then it means this QString was moved to other memory place and then you should read PART0 as a pointer to the new start of the QString.
- In our example, we have a valid string and there are 8 memory structures that references this string.
- I only had 1 char in Zanera in my character list, however there must be 7 other places that reference it.
- For example: the structure that holds the current server that you are playing ("Qt5Core.dll" + 004555C8 > 8 > 320 > 18 > 60 > C)
- We still miss 6 places that references Zanera, but well, this is not really important here.
- However PART0 might be important in a future moment of your reverse enginering tasks.
PART1 is the size of the string. Well, this is easy to understand. In the case of Zanera the size = 6. This number is important so we can know how many positions we should try to read.
PART2 is the number of allocated positions. In this case it is 7. It means we can do an easy change of the string to something else with max size of 7 before we need to search a bigger place in memory to place the string. If you need to modify strings then you will have to check this.
PART3 is the offset. We should search the content at QString start address + offset. In our case offset = HEX 10 = 16 positions later. In most cases this is HEX 10.
PART4 is the string. It is unicode and Tibia does not really use it so you can ignore the 00 after each char.
PART5 are extra allocated memory positions (not part of the string) in this case PART2-PART1 = 1, that is, we still have enough memory to write 1 more character before this QString need a bigger memory place. Please be aware that we could have trash instead zeroes. Whatever you write in PART5 is not important because it is never read until PART2 says we should read up to this point.