TRose.exe the library
So there comes a time when you decide ‘hey, I am going to have to edit the client to do this’ which is where my TRose library comes into use. I attempted to keep the interface to it as clean as possible which is why if you look at the code (I suggest you don’t
) you will probably be like ‘wtf is he doing’.
It works in the way that every class and its functions are defined in my library, I also have one function which must be used before all others (RoseAPI::Init()) this function goes through every class member functions and rewrites the first bytes of them to a JMP to the original code using my function ‘FixMemberFuncAddress’.
template<class T> void FixMemberFuncAddress(int troseAddr, T func){
CodeHook::ApplyJmpHook((unsigned char*)(*((void**)&func)), (unsigned char*)troseAddr, 0);
}
The crazy recasting of func is to get around the fact that you cannot convert a member function pointer to a memory address directly so I used the redirection shown above to get around this compiler restriction.
There was one more challenge to handle though, rewriting constructor and destructor addresses, so far I only have a need for constructor so I did not bother with writing a handler for them. The reason this was a challenge is because in the c++ specification it is stated that constructors are not functions, not physically existent and thus you cannot get their address. Well, fuck the standards, we don’t want any of that shit. So I declared it was time for a workaround!
This is where my code gets dodgy and I highly recommend you use my .lib file and do not attempt to recompile the lib as this constructor code is based on the final assembly generated and it will differ between compilers.
First step was making a small function which just creates an object:
void CSlotCreator(){
CSlot* slot = new CSlot();
}
The next step was to write a function which reads the assembly generated for this small function and attempts to get the address of the constructor, I found two types of constructing, one which used a CALL and one which used a JMP to go to the constructor, both are able to be processed in my code.
void FixConstructorAddress(int addrROSE, unsigned char* createFunc){
unsigned char* addr = createFunc;
if(addr[2] == 0xE8){
for(int i = 0; i < 0x20; ++i){
if(addr[i] != 0xE9) continue;
int relAddr = *(int*)(addr + i + 1);
int cAddr = (int)(addr + i);
int ctorAddr = cAddr + relAddr + 5;
unsigned char* codePtr = (unsigned char*)ctorAddr;
DWORD oldProtect;
VirtualProtect(codePtr, 5, PAGE_EXECUTE_READWRITE, &oldProtect);
codePtr[0] = 0x8B;
codePtr[1] = 0xC8;
VirtualProtect(codePtr, 5, oldProtect, &oldProtect);
CodeHook::ApplyJmpHook(codePtr + 2, (unsigned char*)addrROSE, 0);
break;
}
}else{
addr = addr + 0x30;
for(int i = 0; i < 0x20; ++i){
if(addr[i] != 0xE8) continue;
int relAddr = *(int*)(addr + i + 1);
int cAddr = (int)(addr + i);
int ctorAddr = cAddr + relAddr + 5;
unsigned char* codePtr = (unsigned char*)ctorAddr;
DWORD oldProtect;
VirtualProtect(codePtr, 5, PAGE_EXECUTE_READWRITE, &oldProtect);
codePtr[0] = 0x8B;
codePtr[1] = 0xCE;
VirtualProtect(codePtr, 5, oldProtect, &oldProtect);
CodeHook::ApplyJmpHook(codePtr + 2, (unsigned char*)addrROSE, 1);
break;
}
}
}
So as you can see, it reads the bytes until it finds a JMP or CALL and then reads the address to the constructor, once this is done it rewrites the first bytes of the constructor to MOV ECX, ESI or MOV ECX, EAX (depending on CALL or JMP style) then JMP to the original TRose constructor! Hurray, that was fun.
Download the code and library here: TRose.lib.
C++, Open Source, Programming, ROSE Online, Reverse Engineering
Are you gonna post a example for TGameCtrl_r.lib anytime soon? My custom windows don’t show up if I give them a Custom XML file
Do you have the correct TSI file and the .id file?
Nope :$ so I have to make a custom TSI and a ID file?
Well if you have custom elements you are using in your xml!
k thanks it’s working now do you maybe have a list of those wParam, lParam, uiMsg?
or are they just the winapi ones?
wow nice ;p
:< just gotta know how to work with those Messages and I’ll be able to make a mp3 player
nvm already figured it out
thank you very much!!
How can you link the lib to my dll?
Correct me if i’m wrong but in your Packet class :
change :
template void Add(T value){
*((T*)(mData + mSize)) = value;
mSize += sizeof(T);
}
by : template void Add(T value){
*((T*)(mData)) = value;
mSize += sizeof(T);
}
Was that as answer for my question?