Skip to content

Commit

Permalink
Big reworks
Browse files Browse the repository at this point in the history
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.
  • Loading branch information
Northn committed Sep 18, 2021
1 parent 4809cd9 commit f089088
Show file tree
Hide file tree
Showing 9 changed files with 249 additions and 89 deletions.
31 changes: 20 additions & 11 deletions src/MoonFunctions.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -201,7 +201,7 @@ uintptr_t raknetBitStreamGetDataPtr(RakLuaBitStream* bs)
return bs->getDataPtr();
}

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

void sampSendDialogResponse(uint16_t id, uint8_t button, int16_t listItem, std::string_view string = "")
void sampSendDialogResponse(uint16_t id, uint8_t button, uint16_t listItem, std::string_view string = "")
{
BitStream bs;
bs.Write(id);
Expand All @@ -245,7 +245,7 @@ void sampSendClickTextdraw(uint16_t id)
RakLuaBitStream(&bs).sendRPC(62);
}

void sampSendGiveDamage(uint16_t id, float damage, int weapon, int bodyPart)
void sampSendGiveDamage(uint16_t id, float damage, int32_t weapon, int32_t bodyPart)
{
BitStream bs;
bs.Write(false);
Expand All @@ -256,7 +256,7 @@ void sampSendGiveDamage(uint16_t id, float damage, int weapon, int bodyPart)
RakLuaBitStream(&bs).sendRPC(115);
}

void sampSendTakeDamage(uint16_t id, float damage, int weapon, int bodyPart)
void sampSendTakeDamage(uint16_t id, float damage, int32_t weapon, int32_t bodyPart)
{
BitStream bs;
bs.Write(true);
Expand All @@ -267,7 +267,10 @@ void sampSendTakeDamage(uint16_t id, float damage, int weapon, int bodyPart)
RakLuaBitStream(&bs).sendRPC(115);
}

void sampSendEditObject(bool playerObject, uint16_t objectId, int response, float posX, float posY, float posZ, float rotX, float rotY, float rotZ)
void sampSendEditObject(bool playerObject, uint16_t objectId, int32_t response,
float posX, float posY, float posZ,
float rotX, float rotY, float rotZ
)
{
BitStream bs;
bs.Write(playerObject);
Expand All @@ -286,7 +289,11 @@ void sampSendEditObject(bool playerObject, uint16_t objectId, int response, floa
}

// TODO: COLOR?
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)
void sampSendEditAttachedObject(int32_t response, int32_t index, int32_t model, int32_t bone,
float posX, float posY, float posZ,
float rotX, float rotY, float rotZ,
float scaleX, float scaleY, float scaleZ
)
{
BitStream bs;
bs.Write(response);
Expand All @@ -306,8 +313,8 @@ void sampSendEditAttachedObject(int response, int index, int model, int bone, fl
bs.Write(scaleY);
bs.Write(scaleZ);

bs.Write<int>(0);
bs.Write<int>(0);
bs.Write<int32_t>(0);
bs.Write<int32_t>(0);

RakLuaBitStream(&bs).sendRPC(116);
}
Expand All @@ -324,7 +331,7 @@ void sampSendRequestSpawn()
RakLuaBitStream().sendRPC(129);
}

void sampSendPickedUpPickup(int id)
void sampSendPickedUpPickup(int32_t id)
{
BitStream bs;
bs.Write(id);
Expand Down Expand Up @@ -384,7 +391,7 @@ void sampSendEnterVehicle(uint16_t id, bool passenger)
{
BitStream bs;
bs.Write(id);
bs.Write(passenger);
bs.Write<uint8_t>(passenger);
RakLuaBitStream(&bs).sendRPC(26);
}

Expand All @@ -400,7 +407,7 @@ void sampSendSpawn()
RakLuaBitStream().sendRPC(52);
}

void sampSendDamageVehicle(uint16_t id, int panel, int doors, uint8_t lights, uint8_t tires)
void sampSendDamageVehicle(uint16_t id, int32_t panel, int32_t doors, uint8_t lights, uint8_t tires)
{
BitStream bs;
bs.Write(id);
Expand All @@ -414,8 +421,10 @@ void sampSendDamageVehicle(uint16_t id, int panel, int doors, uint8_t lights, ui
void sampSendUpdatePlayers()
{
static DWORD dwLastUpdateTick = 0;
#pragma warning(disable : 28159) // Consider using GetTickCount64 function instead of GetTickCount
if ((GetTickCount() - dwLastUpdateTick) > 3000) {
dwLastUpdateTick = GetTickCount();
#pragma warning(default : 28159)
RakLuaBitStream().sendRPC(155);
}
}
34 changes: 16 additions & 18 deletions src/RakLua.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -22,27 +22,24 @@ RakLua::eInitState RakLua::initialize()

mState = eInitState::INITIALIZING;

std::thread([&]() {
uintptr_t sampInfo = sampGetSampInfoPtr();
while (!sampInfo)
sampInfo = sampGetSampInfoPtr();

mVmtHook = new rtdhook_vmt(*reinterpret_cast<uintptr_t*>(sampGetRakClientInterface()));
mVmtHook->install(6, &handleOutgoingPacket);
mVmtHook->install(8, &handleIncomingPacket);
mVmtHook->install(25, &handleOutgoingRpc);
mRakClientIntfConstructor = new rtdhook(sampGetRakClientIntfConstructorPtr(), &hookRakClientIntfConstructor, 7);
mRakClientIntfConstructor->install();

mState = eInitState::OK;
}).detach();
returnState:
return mState;
}

void RakLua::postRakClientInitialization(uintptr_t rakClientIntf)
{
mIncomingRpcHandlerHook = new rtdhook(sampGetIncomingRpcHandlerPtr(), &handleIncomingRpc);
mIncomingRpcHandlerHook->install();

mRakClientIntfConstructor = new rtdhook(sampGetRakClientIntfConstructorPtr(), &hookRakClientIntfConstructor, 7);
mRakClientIntfConstructor->install();
mVmtHook = new rtdhook_vmt(rakClientIntf);
mVmtHook->install(6, &handleOutgoingPacket);
mVmtHook->install(8, &handleIncomingPacket);
mVmtHook->install(25, &handleOutgoingRpc);

returnState:
return mState;
mState = eInitState::OK;
}

bool RakLua::addEventHandler(sol::this_state& ts, eEventType type, sol::function detour)
Expand Down Expand Up @@ -121,9 +118,7 @@ bool inlineIncomingPacketHandler(uint8_t id, RakLuaBitStream& luaBs)
{
luaBs.resetReadPointer();
if (!RakLua::safeCall(handler.handler, id, &luaBs))
{
return false;
}
}
return true;
}
Expand Down Expand Up @@ -238,6 +233,9 @@ uintptr_t hookRakClientIntfConstructor()
{
uintptr_t rakClientInterface = reinterpret_cast<uintptr_t(*)()>(gRakLua.getIntfConstructorHook()->getTrampoline())();
if (rakClientInterface)
gRakPeer = reinterpret_cast<void*>(rakClientInterface - 3550);
{
gRakPeer = reinterpret_cast<void*>(rakClientInterface - 0xDDE);
gRakLua.postRakClientInitialization(rakClientInterface);
}
return rakClientInterface;
}
2 changes: 2 additions & 0 deletions src/RakLua.h
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,8 @@ class RakLua
public:
eInitState initialize();
bool destroy();

void postRakClientInitialization(uintptr_t rakClientIntf);

bool addEventHandler(sol::this_state& ts, eEventType type, sol::function detour);
void destroyHandlers(sol::this_state& ts);
Expand Down
20 changes: 11 additions & 9 deletions src/RakLuaBitStream.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -145,7 +145,7 @@ float RakLuaBitStream::readFloat()

std::string RakLuaBitStream::readString(int32_t len)
{
std::string ret(len, 0);
std::string ret(len, '\0');
bs->Read(ret.data(), len);
return ret;
}
Expand Down Expand Up @@ -250,19 +250,21 @@ bool RakLuaBitStream::emulIncomingPacket(uint8_t packetId)
Packet* send_packet = reinterpret_cast<Packet*(*)(int)>(sampGetAllocPacketPtr())(send_bs.GetNumberOfBytesUsed());
memcpy(send_packet->data, send_bs.GetData(), send_packet->length);

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

*write_lock(packets) = send_packet;
write_unlock(packets);
// RakPeer::AddPacketToProducer
*write_lock(packets) = send_packet;
write_unlock(packets);
// RakPeer::AddPacketToProducer
}

return true;
}

#define RAKCLIENT_INTF *reinterpret_cast<uintptr_t*>(sampGetRakClientInterface())
#define RAKCLIENT_INTF reinterpret_cast<uintptr_t>(gRakPeer) + 0xDDE

bool RakLuaBitStream::sendRPC(int rpcId)
{
Expand Down
97 changes: 88 additions & 9 deletions src/libs/rtdhook/rtdhook.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,9 @@
#include <windows.h> // VirtualProtect
#include <vector>

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

class rtdhook {
typedef unsigned char byte_t;
Expand All @@ -24,7 +26,7 @@ class rtdhook {
public:
/**
* @brief Конструктор
* @details В конструкторе записываются необходимые данные, выделяется область для трамплина и оригинального пролога, методы заменяются позднее через метод install
* @details В конструкторе записываются необходимые данные, выделяется область для трамплина и оригинального пролога, функция хукается позднее через метод install
* @param hook_address Адрес функции
* @param detour_function Функция, которая будет вызываться вмето оригинального
* @param prologue_size Размер пролога
Expand Down Expand Up @@ -57,7 +59,7 @@ class rtdhook {
}

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

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

VirtualProtect((LPVOID)mHookAddress, mHookSize, old_protection, nullptr);
VirtualProtect((LPVOID)mHookAddress, mHookSize, old_protection, &old_protection);

setEnabled(true);
}

/**
* @brief Снятие хука на функцию
* @brief Снятие хука с функции
*/
void uninstall()
{
Expand All @@ -90,7 +92,7 @@ class rtdhook {

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

VirtualProtect((LPVOID)mHookAddress, mHookSize, old_protection, nullptr);
VirtualProtect((LPVOID)mHookAddress, mHookSize, old_protection, &old_protection);

setEnabled(false);
}
Expand All @@ -100,6 +102,85 @@ class rtdhook {
inline uintptr_t getTrampoline() { return mTrampoline; }
};

class rtdhook_call {
typedef unsigned char byte_t;
private:
bool mIsEnabled = false;

uintptr_t mDetourAddress;
uintptr_t mHookAddress;
uintptr_t mHookedFunctionAddress;

inline void setEnabled(bool enabled) { mIsEnabled = enabled; }

public:
/**
* @brief Конструктор
* @details В конструкторе записываются необходимые данные, хук происходит позже через метод install()
* @param hook_address Адрес функции
* @param detour_function Функция, которая будет вызываться вместо оригинального
*/
template <typename T> rtdhook_call(uintptr_t hook_address, T(*detour_function))
{
#ifdef _DEBUG
assert(*reinterpret_cast<byte_t*>(hook_address) == 0xE8);
#endif

mDetourAddress = reinterpret_cast<uintptr_t>(detour_function);
mHookAddress = hook_address;
mHookedFunctionAddress = *reinterpret_cast<uintptr_t*>(mHookAddress + 1);
}

/**
* @brief Деструктор
* @details В деструкторе снимается установленный хук
*/
~rtdhook_call()
{
uninstall();
}

/**
* @brief Установка хука на вызов функции
*/
void install()
{
if (isEnabled()) return;

DWORD old_protection;
VirtualProtect((LPVOID)mHookAddress, 5, PAGE_EXECUTE_READWRITE, &old_protection);

*reinterpret_cast<uintptr_t*>(mHookAddress + 1) = mDetourAddress - mHookAddress - 5;

VirtualProtect((LPVOID)mHookAddress, 5, old_protection, &old_protection);

setEnabled(true);
}

/**
* @brief Снятие хука на вызов функции
*/
void uninstall()
{
// TODO: Current realisation will break other hooks installed by this address

if (!isEnabled()) return;

DWORD old_protection;
VirtualProtect((LPVOID)mHookAddress, 5, PAGE_EXECUTE_READWRITE, &old_protection);

*reinterpret_cast<uintptr_t*>(mHookAddress + 1) = mHookedFunctionAddress;

VirtualProtect((LPVOID)mHookAddress, 5, old_protection, &old_protection);

setEnabled(false);
}

inline bool isEnabled() { return mIsEnabled; }
inline uintptr_t getHookAddress() { return mHookAddress; }
inline uintptr_t getHookedFunctionAddress() { return mHookedFunctionAddress + mHookAddress + 5; }
};

class rtdhook_vmt {
typedef struct { int id; uintptr_t original; } vmt_method_t;
private:
Expand All @@ -117,7 +198,7 @@ class rtdhook_vmt {
uintptr_t* vmt = *reinterpret_cast<uintptr_t**>(mVmtAddress);
VirtualProtect(vmt + method_id, 4, PAGE_EXECUTE_READWRITE, &old_protection);
*reinterpret_cast<uintptr_t*>(vmt + method_id) = detour_function;
VirtualProtect(vmt + method_id, 4, old_protection, nullptr);
VirtualProtect(vmt + method_id, 4, old_protection, &old_protection);
}
public:
/**
Expand Down Expand Up @@ -207,5 +288,3 @@ class rtdhook_vmt {
return *reinterpret_cast<uintptr_t*>(vmt + method_id);
}
};

#pragma warning(default : 6387)
Loading

0 comments on commit f089088

Please sign in to comment.