Skip to content

Commit f089088

Browse files
committed
Big reworks
Base: - Fixed 'Debug' configuration RakLua: - Added R4-2 support (untested) - Fixed compatibility with some launchers - Fixed recursion at one of the functions - Moved RakClientInterface methods hook to RakClient constructor samp-functions: - Code refactoring MoonFunctions: - Fixed sampSendEnterVehicle - Inline of types with SAMP.Lua rtdhook: - Fixed returning of default protection.
1 parent 4809cd9 commit f089088

File tree

9 files changed

+249
-89
lines changed

9 files changed

+249
-89
lines changed

src/MoonFunctions.hpp

Lines changed: 20 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -201,7 +201,7 @@ uintptr_t raknetBitStreamGetDataPtr(RakLuaBitStream* bs)
201201
return bs->getDataPtr();
202202
}
203203

204-
bool raknetEmulPacketReceiveBitStream(uint8_t packetId /* Why, FYP, why?!*/, RakLuaBitStream* bs)
204+
bool raknetEmulPacketReceiveBitStream(uint8_t packetId, RakLuaBitStream* bs)
205205
{
206206
return bs->emulIncomingPacket(packetId);
207207
}
@@ -225,7 +225,7 @@ void sampSendClickPlayer(uint16_t playerId, uint8_t source)
225225
RakLuaBitStream(&bs).sendRPC(23);
226226
}
227227

228-
void sampSendDialogResponse(uint16_t id, uint8_t button, int16_t listItem, std::string_view string = "")
228+
void sampSendDialogResponse(uint16_t id, uint8_t button, uint16_t listItem, std::string_view string = "")
229229
{
230230
BitStream bs;
231231
bs.Write(id);
@@ -245,7 +245,7 @@ void sampSendClickTextdraw(uint16_t id)
245245
RakLuaBitStream(&bs).sendRPC(62);
246246
}
247247

248-
void sampSendGiveDamage(uint16_t id, float damage, int weapon, int bodyPart)
248+
void sampSendGiveDamage(uint16_t id, float damage, int32_t weapon, int32_t bodyPart)
249249
{
250250
BitStream bs;
251251
bs.Write(false);
@@ -256,7 +256,7 @@ void sampSendGiveDamage(uint16_t id, float damage, int weapon, int bodyPart)
256256
RakLuaBitStream(&bs).sendRPC(115);
257257
}
258258

259-
void sampSendTakeDamage(uint16_t id, float damage, int weapon, int bodyPart)
259+
void sampSendTakeDamage(uint16_t id, float damage, int32_t weapon, int32_t bodyPart)
260260
{
261261
BitStream bs;
262262
bs.Write(true);
@@ -267,7 +267,10 @@ void sampSendTakeDamage(uint16_t id, float damage, int weapon, int bodyPart)
267267
RakLuaBitStream(&bs).sendRPC(115);
268268
}
269269

270-
void sampSendEditObject(bool playerObject, uint16_t objectId, int response, float posX, float posY, float posZ, float rotX, float rotY, float rotZ)
270+
void sampSendEditObject(bool playerObject, uint16_t objectId, int32_t response,
271+
float posX, float posY, float posZ,
272+
float rotX, float rotY, float rotZ
273+
)
271274
{
272275
BitStream bs;
273276
bs.Write(playerObject);
@@ -286,7 +289,11 @@ void sampSendEditObject(bool playerObject, uint16_t objectId, int response, floa
286289
}
287290

288291
// TODO: COLOR?
289-
void sampSendEditAttachedObject(int response, int index, int model, int bone, float posX, float posY, float posZ, float rotX, float rotY, float rotZ, float scaleX, float scaleY, float scaleZ)
292+
void sampSendEditAttachedObject(int32_t response, int32_t index, int32_t model, int32_t bone,
293+
float posX, float posY, float posZ,
294+
float rotX, float rotY, float rotZ,
295+
float scaleX, float scaleY, float scaleZ
296+
)
290297
{
291298
BitStream bs;
292299
bs.Write(response);
@@ -306,8 +313,8 @@ void sampSendEditAttachedObject(int response, int index, int model, int bone, fl
306313
bs.Write(scaleY);
307314
bs.Write(scaleZ);
308315

309-
bs.Write<int>(0);
310-
bs.Write<int>(0);
316+
bs.Write<int32_t>(0);
317+
bs.Write<int32_t>(0);
311318

312319
RakLuaBitStream(&bs).sendRPC(116);
313320
}
@@ -324,7 +331,7 @@ void sampSendRequestSpawn()
324331
RakLuaBitStream().sendRPC(129);
325332
}
326333

327-
void sampSendPickedUpPickup(int id)
334+
void sampSendPickedUpPickup(int32_t id)
328335
{
329336
BitStream bs;
330337
bs.Write(id);
@@ -384,7 +391,7 @@ void sampSendEnterVehicle(uint16_t id, bool passenger)
384391
{
385392
BitStream bs;
386393
bs.Write(id);
387-
bs.Write(passenger);
394+
bs.Write<uint8_t>(passenger);
388395
RakLuaBitStream(&bs).sendRPC(26);
389396
}
390397

@@ -400,7 +407,7 @@ void sampSendSpawn()
400407
RakLuaBitStream().sendRPC(52);
401408
}
402409

403-
void sampSendDamageVehicle(uint16_t id, int panel, int doors, uint8_t lights, uint8_t tires)
410+
void sampSendDamageVehicle(uint16_t id, int32_t panel, int32_t doors, uint8_t lights, uint8_t tires)
404411
{
405412
BitStream bs;
406413
bs.Write(id);
@@ -414,8 +421,10 @@ void sampSendDamageVehicle(uint16_t id, int panel, int doors, uint8_t lights, ui
414421
void sampSendUpdatePlayers()
415422
{
416423
static DWORD dwLastUpdateTick = 0;
424+
#pragma warning(disable : 28159) // Consider using GetTickCount64 function instead of GetTickCount
417425
if ((GetTickCount() - dwLastUpdateTick) > 3000) {
418426
dwLastUpdateTick = GetTickCount();
427+
#pragma warning(default : 28159)
419428
RakLuaBitStream().sendRPC(155);
420429
}
421430
}

src/RakLua.cpp

Lines changed: 16 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -22,27 +22,24 @@ RakLua::eInitState RakLua::initialize()
2222

2323
mState = eInitState::INITIALIZING;
2424

25-
std::thread([&]() {
26-
uintptr_t sampInfo = sampGetSampInfoPtr();
27-
while (!sampInfo)
28-
sampInfo = sampGetSampInfoPtr();
29-
30-
mVmtHook = new rtdhook_vmt(*reinterpret_cast<uintptr_t*>(sampGetRakClientInterface()));
31-
mVmtHook->install(6, &handleOutgoingPacket);
32-
mVmtHook->install(8, &handleIncomingPacket);
33-
mVmtHook->install(25, &handleOutgoingRpc);
25+
mRakClientIntfConstructor = new rtdhook(sampGetRakClientIntfConstructorPtr(), &hookRakClientIntfConstructor, 7);
26+
mRakClientIntfConstructor->install();
3427

35-
mState = eInitState::OK;
36-
}).detach();
28+
returnState:
29+
return mState;
30+
}
3731

32+
void RakLua::postRakClientInitialization(uintptr_t rakClientIntf)
33+
{
3834
mIncomingRpcHandlerHook = new rtdhook(sampGetIncomingRpcHandlerPtr(), &handleIncomingRpc);
3935
mIncomingRpcHandlerHook->install();
4036

41-
mRakClientIntfConstructor = new rtdhook(sampGetRakClientIntfConstructorPtr(), &hookRakClientIntfConstructor, 7);
42-
mRakClientIntfConstructor->install();
37+
mVmtHook = new rtdhook_vmt(rakClientIntf);
38+
mVmtHook->install(6, &handleOutgoingPacket);
39+
mVmtHook->install(8, &handleIncomingPacket);
40+
mVmtHook->install(25, &handleOutgoingRpc);
4341

44-
returnState:
45-
return mState;
42+
mState = eInitState::OK;
4643
}
4744

4845
bool RakLua::addEventHandler(sol::this_state& ts, eEventType type, sol::function detour)
@@ -121,9 +118,7 @@ bool inlineIncomingPacketHandler(uint8_t id, RakLuaBitStream& luaBs)
121118
{
122119
luaBs.resetReadPointer();
123120
if (!RakLua::safeCall(handler.handler, id, &luaBs))
124-
{
125121
return false;
126-
}
127122
}
128123
return true;
129124
}
@@ -238,6 +233,9 @@ uintptr_t hookRakClientIntfConstructor()
238233
{
239234
uintptr_t rakClientInterface = reinterpret_cast<uintptr_t(*)()>(gRakLua.getIntfConstructorHook()->getTrampoline())();
240235
if (rakClientInterface)
241-
gRakPeer = reinterpret_cast<void*>(rakClientInterface - 3550);
236+
{
237+
gRakPeer = reinterpret_cast<void*>(rakClientInterface - 0xDDE);
238+
gRakLua.postRakClientInitialization(rakClientInterface);
239+
}
242240
return rakClientInterface;
243241
}

src/RakLua.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,8 @@ class RakLua
2626
public:
2727
eInitState initialize();
2828
bool destroy();
29+
30+
void postRakClientInitialization(uintptr_t rakClientIntf);
2931

3032
bool addEventHandler(sol::this_state& ts, eEventType type, sol::function detour);
3133
void destroyHandlers(sol::this_state& ts);

src/RakLuaBitStream.cpp

Lines changed: 11 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -145,7 +145,7 @@ float RakLuaBitStream::readFloat()
145145

146146
std::string RakLuaBitStream::readString(int32_t len)
147147
{
148-
std::string ret(len, 0);
148+
std::string ret(len, '\0');
149149
bs->Read(ret.data(), len);
150150
return ret;
151151
}
@@ -250,19 +250,21 @@ bool RakLuaBitStream::emulIncomingPacket(uint8_t packetId)
250250
Packet* send_packet = reinterpret_cast<Packet*(*)(int)>(sampGetAllocPacketPtr())(send_bs.GetNumberOfBytesUsed());
251251
memcpy(send_packet->data, send_bs.GetData(), send_packet->length);
252252

253-
// RakPeer::AddPacketToProducer
254-
char* packets = static_cast<char*>(gRakPeer) + 0xdb6;
255-
auto write_lock = reinterpret_cast<Packet**(__thiscall*)(void*)>(sampGetWriteLockPtr());
256-
auto write_unlock = reinterpret_cast<void(__thiscall*)(void*)>(sampGetWriteUnlockPtr());
253+
{
254+
// RakPeer::AddPacketToProducer
255+
char* packets = static_cast<char*>(gRakPeer) + 0xdb6;
256+
auto write_lock = reinterpret_cast<Packet**(__thiscall*)(void*)>(sampGetWriteLockPtr());
257+
auto write_unlock = reinterpret_cast<void(__thiscall*)(void*)>(sampGetWriteUnlockPtr());
257258

258-
*write_lock(packets) = send_packet;
259-
write_unlock(packets);
260-
// RakPeer::AddPacketToProducer
259+
*write_lock(packets) = send_packet;
260+
write_unlock(packets);
261+
// RakPeer::AddPacketToProducer
262+
}
261263

262264
return true;
263265
}
264266

265-
#define RAKCLIENT_INTF *reinterpret_cast<uintptr_t*>(sampGetRakClientInterface())
267+
#define RAKCLIENT_INTF reinterpret_cast<uintptr_t>(gRakPeer) + 0xDDE
266268

267269
bool RakLuaBitStream::sendRPC(int rpcId)
268270
{

src/libs/rtdhook/rtdhook.hpp

Lines changed: 88 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,9 @@
44
#include <windows.h> // VirtualProtect
55
#include <vector>
66

7-
#pragma warning(disable : 6387) // warning C6387: _Param_(4) may be 0: this does not adhere to the specification for the function "VirtualProtect"
7+
#ifdef _DEBUG
8+
#include <assert.h>
9+
#endif
810

911
class rtdhook {
1012
typedef unsigned char byte_t;
@@ -24,7 +26,7 @@ class rtdhook {
2426
public:
2527
/**
2628
* @brief Конструктор
27-
* @details В конструкторе записываются необходимые данные, выделяется область для трамплина и оригинального пролога, методы заменяются позднее через метод install
29+
* @details В конструкторе записываются необходимые данные, выделяется область для трамплина и оригинального пролога, функция хукается позднее через метод install
2830
* @param hook_address Адрес функции
2931
* @param detour_function Функция, которая будет вызываться вмето оригинального
3032
* @param prologue_size Размер пролога
@@ -57,7 +59,7 @@ class rtdhook {
5759
}
5860

5961
/**
60-
* @brief Установка хука на виртуальный метод
62+
* @brief Установка хука на функцию
6163
*/
6264
void install()
6365
{
@@ -71,13 +73,13 @@ class rtdhook {
7173

7274
memset((void*)(mHookAddress + 5), 0x90, mHookSize - 5);
7375

74-
VirtualProtect((LPVOID)mHookAddress, mHookSize, old_protection, nullptr);
76+
VirtualProtect((LPVOID)mHookAddress, mHookSize, old_protection, &old_protection);
7577

7678
setEnabled(true);
7779
}
7880

7981
/**
80-
* @brief Снятие хука на функцию
82+
* @brief Снятие хука с функции
8183
*/
8284
void uninstall()
8385
{
@@ -90,7 +92,7 @@ class rtdhook {
9092

9193
memcpy((void*)mHookAddress, (void*)mOriginalPrologue, mHookSize);
9294

93-
VirtualProtect((LPVOID)mHookAddress, mHookSize, old_protection, nullptr);
95+
VirtualProtect((LPVOID)mHookAddress, mHookSize, old_protection, &old_protection);
9496

9597
setEnabled(false);
9698
}
@@ -100,6 +102,85 @@ class rtdhook {
100102
inline uintptr_t getTrampoline() { return mTrampoline; }
101103
};
102104

105+
class rtdhook_call {
106+
typedef unsigned char byte_t;
107+
private:
108+
bool mIsEnabled = false;
109+
110+
uintptr_t mDetourAddress;
111+
uintptr_t mHookAddress;
112+
uintptr_t mHookedFunctionAddress;
113+
114+
inline void setEnabled(bool enabled) { mIsEnabled = enabled; }
115+
116+
public:
117+
/**
118+
* @brief Конструктор
119+
* @details В конструкторе записываются необходимые данные, хук происходит позже через метод install()
120+
* @param hook_address Адрес функции
121+
* @param detour_function Функция, которая будет вызываться вместо оригинального
122+
*/
123+
template <typename T> rtdhook_call(uintptr_t hook_address, T(*detour_function))
124+
{
125+
#ifdef _DEBUG
126+
assert(*reinterpret_cast<byte_t*>(hook_address) == 0xE8);
127+
#endif
128+
129+
mDetourAddress = reinterpret_cast<uintptr_t>(detour_function);
130+
mHookAddress = hook_address;
131+
mHookedFunctionAddress = *reinterpret_cast<uintptr_t*>(mHookAddress + 1);
132+
}
133+
134+
/**
135+
* @brief Деструктор
136+
* @details В деструкторе снимается установленный хук
137+
*/
138+
~rtdhook_call()
139+
{
140+
uninstall();
141+
}
142+
143+
/**
144+
* @brief Установка хука на вызов функции
145+
*/
146+
void install()
147+
{
148+
if (isEnabled()) return;
149+
150+
DWORD old_protection;
151+
VirtualProtect((LPVOID)mHookAddress, 5, PAGE_EXECUTE_READWRITE, &old_protection);
152+
153+
*reinterpret_cast<uintptr_t*>(mHookAddress + 1) = mDetourAddress - mHookAddress - 5;
154+
155+
VirtualProtect((LPVOID)mHookAddress, 5, old_protection, &old_protection);
156+
157+
setEnabled(true);
158+
}
159+
160+
/**
161+
* @brief Снятие хука на вызов функции
162+
*/
163+
void uninstall()
164+
{
165+
// TODO: Current realisation will break other hooks installed by this address
166+
167+
if (!isEnabled()) return;
168+
169+
DWORD old_protection;
170+
VirtualProtect((LPVOID)mHookAddress, 5, PAGE_EXECUTE_READWRITE, &old_protection);
171+
172+
*reinterpret_cast<uintptr_t*>(mHookAddress + 1) = mHookedFunctionAddress;
173+
174+
VirtualProtect((LPVOID)mHookAddress, 5, old_protection, &old_protection);
175+
176+
setEnabled(false);
177+
}
178+
179+
inline bool isEnabled() { return mIsEnabled; }
180+
inline uintptr_t getHookAddress() { return mHookAddress; }
181+
inline uintptr_t getHookedFunctionAddress() { return mHookedFunctionAddress + mHookAddress + 5; }
182+
};
183+
103184
class rtdhook_vmt {
104185
typedef struct { int id; uintptr_t original; } vmt_method_t;
105186
private:
@@ -117,7 +198,7 @@ class rtdhook_vmt {
117198
uintptr_t* vmt = *reinterpret_cast<uintptr_t**>(mVmtAddress);
118199
VirtualProtect(vmt + method_id, 4, PAGE_EXECUTE_READWRITE, &old_protection);
119200
*reinterpret_cast<uintptr_t*>(vmt + method_id) = detour_function;
120-
VirtualProtect(vmt + method_id, 4, old_protection, nullptr);
201+
VirtualProtect(vmt + method_id, 4, old_protection, &old_protection);
121202
}
122203
public:
123204
/**
@@ -207,5 +288,3 @@ class rtdhook_vmt {
207288
return *reinterpret_cast<uintptr_t*>(vmt + method_id);
208289
}
209290
};
210-
211-
#pragma warning(default : 6387)

0 commit comments

Comments
 (0)