Using MCommand (07 again)
MCommand.h
Code:
#include "Empathy.h"
#include "MUID.h"
#include "Addresses.h"
#include "MCommandParameter.h"
#include "Enums.h"
struct MCommandDesc;
typedef MCommandDesc* (__thiscall* MCommandDescTypedef)(MCommandDesc*, uint32_t, const char*, const char*, int);
MCommandDescTypedef MCommandDescConstructor = reinterpret_cast<MCommandDescTypedef>(MCommandDesc__MCommandDescAddress);
struct MCommandManager
{
void AddCommandDesc(MCommandDesc* command)
{
((void (__thiscall*)(LPVOID, MCommandDesc*))MCommandManager__AddCommandDescAddress) (this, command);
}
};
struct MCommandDesc
{
LPVOID m_pPolymoprhism;
uint32_t m_nCommandId;
char m_szName[256];
char m_szDescription[256];
uint32_t m_nFlag;
std::vector<MCommandParameterDesc*> m_pParameterDescs;
MCommandDesc(uint32_t commandId, const char* name, const char* description, uint32_t flag)
{
MCommandDescConstructor (this, commandId, name, description, flag);
}
void AddParamDesc(MCommandParameterDesc* param)
{
((void (__thiscall*)(LPVOID, MCommandParameterDesc*))MCommandDesc__AddParameterDescAddress) (this, param);
}
};
struct MCommand
{
LPVOID CMemPool;
MCommand* m_pNextCommand;
MUID m_uidSender;
MUID m_uidReceiver;
MCommandDesc* m_pCommandDesc;
std::vector<MCommandParameter*> m_pCommandParams;
BYTE m_nSerialNumber;
bool AddParameter(MCommandParameter* param)
{
return ((bool (__thiscall *)(LPVOID,MCommandParameter*))MCommand__AddParameterAddress) (this, param);
}
bool GetParameter(void *pValue, int i, MCommandParameterType type, int bufferSize)
{
return ((bool (__thiscall *)(LPVOID,LPVOID,int,MCommandParameterType,int))MCommand__GetParameterAddress) (this, pValue, i, type, bufferSize);
}
MCommandParameter* GetParameter(uint32_t i)
{
return ((MCommandParameter* (__thiscall*)(LPVOID, uint32_t))MCommand__GetParameterAddress2)(this, i);
}
static MCommand* Create(uint32_t packetId)
{
return ((MCommand* (__cdecl*)(uint32_t))ZNewCMDAddress)(packetId);
}
static void Post(MCommand* packet)
{
_asm
{
mov eax, ZGetGameClientAddress
call eax
push packet
mov edx, [eax]
mov ecx,eax
call [edx+0x30]
}
}
};
struct MPacketHeader
{
uint16_t nMsg;
uint16_t nSize;
uint16_t nCheckSum;
};
struct MPacketCrypterKey
{
char szKey[32];
};
struct MPacketCrypter
{
LPVOID m_pPolymoprhism;
MPacketCrypterKey m_Key;
};
struct MCommandBuilder
{
LPVOID m_pPolymoprhism;
MUID m_uidSender;
MUID m_uidReceiver;
MCommandManager* m_pCommandManager;
char m_Buffer[0x4000];
uint32_t m_nBufferNext;
std::list<MCommand*> m_CommandList;
std::list<MPacketHeader*> m_NetCmdList;
MPacketCrypter* m_pPacketCrypter;
};
MCommandParameters.h
Code:
#include "Empathy.h"
#include "MUID.h"
#include "Addresses.h"
struct MCommandParameterDesc;
struct MCommandParameterInt;
struct MCommandParameterUInt;
struct MCommandParameterString;
struct MCommandParameterFloat;
struct MCommandParameterMUID;
struct MCommandParameterBlob;
typedef MCommandParameterDesc* (__thiscall* MCommandParameterDescTypedef)(MCommandParameterDesc*, uint32_t, const char*);
typedef MCommandParameterInt* (__thiscall* MCommandParameterIntTypedef) (MCommandParameterInt*, int);
typedef MCommandParameterUInt* (__thiscall* MCommandParameterUIntTypedef) (MCommandParameterUInt*, uint32_t);
typedef MCommandParameterString* (__thiscall* MCommandParameterStringTypedef) (MCommandParameterString*, char*);
typedef MCommandParameterFloat* (__thiscall* MCommandParameterFloatTypedef) (MCommandParameterFloat*, float);
typedef MCommandParameterMUID* (__thiscall* MCommandParameterMUIDTypedef) (MCommandParameterMUID*, MUID*);
typedef MCommandParameterBlob* (__thiscall* MCommandParameterBlobTypedef) (MCommandParameterBlob*, LPVOID, int);
MCommandParameterDescTypedef MCommandParameterDescConstructor = reinterpret_cast<MCommandParameterDescTypedef>(MCommandParameterDesc__MCommandParameterDescAddress);
MCommandParameterIntTypedef MCommandParameterIntConstructor = reinterpret_cast<MCommandParameterIntTypedef>(MCommandParameterInt__MCommandParameterIntAddress);
MCommandParameterUIntTypedef MCommandParameterUIntConstructor = reinterpret_cast<MCommandParameterUIntTypedef>(MCommandParameterUInt__MCommandParameterUIntAddress);
MCommandParameterStringTypedef MCommandParameterStringConstructor = reinterpret_cast<MCommandParameterStringTypedef>(MCommandParameterString__MCommandParameterStringAddress);
MCommandParameterFloatTypedef MCommandParameterFloatConstructor = reinterpret_cast<MCommandParameterFloatTypedef>(MCommandParameterFloat__MCommandParameterFloatAddress);
MCommandParameterMUIDTypedef MCommandParameterMUIDConstructor = reinterpret_cast<MCommandParameterMUIDTypedef>(MCommandParameterMUID__MCommandParameterMUIDAddress);
MCommandParameterBlobTypedef MCommandParameterBlobConstructor = reinterpret_cast<MCommandParameterBlobTypedef>(MCommandParameterBlob__MCommandParameterBlobAddress);
struct MCommandParameterDesc
{
LPVOID m_pPolymoprhism;
uint32_t m_nParamType;
char m_szDescription[64];
std::vector<LPVOID> m_pParameterConditions;
MCommandParameterDesc(uint32_t type, const char* desc)
{
MCommandParameterDescConstructor(this, type, desc);
}
};
struct MCommandParameter
{
LPVOID m_pPolymoprhism;
uint32_t m_nParamType;
};
struct MCommandParameterInt : public MCommandParameter
{
int m_Value;
MCommandParameterInt(int value)
{
MCommandParameterIntConstructor (this, value);
}
};
struct MCommandParameterUInt : public MCommandParameter
{
uint32_t m_Value;
MCommandParameterUInt(uint32_t value)
{
MCommandParameterUIntConstructor (this, value);
}
};
struct MCommandParameterString : public MCommandParameter
{
char* m_Value;
MCommandParameterString(char* value)
{
MCommandParameterStringConstructor (this, value);
}
};
struct MCommandParameterMUID : public MCommandParameter
{
MUID m_Value;
MCommandParameterMUID(MUID* value)
{
MCommandParameterMUIDConstructor (this, value);
}
};
struct MCommandParameterBlob : public MCommandParameter
{
char* m_Value;
int m_nSize;
static void MakeBlobHeader(char* data, int elementCount, int elementSize)
{
int total = (elementCount * elementSize) + 8;
data = new char[total+4];
memcpy(data, &total, 4);
memcpy(data+4, &elementSize, 4);
memcpy(data+8, &elementCount, 4);
}
static char* MMakeBlobArray(int nOneBlobSize, int nBlobCount)
{
char *result;
result = new char[(nBlobCount * nOneBlobSize + 8)];
*((DWORD *)result + 1) = nBlobCount;
*(DWORD *)result = nOneBlobSize;
return result;
}
static char *MGetBlobArrayElement(char *pBlob, uint32_t i)
{
char *result;
if (i < 0 || i >= *((DWORD *)pBlob + 1))
result = 0;
else
result = pBlob + (i * *(DWORD *)pBlob + 8);
return result;
}
MCommandParameterBlob(LPVOID value, int size)
{
MCommandParameterBlobConstructor (this, value, size);
}
};
Addresses (07)
Code:
static uint32_t MAddSharedCommandTableAddress = 0x0051D6D0;
static uint32_t ZNewCMDAddress = 0x004C3B60;
static uint32_t MCommand__AddParameterAddress = 0x00507C00;
static uint32_t MCommand__GetParameterAddress = 0x00507010;
static uint32_t MCommand__GetParameterAddress2 = 0x00506FD0;
static uint32_t MCommandDesc__MCommandDescAddress = 0x005079B0;
static uint32_t MCommandParameterDesc__MCommandParameterDescAddress = 0x00506F20;
static uint32_t MCommandManager__AddCommandDescAddress = 0x00514FA0;
static uint32_t MCommandDesc__AddParameterDescAddress = 0x005083A0;
static uint32_t MCommandParameterInt__MCommandParameterIntAddress = 0x00505AF0;
static uint32_t MCommandParameterUInt__MCommandParameterUIntAddress = 0x00505C20;
static uint32_t MCommandParameterString__MCommandParameterStringAddress = 0x00505DD0;
static uint32_t MCommandParameterFloat__MCommandParameterFloatAddress = 0x00505CF0;
static uint32_t MCommandParameterMUID__MCommandParameterMUIDAddress = 0x005068E0;
static uint32_t MCommandParameterBlob__MCommandParameterBlobAddress = 0x00505FD0;
static uint32_t ZGameClient__OnCommandAddress = 0x004C7990;
Enum
Code:
enum MCommandParameterType
{
MPT_INT,
MPT_UINT,
MPT_FLOAT,
MPT_BOOL,
MPT_STRING,
MPT_VECTOR,
MPT_POS,
MPT_DIR,
MPT_COLOR,
MPT_MUID,
MPT_BLOB,
MPT_CHAR,
MPT_UCHAR,
MPT_SHORT,
MPT_USHORT,
MPT_INT64,
MPT_UINT64,
MPT_SVECTOR
};
Example of creating and sending:
Code:
auto command = MCommand::Create(0xD136);
auto file = new MCommandParameterString(argv[1]);
command->AddParameter(file);
MCommand::Post(command);
Example of extracting:
Code:
if (pCommand->m_pCommandDesc->m_nCommandId == 0x515)
{
MUID uidPlayer;
char szStage[256];
bool isPrivate;
char szPassword[64];
pCommand->GetParameter(&uidPlayer, 0, MPT_MUID, -1);
if (uidPlayer.uidHigh != pCommand->m_uidSender.uidHigh)
{
instance->DisconnectObject(&uidPlayer);
return false;
}
if (!pCommand->GetParameter(szStage, 1, MPT_STRING, 256) ||
!pCommand->GetParameter(&isPrivate, 2, MPT_BOOL, -1) ||
!pCommand->GetParameter(szPassword, 3, MPT_STRING, 64))
{
return false;
}
instance->OnStageCreate(&uidPlayer, szStage, isPrivate, szPassword);
return true;
}
Example of Adding custom packets:
Code:
CDetour MAddSharedCommandTableDet;
void MAddSharedCommandTableHook (MCommandManager* pCommandManager, int nSharedType)
{
MCommandDesc* sexCommand = new MCommandDesc(0xD135, "Dreams.Sex.Change", "Changes character sex in-game", 1);
MCommandParameterDesc* sexDesc = new MCommandParameterDesc (0, "nSex");
sexCommand->AddParamDesc(sexDesc);
pCommandManager->AddCommandDesc (sexCommand);
pCommandManager->AddParamDesc (sexDesc);
printf ("Added sex change packet.\n");
MCommandDesc* configRehash = new MCommandDesc(0xD136, "Dreams.Config.Rehash", "Reloads config file on the fly", 1);
MCommandParameterDesc* configDesc = new MCommandParameterDesc (4, "szFile");
configRehash->AddParamDesc(configDesc);
pCommandManager->AddCommandDesc (configRehash);
pCommandManager->AddParamDesc (configDesc);
printf ("Added config rehashing packet.\n");
MCommandDesc* color = new MCommandDesc(0xD137, "Dreams.Server.RequestColors", "Allows for on-the fly dynamic loading of custom colors", 1);
pCommandManager->AddCommandDesc(color);
MCommandDesc* colorResponse = new MCommandDesc(0xD138, "Dreams.Server.RehashColors", "Allows for on-the fly dynamic loading of custom colors", 1);
MCommandParameterDesc* colorBlob = new MCommandParameterDesc (10, "ColorInfo");
colorResponse->AddParamDesc(colorBlob);
pCommandManager->AddCommandDesc(colorResponse);
pCommandManager->AddParamDesc(colorBlob);
auto ban = new MCommandDesc(0xD149, "Dreams.Server.Ban", "Bans specified user", 1);
auto user = new MCommandParameterDesc(4, "szUser");
auto reason = new MCommandParameterDesc(4, "szReason");
pCommandManager->AddCommandDesc(ban);
ban->AddParamDesc(user);
ban->AddParamDesc(reason);
}
Re: Using MCommand (07 again)
Can you send the VC++ project?
Anyways your stuff is great ;)
Re: Using MCommand (07 again)
btw, how you hook OnCommand? to get the packets... or what you hook to check if one of your packets arrived?
Re: Using MCommand (07 again)
Nice release needed that too.. mm thanks
Re: Using MCommand (07 again)
Quote:
Originally Posted by
dacharles
btw, how you hook OnCommand? to get the packets... or what you hook to check if one of your packets arrived?
Code:
CDetour MMatchServer__OnCommand;
void WINAI MMatchServer__OnCommandhook(MCommand *pCmd)
{
switch(pCmd->pCmdDesc->m_nCommandID)
{
case 0xlolololol:
{
do_your_stuff();
break;
}
}
}
example based from his code.
Re: Using MCommand (07 again)
Quote:
Originally Posted by
R3apingSaint
Code:
CDetour MMatchServer__OnCommand;
void WINAI MMatchServer__OnCommandhook(MCommand *pCmd)
{
switch(pCmd->pCmdDesc->m_nCommandID)
{
case 0xlolololol:
{
do_your_stuff();
break;
}
}
}
example based from his code.
http://forum.ragezone.com/f496/dev-h...on-fix-690994/
I use that, and sometimes it crash and sometimes it works good and is tested just by me.
Edit: wait, "void WINAPI" will make any difference?...
Re: Using MCommand (07 again)
yes i meant to write WINAPI instead of WINAI. im just waking up so forgive me if im wrong but WINAPI is just
Code:
#define WINAPI __stdcall
if you use that function and it sometimes crashes then id suggest using what thephailure772 reversed and look up on it yourself.
fyi if you are going to need a lot of "if and else" statements then id highly suggest using the switch loop, its easier on your application or dll.
Re: Using MCommand (07 again)
Quote:
Originally Posted by
dacharles
WINAPI = __stdcall
Use a boolean as the function type for MCommand instead.
About this:
http://forum.ragezone.com/f496/dev-h...on-fix-690994/
Avoid using __asm to get your parameters, and use the structures instead...
Re: Using MCommand (07 again)
I'm using the structures of phailure and it works for the first packets(I print every packetID that is passed on OnCommand), then it crash with the bool __stdcall.
There is any other solution?
Re: Using MCommand (07 again)
Don't create any pointer variables in your hook, and use return true for readability.
Re: Using MCommand (07 again)
Can someone please declare everything that is required to get MCommandParameterVector working for me please? I've tried but shit just isnt working.