diff --git a/bitstream.c b/bitstream.c index 6a389ad..83a11bb 100644 --- a/bitstream.c +++ b/bitstream.c @@ -4,6 +4,7 @@ #include "common.h" #include "bitstream.h" #include "packet.h" +#include __declspec(naked) void __stdcall BitStream__ctor( @@ -44,3 +45,61 @@ int __stdcall BitStream__Read(struct CBitStream *this, char *out) jmp eax } } + +int __stdcall Hooked_BitStream__ReadCompressed( + char *out, + unsigned char a, + unsigned char unsignedData) +{ + struct CBitStream *this; + unsigned char tmpa, tmpread; + int myReadOffset; + + _asm mov this, ecx + + tmpa = (a >> 3) - 1; + if (unsignedData) { + unsignedData = 0; + a = 0; + } else { + unsignedData = 0xFF; + a = 0xF0; + } + + while (tmpa > 0) { + myReadOffset = this->readOffset + 1; + if (myReadOffset > this->numberOfBitsUsed) { + return 0; + } + if ((0x80 >> this->readOffset) == this->ptrData[myReadOffset]) { + this->readOffset = myReadOffset; + return (int) thiscall3( + (void*) 0x44DA70, this, (int) out, tmpa, 1); + } + + this->readOffset = myReadOffset; + out[tmpa] = unsignedData; + tmpa--; + } + + if (this->readOffset + 1 > this->numberOfBitsUsed) { + return 0; + } + + if (!thiscall1((void*) 0x44D840, this, (int) &tmpread)) { /*readBit*/ + return 0; + } + + out += 0; /*? esi + ebx but esi should be always 0?*/ + if (tmpread) { + if (!thiscall3((void*) 0x44DA70, this, (int) out, 4, 1)) { + return 0; + } + *out |= a; + } else { + if (!thiscall3((void*) 0x44DA70, this, (int) out, 8, 1)) { + return 0; + } + } + return 1; +} diff --git a/bitstream.h b/bitstream.h index 8d44611..bcb3989 100644 --- a/bitstream.h +++ b/bitstream.h @@ -21,3 +21,7 @@ void __stdcall BitStream__ctor( void __stdcall BitStream__dtor(); int __stdcall BitStream__Read(struct CBitStream *this, char *out); +int __stdcall Hooked_BitStream__ReadCompressed( + char *out, + unsigned char, + unsigned char); diff --git a/common.c b/common.c index ead1ea6..b5a17ce 100644 --- a/common.c +++ b/common.c @@ -3,6 +3,67 @@ #include "common.h" +__declspec(naked) +void * __stdcall thiscall0(void *address, void *this) +{ + _asm { + add esp, 0xC + mov ecx, [esp-0x4] + mov eax, [esp-0x8] + push [esp-0xC] + jmp eax + } +} + +__declspec(naked) +void * __stdcall thiscall1(void *address, void *this, int a) +{ + _asm { + add esp, 0xC + mov ecx, [esp-0x4] + mov eax, [esp-0x8] + push [esp-0xC] + jmp eax + } +} + +__declspec(naked) +void * __stdcall thiscall2(void *address, void *this, int a, int b) +{ + _asm { + add esp, 0xC + mov ecx, [esp-0x4] + mov eax, [esp-0x8] + push [esp-0xC] + jmp eax + } +} + +__declspec(naked) +void * __stdcall thiscall3(void *address, void *this, int a, int b, int c) +{ + _asm { + add esp, 0xC + mov ecx, [esp-0x4] + mov eax, [esp-0x8] + push [esp-0xC] + jmp eax + } +} + +__declspec(naked) +void * __stdcall thiscall4(void *address, void *this, + int a, int b, int c, int d) +{ + _asm { + add esp, 0xC + mov ecx, [esp-0x4] + mov eax, [esp-0x8] + push [esp-0xC] + jmp eax + } +} + __declspec(naked) void __stdcall RangeList__ctor(struct CRangeList *this) { diff --git a/common.h b/common.h index 482b682..15f7a70 100644 --- a/common.h +++ b/common.h @@ -131,6 +131,11 @@ struct CInternalPacket { EXPECT_SIZE(struct CInternalPacket, 0x38); #pragma pack(pop) +void * __stdcall thiscall0(void *address, void *this); +void * __stdcall thiscall1(void *address, void *this, int); +void * __stdcall thiscall2(void *address, void *this, int, int); +void * __stdcall thiscall3(void *address, void *this, int, int, int); +void * __stdcall thiscall4(void *address, void *this, int, int, int, int); void __stdcall RangeList__ctor(struct CRangeList *this); void __stdcall RangeList__dtor(struct CRangeList *this); int __stdcall BPlusTree__IsEmpty(void *this); diff --git a/nethandler.c b/nethandler.c index ccac8cb..af7b90d 100644 --- a/nethandler.c +++ b/nethandler.c @@ -2,9 +2,11 @@ /* vim: set filetype=c ts=8 noexpandtab: */ #include "common.h" +#include "bitstream.h" #include "rakpeer.h" #include "processnetworkpacket.h" #include "uncompress.h" +#include "rangelist_deserialize.h" #include #include #include @@ -24,4 +26,6 @@ void nethandler_init() simple_redir_call(RP_PARSE_NETWORK_PACKET, ProcessNetworkPacket); simple_redir_call(RP_PARSE_CONNECTION_REQ, RakPeer__ParseConnectionRequestPacket); + //simple_redir_call((void*) 0x45F951, RangeList__Deserialize_hooked); + simple_redir_call((void*) 0x45E2EF, Hooked_BitStream__ReadCompressed); } diff --git a/rangelist_deserialize.c b/rangelist_deserialize.c new file mode 100644 index 0000000..f1c86b0 --- /dev/null +++ b/rangelist_deserialize.c @@ -0,0 +1,51 @@ + +/* vim: set filetype=c ts=8 noexpandtab: */ + +#include "common.h" +#include "rangelist_deserialize.h" +#include "bitstream.h" + +static +__declspec(naked) +int __stdcall RangeList__Deserialize( + struct CRangeList *this, + struct CBitStream *bitStream) +{ + _asm { + pop eax + pop ecx + push eax + mov eax, 0x45E2D0 + jmp eax + } +} + +int __stdcall RangeList__Deserialize_hooked(struct CBitStream *bitStream) +{ + struct CRangleList *this; + short result; + char confusingVar; + int value, valueshr3; + + _asm mov this, ecx + + thiscall0((void*) 0x45D820, this); + thiscall3((void*) 0x44DB30, bitStream, (int) &result, 0x10, 1); + + if (result == 0) { + return 1; + } + + confusingVar = *((char*) bitStream); // ?? + + if (bitStream->readOffset + 1 <= bitStream->numberOfBitsUsed) { + value = (int) bitStream->ptrData; + valueshr3 = value >> 3; + value &= 0x8000007; + if (value & 0x80000000) { + + } + } + + return 0; +} diff --git a/rangelist_deserialize.h b/rangelist_deserialize.h new file mode 100644 index 0000000..6f28c97 --- /dev/null +++ b/rangelist_deserialize.h @@ -0,0 +1,8 @@ + +/* vim: set filetype=c ts=8 noexpandtab: */ + +int __stdcall RangeList__Deserialize( + struct CRangeList *this, + struct CBitStream *bitStream); + +int __stdcall RangeList__Deserialize_hooked(struct CBitStream *bitStream); diff --git a/reliability.c b/reliability.c index 764d99a..82033ee 100644 --- a/reliability.c +++ b/reliability.c @@ -1,6 +1,8 @@ /* vim: set filetype=c ts=8 noexpandtab: */ +#define CALL_ORIGINAL + #define RELIABILITY_PRINT #ifdef RELIABILITY_PRINT @@ -13,6 +15,7 @@ #include "bitstream.h" #include "rakpeer.h" #include "reliability.h" +#include "rangelist_deserialize.h" #include __declspec(naked) @@ -74,21 +77,6 @@ __stdcall ReliabilityLayer__CreateInternalPacketFromBitStream( } } -static -__declspec(naked) -int __stdcall RangeList__Deserialize( - struct CRangeList *this, - struct CBitStream *bitStream) -{ - _asm { - pop eax - pop ecx - push eax - mov eax, 0x45E2D0 - jmp eax - } -} - /*ReliabilityLayer__RemovePacketFromResendListAndDeleteOlderReliableSequenced*/ __declspec(naked) int __stdcall ReliabilityLayer__RemovePacketsConfirmedByAck( @@ -233,6 +221,9 @@ void AddBitsReceivedStatistic(struct CReliabilityLayer *this, int bits) } } +#ifdef CALL_ORIGINAL +__declspec(naked) +#endif int __stdcall ReliabilityLayer__HandleSocketReceiveFromConnectedPlayer( struct CReliabilityLayer *this, char *buffer, @@ -242,6 +233,15 @@ int __stdcall ReliabilityLayer__HandleSocketReceiveFromConnectedPlayer( int MTUSize, int *ptrOutIsPacketFlood) { +#ifdef CALL_ORIGINAL + _asm { + pop eax + pop ecx + push eax + mov eax, 0x45F7E0 + jmp eax + } +#else struct CInternalPacket *packet; struct CBitStream bitStream; struct CRaknetTimeNS timeNS; @@ -281,4 +281,5 @@ int __stdcall ReliabilityLayer__HandleSocketReceiveFromConnectedPlayer( BitStream__dtor(&bitStream); dprintf("HandleSocketReceiveFromConnectedPlayerEnd\n"); return returnValue; +#endif } diff --git a/samp-re.vcproj b/samp-re.vcproj index 15401df..b6e4a1d 100644 --- a/samp-re.vcproj +++ b/samp-re.vcproj @@ -141,6 +141,14 @@ RelativePath=".\rakpeer.h" > + + + +