From a7aa10a6370e05e0da4961b8711a29eac7bc9d03 Mon Sep 17 00:00:00 2001 From: yugecin Date: Sat, 4 Apr 2020 21:24:06 +0200 Subject: [PATCH] start replacing ReliabilityLayer__HandleSocketReceiveFromConnectedPlayer --- bitstream.c | 46 ++++++++++++++++++++++ bitstream.h | 23 +++++++++++ common.h | 87 ++++++++++++++++++++++++++++++++++++++++++ datastructures.c | 28 ++++++++++++++ plugin.c | 2 +- processnetworkpacket.c | 4 +- rakpeer.c | 20 +++++++++- rakpeer.h | 2 + reliability.c | 65 +++++++++++++++++++++++++++---- samp-re.vcproj | 12 ++++++ 10 files changed, 278 insertions(+), 11 deletions(-) create mode 100644 bitstream.c create mode 100644 bitstream.h create mode 100644 datastructures.c diff --git a/bitstream.c b/bitstream.c new file mode 100644 index 0000000..6a389ad --- /dev/null +++ b/bitstream.c @@ -0,0 +1,46 @@ + +/* vim: set filetype=c ts=8 noexpandtab: */ + +#include "common.h" +#include "bitstream.h" +#include "packet.h" + +__declspec(naked) +void __stdcall BitStream__ctor( + struct CBitStream *this, + char *buffer, + int lengthInBytes, + char copyData) +{ + _asm { + pop eax + pop ecx + push eax + mov eax, 0x44D930 + jmp eax + } +} + +__declspec(naked) +void __stdcall BitStream__dtor(struct CBitStream *this) +{ + _asm { + pop eax + pop ecx + push eax + mov eax, 0x44D9B0 + jmp eax + } +} + +__declspec(naked) +int __stdcall BitStream__Read(struct CBitStream *this, char *out) +{ + _asm { + pop eax + pop ecx + push eax + mov eax, 0x44D840 + jmp eax + } +} diff --git a/bitstream.h b/bitstream.h new file mode 100644 index 0000000..8d44611 --- /dev/null +++ b/bitstream.h @@ -0,0 +1,23 @@ + +/* vim: set filetype=c ts=8 noexpandtab: */ + +#pragma pack(push,1) +struct CBitStream { + int numberOfBitsUsed; + int numberOfBitsAllocated; + int readOffset; + char *ptrData; + char copyData; + char stackData[256]; +}; +#pragma pack(pop) + +void __stdcall BitStream__ctor( + struct CBitStream *this, + char *buffer, + int lengthInBytes, + char copyData); + +void __stdcall BitStream__dtor(); + +int __stdcall BitStream__Read(struct CBitStream *this, char *out); diff --git a/common.h b/common.h index c7380d1..a305f98 100644 --- a/common.h +++ b/common.h @@ -14,9 +14,96 @@ struct PlayerID { }; EXPECT_SIZE(struct PlayerID, 0x8); +struct CList { + void *values; + int list_size; + int allocation_size; +}; +EXPECT_SIZE(struct CList, 0xC); + +struct COrdenedList { + struct CList _parent; +}; +EXPECT_SIZE(struct COrdenedList, 0xC); + +struct CRangeList { + struct COrdenedList _parent; +}; +EXPECT_SIZE(struct CRangeList, 0xC); + struct CRaknetTimeNS { int lo32; int hi32; }; EXPECT_SIZE(struct CRaknetTimeNS, 0x8); + +struct CQueue { + void *array; + void *head; + void *tail; + int allocationSize; +}; +EXPECT_SIZE(struct CQueue, 0x10); + +struct CReliabilityLayer { +/*000*/ char _pad0[0xC]; +/*00C*/ struct CQueue outputQueue; +/*01C*/ void *acknowlegements; // DataStructures::RangeList +/*020*/ char _pad20[0x20]; +/*040*/ void *resendList; +/*044*/ char _pad44[0x24]; +/*068*/ void* sendPacketSet; // DataStructures::Queue + // (sizeof one element = 16 0x10) + // TODO this would be too big? +/*06C*/ char _pad6C[0x4C]; +/*0B8*/ struct CRaknetTimeNS lastAckTime; +/*0C0*/ char _padC0[0x114]; +/*1D4*/ short waitingForOrderedPacketWriteIndex[32]; +/*214*/ short waitingForSequencedPacketWriteIndex[32]; +/*254*/ short waitingForOrderedPacketReadIndex[32]; +/*294*/ short waitingForSequencedPacketReadIndex[32]; +/*2D4*/ char _pad2D4[0xC]; +/*2E0*/ int timeoutTimeMS; +/*2E4*/ char _pad2E4[0x68]; +/*35C*/ int statistics_acknowlegementsSent; +/*360*/ char _pad360[0x2C]; +/*38C*/ int statistics_numberOfUnsplitMessages; +/*390*/ int statistics_numberOfSplitMessages; +/*394*/ char _pad394[0x2C]; +/*3B0*/ int statistics_sequencedMessagesOutOfOrder; +/*3B4*/ int statistics_sequencedMessagesInOrder; +/*3B8*/ int statistics_orderedMessagesOutOfOrder; +/*3BC*/ int statistics_orderedMessagesInOrder; +/*3C0*/ int statistics_packetsReceived; +/*3C4*/ char _pad3C4[0x4]; +/*3C8*/ unsigned int statistics_bitsReceivedLo32; +/*3CC*/ unsigned int statistics_bitsReceivedHi32; +/*3D0*/ char _pad3D0[0x10]; +/*3E0*/ int statistics_messagesReceived; +/*3E4*/ char _pad3E4[0x4]; +/*3E8*/ int statistics_duplicateMessagesReceived; +/*3EC*/ char _pad3EC[0x28]; +/*414*/ int someCounter; +/*418*/ char _pad418[0xC]; +/*424*/ struct CQueue hasReceivedPacketQueue; +/*434*/ short receivedPacketsBaseIndex; +/*436*/ char resetReceivedPackets; +/*437*/ char _pad437[0x11]; +/*448*/ struct CRaknetTimeNS histogramStartTime; +/*450*/ int histogramReceiveMarker; +/*454*/ char _pad454[0x8]; +/*45C*/ int histogramAckCount; +/*460*/ char _pad460[0x24]; +/*484*/ void *encryptor; +/*488*/ char _pad488[0x274]; +/*6FC*/ int receivePacketCount; +/*700*/ char _pad700[0x8]; +/*708*/ char freeThreadedMemoryOnNextUpdate; +/*709*/ char _pad709[0x1F]; +/*728*/ void *internalPacketPool; +}; +EXPECT_SIZE(struct CReliabilityLayer, 0x72C); #pragma pack(pop) + +void __stdcall __RangeList__ctor(struct CRangeList *this); +void __stdcall __RangeList__dtor(struct CRangeList *this); diff --git a/datastructures.c b/datastructures.c new file mode 100644 index 0000000..39bafde --- /dev/null +++ b/datastructures.c @@ -0,0 +1,28 @@ + +/* vim: set filetype=c ts=8 noexpandtab: */ + +#include "common.h" + +__declspec(naked) +void __stdcall __RangeList__ctor(struct CRangeList *this) +{ + _asm { + pop eax + pop ecx + push eax + mov eax, 0x45F2D0 + jmp eax + } +} + +__declspec(naked) +void __stdcall __RangeList__dtor(struct CRangeList *this) +{ + _asm { + pop eax + pop ecx + push eax + mov eax, 0x45F300 + jmp eax + } +} diff --git a/plugin.c b/plugin.c index eccda26..243e517 100644 --- a/plugin.c +++ b/plugin.c @@ -245,7 +245,7 @@ void gen_gamemode_script() PLUGIN_EXPORT int PLUGIN_CALL Load(void **ppData) { - void nethandler_load(); + void nethandler_init(); pAMXFunctions = ppData[PLUGIN_DATA_AMX_EXPORTS]; logprintf = (logprintf_t) ppData[PLUGIN_DATA_LOGPRINTF]; diff --git a/processnetworkpacket.c b/processnetworkpacket.c index 0da30f4..474ce98 100644 --- a/processnetworkpacket.c +++ b/processnetworkpacket.c @@ -1,7 +1,7 @@ /* vim: set filetype=c ts=8 noexpandtab: */ -#define PROCESSNETWORKPACKET_PRINT +//#define PROCESSNETWORKPACKET_PRINT #ifdef PROCESSNETWORKPACKET_PRINT #define dprintf(X,...) printf(X,__VA_ARGS__) @@ -108,6 +108,8 @@ void __stdcall ProcessNetworkPacket( playerId.binaryAddress = host; playerId.port = port; + /*banned was checked here*/ + if (data[0] == ID_OPEN_CONNECTION_REQUEST && length == 3) { dprintf("got connection request\n"); rs = RakPeer__GetRemoteSystemFromPlayerID(rp, playerId, 1, 1); diff --git a/rakpeer.c b/rakpeer.c index 8e720b2..e3ef5b7 100644 --- a/rakpeer.c +++ b/rakpeer.c @@ -98,6 +98,23 @@ unsigned int __stdcall RakPeer__GetTime() } } +__declspec(naked) +void RakNet__GetTimeNS(struct CRaknetTimeNS *time) +{ + _asm { + push esi + push edx + mov esi, [esp+0xC] + mov eax, 0x44EA30 + call eax + mov [esi], eax + mov [esi+0x3], edx + pop edx + pop esi + ret + } +} + static void __declspec(naked) RakPeer__SendImmediate( struct CRakPeer *this, @@ -208,8 +225,7 @@ sendimmediateresponse: playerId, 0, 0, - RakPeer__GetTime(), - 0 + RakPeer__GetTime() ); remoteSystem->connectMode = DISCONNECT_ASAP_SILENTLY; ret: diff --git a/rakpeer.h b/rakpeer.h index 5655b11..9f93366 100644 --- a/rakpeer.h +++ b/rakpeer.h @@ -85,6 +85,8 @@ Only seems to fetch lo32 */ unsigned int __stdcall RakPeer__GetTime(); +void RakNet__GetTimeNS(struct CRaknetTimeNS *time); + int __stdcall RakPeer__GetIndexFromPlayerID( struct CRakPeer *this, struct PlayerID playerId, diff --git a/reliability.c b/reliability.c index 7c4d991..a0ec73e 100644 --- a/reliability.c +++ b/reliability.c @@ -1,11 +1,43 @@ /* vim: set filetype=c ts=8 noexpandtab: */ +#define RELIABILITY_PRINT + +#ifdef RELIABILITY_PRINT +#define dprintf(X,...) printf(X,__VA_ARGS__) +#else +#define dprintf(X,...) +#endif + #include "common.h" +#include "bitstream.h" #include "rakpeer.h" #include "reliability.h" +#include + +/** +seems like a nop +*/ +static +void UpdateThreadedMemory(struct CReliabilityLayer *this) +{ + if (this->freeThreadedMemoryOnNextUpdate) { + this->freeThreadedMemoryOnNextUpdate = 0; + } +} + +static +void AddBitsReceivedStatistic(struct CReliabilityLayer *this, int bits) +{ + unsigned int loValue; + + loValue = this->statistics_bitsReceivedLo32; + this->statistics_bitsReceivedLo32 += bits; + if (this->statistics_bitsReceivedLo32 < loValue) { + this->statistics_bitsReceivedHi32++; + } +} -__declspec(naked) int __stdcall ReliabilityLayer__HandleSocketReceiveFromConnectedPlayer( struct CReliabilityLayer *this, char *buffer, @@ -15,11 +47,30 @@ int __stdcall ReliabilityLayer__HandleSocketReceiveFromConnectedPlayer( int MTUSize, int *ptrOutIsPacketFlood) { - _asm { - pop eax - pop ecx - push eax - mov eax, 0x45F7E0 - jmp eax + struct CBitStream bitStream; + struct CRaknetTimeNS time; + struct CRangeList incomingAcks; + char hasAcks; + + if (length == 1 || buffer == NULL) { + dprintf("ignoring length %d buffer %p\n", length, buffer); + // connection request, ignore + return 1; } + + UpdateThreadedMemory(this); + AddBitsReceivedStatistic(this, length * 8); + + BitStream__ctor(&bitStream, buffer, length, 0); + RakNet__GetTimeNS(&time); + __RangeList__ctor(&incomingAcks); + + BitStream__Read(&bitStream, &hasAcks); + if (hasAcks) { + dprintf("hasacks\n"); + } + + __RangeList__dtor(&incomingAcks); + BitStream__dtor(&bitStream); + return 0; } diff --git a/samp-re.vcproj b/samp-re.vcproj index 96b9ae0..b44414a 100644 --- a/samp-re.vcproj +++ b/samp-re.vcproj @@ -93,10 +93,22 @@ Filter="cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx;h;hpp;hxx;hm;inl;inc;xsd" UniqueIdentifier="{684CEF6A-23EC-4AF8-85DF-5508CE723369}" > + + + + + +