View Full Version : Current Container's structure
Lolrapa
03-12-2014, 02:26 AM
Hello, I've been trying to update my library for the new Tibia version and I found a big issue when I tried to read the container structure.
I know that the start continer address is 0x5EDA40 + baseAddress, I figured out that that address is a pointer to the next image's memory zone:
152
Where the red rectangle is the ammount of opened containers.
Also I noticed that the values like 0x80000000 has something to do with the open state of a container where 80000000 means closed and 8B000000 means open, but also there are values like 8C000000 (dont know what they means). If you can explain me how does the container system works, I'll be very grateful.
DarkstaR
03-12-2014, 08:47 AM
It's a red-black tree of pointers.
Ash Katchup
03-12-2014, 01:47 PM
https://www.youtube.com/watch?v=CrCClRcLTfU
https://www.youtube.com/watch?v=mo2-DE05Z10
Ash Katchup
03-12-2014, 04:24 PM
Also:
http://tpforums.org/forum/threads/5881-New-container-structure-traversing-in-C
http://tpforums.org/forum/threads/5752-New-Containers-Structure?p=50770&viewfull=1#post50770
Lolrapa
03-12-2014, 09:03 PM
It's a red-black tree of pointers.
https://www.youtube.com/watch?v=CrCClRcLTfU
https://www.youtube.com/watch?v=mo2-DE05Z10
Thank both of you! After learning some things about trees i was able to figure out how does the id system works :)
Now im trying to get the items inside the containers.
Thank you!
DarkstaR
03-13-2014, 04:56 PM
Thank both of you! After learning some things about trees i was able to figure out how does the id system works :)
Now im trying to get the items inside the containers.
Thank you!
Items are an std::vector
ottizy
03-13-2014, 05:58 PM
Items are an std::vector
So while injected, you could cast the items to a vector? Tried it but didn't work out very well
DarkstaR
03-13-2014, 06:05 PM
So while injected, you could cast the items to a vector? Tried it but didn't work out very well
You would need to use the same exact optimization options, the same exact std compilation options, and the same exact prototype that Tibia uses. IIRC, the prototype is std::vector<tItem>, which means you would cast to std::vector<tItem>*. tItem is their exact item structure, including the square color and the lastUpdate counters.
You can tell its a vector because the items are stored in a linear fashion, and because it holds a pointer to both the first and last item. Also because everytime an item is added, you can see the pointers to the array change and get farther apart, meaning they don't do a .reserve(containerCapacity). Noobs.
Blequi
03-13-2014, 10:01 PM
So while injected, you could cast the items to a vector? Tried it but didn't work out very well
The following is a code to prove what DarkstaR says (it must be compiled with MSVC 2010, release build... not sure about other compilers):
// dllmain.cpp : Defines the entry point for the DLL application.
#include "stdafx.h"
#include <sstream>
#include <vector>
HMODULE dll;
struct Item
{
int offsetH0;
int count;
int id;
int offsetHC;
int offsetH10;
int offsetH14;
int offsetH18;
int offsetH1C;
int offsetH20;
};
typedef std::vector<Item> Items;
extern "C" __declspec(dllexport)
void WINAPI Test()
{
HMODULE tibiaExe = GetModuleHandle(NULL);
DWORD baseAddress = (DWORD)(tibiaExe);
DWORD containers = 0x5EDA40;
DWORD addr = *(DWORD*)(baseAddress + containers);
addr = *(DWORD*)(addr + 0x8);
addr = *(DWORD*)(addr + 0x4);
addr = *(DWORD*)(addr + 0x10);
Items* items = (Items*)(addr + 0x54);
Items::const_iterator end = items->end();
for (Items::const_iterator item = items->begin(); item != end; item++)
{
std::stringstream s;
s << "[" << item->id << "] = " << item->count << std::endl;
MessageBoxA(0, s.str().c_str(), "Current item", MB_OK);
}
}
extern "C" __declspec(dllexport)
void WINAPI Uninject()
{
FreeLibraryAndExitThread(dll, 0);
}
BOOL APIENTRY DllMain( HMODULE hModule,
DWORD ul_reason_for_call,
LPVOID lpReserved
)
{
switch (ul_reason_for_call)
{
case DLL_PROCESS_ATTACH:
{
dll = hModule;
}
break;
case DLL_THREAD_ATTACH:
case DLL_THREAD_DETACH:
case DLL_PROCESS_DETACH:
break;
}
return TRUE;
}
To test this code, first build this dll as mentioned above... open a tibia client and open a (single) container
To test "inject" methods within cheat engine, we can follow such steps (assume your dll name is DllTest and its dll path is C:\TEMP\DllTest.dll)
open cheat engine and attach to some tibia.
open cheat engine Auto Assemble (Memory Viewer > Tools > Auto Assemble, or simply (Ctrl + A))
execute this code there
loadlibrary(C:\TEMP\DllTest.dll)
alloc(code, 512)
CreateThread(code)
code:
call DllTest.Test
call DllTest.Uninject
ret
Remember to set C:\TEMP\DllTest.dll to your dll path.
DarkstaR
03-13-2014, 10:06 PM
You can also cast the container structure to an std::map<int, tcontainer>, I believe.
ottizy
03-13-2014, 10:08 PM
Neat, I suppose it still would be easier to make your own container for the items if you want it to work in both debug and release mode.
Blequi
03-13-2014, 10:13 PM
You can also cast the container structure to an std::map<int, tcontainer>, I believe.
Yeah, Stiju told it too in the first (new container) thread.
Neat, I suppose it still would be easier to make your own container for the items if you want it to work in both debug and release mode.
yeah, actually I wrote a fully templated code to work with STL like std::vector, std::map, std::list, etc for both memory reading (injected and not injected)
DarkstaR
03-13-2014, 10:31 PM
Neat, I suppose it still would be easier to make your own container for the items if you want it to work in both debug and release mode.
You can also create a header which uses #pragma to turn off debug info and optimization for std containers so it would work it both modes. Something like
stdcontainers.h
#pragma whateverturnsoffoptimization
#undef _DEBUG
#include <vector>
#include <map>
#define _DEBUG
#pragma turnonoptimization
something like that.
Powered by vBulletin® Version 4.2.5 Copyright © 2024 vBulletin Solutions Inc. All rights reserved.