修复在使用CommandOrigin::getPlayer()获取的玩家调用Player::kick时崩溃的问题,主要是NetworkIdentifier::getHash越界访问,也许这样获取的玩家实例是不完整的

This commit is contained in:
Qiuzhizhe 2022-10-14 11:42:32 -07:00
parent ca410cd29d
commit 551594cb3e
7 changed files with 54 additions and 22 deletions

View File

@ -11,7 +11,9 @@
class DisconnectPacket : public Packet { class DisconnectPacket : public Packet {
#define AFTER_EXTRA #define AFTER_EXTRA
public:
bool mSkipMessage;
std::string mMessage;
#undef AFTER_EXTRA #undef AFTER_EXTRA
#ifndef DISABLE_CONSTRUCTOR_PREVENTION_DISCONNECTPACKET #ifndef DISABLE_CONSTRUCTOR_PREVENTION_DISCONNECTPACKET
public: public:

View File

@ -11,7 +11,11 @@
class Minecraft { class Minecraft {
#define AFTER_EXTRA #define AFTER_EXTRA
public:
inline NetworkHandler & getNetworkHandler(){
//lambda_b490644342a3912d59dc52eb79c3a67f_::operator() Line410
return dAccess<NetworkHandler>(this,24);
};
#undef AFTER_EXTRA #undef AFTER_EXTRA
#ifndef DISABLE_CONSTRUCTOR_PREVENTION_MINECRAFT #ifndef DISABLE_CONSTRUCTOR_PREVENTION_MINECRAFT
public: public:

View File

@ -4,14 +4,29 @@
#include "../Global.h" #include "../Global.h"
#define BEFORE_EXTRA #define BEFORE_EXTRA
#include "RakNet.hpp"
struct sockaddr_storage
{
__int16 ss_family;
char __ss_padding[118];
unsigned __int64 __ss_align;
};
#undef BEFORE_EXTRA #undef BEFORE_EXTRA
class NetworkIdentifier { class NetworkIdentifier {
#define AFTER_EXTRA #define AFTER_EXTRA
// Add Member There // Add Member There
char filler[160]; enum Type{
RakNet = 0x0,
Address = 0x1,
Address6 = 0x2,
Generic = 0x3,
};
RakNet::RakNetGUID mGuid;
sockaddr_storage mSock;
NetworkIdentifier::Type mType;
public: public:
LIAPI std::string getIP(); LIAPI std::string getIP();

View File

@ -10,7 +10,8 @@
class PacketSender { class PacketSender {
#define AFTER_EXTRA #define AFTER_EXTRA
__int64 _vptr;
uint8_t mSenderSubId;
#undef AFTER_EXTRA #undef AFTER_EXTRA
#ifndef DISABLE_CONSTRUCTOR_PREVENTION_PACKETSENDER #ifndef DISABLE_CONSTRUCTOR_PREVENTION_PACKETSENDER
public: public:

View File

@ -61,6 +61,7 @@
// #include <MC/ResourcePackPaths.hpp> // #include <MC/ResourcePackPaths.hpp>
#include <MC/DirectoryPackSource.hpp> #include <MC/DirectoryPackSource.hpp>
#include <MC/PackSource.hpp> #include <MC/PackSource.hpp>
#include <MC/TextPacket.hpp>
static_assert(offsetof(InventoryAction, source) == 0x0); static_assert(offsetof(InventoryAction, source) == 0x0);
static_assert(offsetof(InventoryAction, slot) == 0x0c); static_assert(offsetof(InventoryAction, slot) == 0x0c);
@ -369,18 +370,16 @@ TClasslessInstanceHook(void, "?handle@?$PacketHandlerDispatcherInstance@VPlayerA
/////////////////// PlayerChat /////////////////// /////////////////// PlayerChat ///////////////////
TInstanceHook(void, "?handle@ServerNetworkHandler@@UEAAXAEBVNetworkIdentifier@@AEBVTextPacket@@@Z", TInstanceHook(void, "?handle@ServerNetworkHandler@@UEAAXAEBVNetworkIdentifier@@AEBVTextPacket@@@Z",
ServerNetworkHandler, NetworkIdentifier* id, void* text) { ServerNetworkHandler, NetworkIdentifier* id, TextPacket* text) {
IF_LISTENED(PlayerChatEvent) { IF_LISTENED(PlayerChatEvent) {
Event::PlayerChatEvent ev{}; Event::PlayerChatEvent ev{};
ev.mPlayer = this->getServerPlayer(*id); ev.mPlayer = this->getServerPlayer(*id);
if (!ev.mPlayer) if (!ev.mPlayer)
return; return;
ev.mMessage = text->mMessage;
ev.mMessage = std::string(*(std::string*)((uintptr_t)text + 80));
if (!ev.call()) if (!ev.call())
return; return;
*(std::string*)((uintptr_t)text + 80) = ev.mMessage; text->mMessage = ev.mMessage;
} }
IF_LISTENED_END(PlayerChatEvent); IF_LISTENED_END(PlayerChatEvent);
return original(this, id, text); return original(this, id, text);

View File

@ -60,11 +60,11 @@ std::string Player::getRealName() {
} }
int Player::getAvgPing() { int Player::getAvgPing() {
return Global<NetworkHandler>->getPeerForUser(*getNetworkIdentifier())->getNetworkStatus().mAveragePing; return Global<Minecraft>->getNetworkHandler().getPeerForUser(*getNetworkIdentifier())->getNetworkStatus().mAveragePing;
} }
int Player::getLastPing() { int Player::getLastPing() {
return Global<NetworkHandler>->getPeerForUser(*getNetworkIdentifier())->getNetworkStatus().mCurrentPing; return Global<Minecraft>->getNetworkHandler().getPeerForUser(*getNetworkIdentifier())->getNetworkStatus().mCurrentPing;
} }
string Player::getIP() { string Player::getIP() {
@ -162,9 +162,19 @@ string Player::getDeviceTypeName() {
} }
bool Player::kick(const std::string& msg) { bool Player::kick(const std::string& msg) {
NetworkIdentifier* pNetworkIdentifier = getNetworkIdentifier(); // NetworkIdentifier* pNetworkIdentifier = getNetworkIdentifier();
unsigned char subID = dAccess<unsigned char>(this,3520); // Global<Minecraft>->getServerNetworkHandler()->disconnectClient(*pNetworkIdentifier, 0, msg, 0);
Global<ServerNetworkHandler>->disconnectClient(*pNetworkIdentifier, subID, msg, 0); BinaryStream wp;
if(msg.empty()){
wp.writeBool(1);
}
else{
wp.writeBool(0);
wp.writeString(msg);
}
auto pkt = MinecraftPackets::createPacket(MinecraftPacketIds::Disconnect);
pkt->read(wp);
this->sendNetworkPacket(*pkt);
return true; return true;
} }
@ -311,15 +321,16 @@ string Player::getXuid() const{
} }
unsigned char Player::getClientSubId() { unsigned char Player::getClientSubId() {
return -1; //ServerPlayer::sendNetworkPacket 参4
return dAccess<unsigned char>(this,3520);
} }
float Player::getAvgPacketLoss() { float Player::getAvgPacketLoss() {
return Global<NetworkHandler>->getPeerForUser(*getNetworkIdentifier())->getNetworkStatus().mAveragePacketLoss; return Global<Minecraft>->getNetworkHandler().getPeerForUser(*getNetworkIdentifier())->getNetworkStatus().mAveragePacketLoss;
} }
float Player::getLastPacketLoss() { float Player::getLastPacketLoss() {
return Global<NetworkHandler>->getPeerForUser(*getNetworkIdentifier())->getNetworkStatus().mCurrentPacketLoss; return Global<Minecraft>->getNetworkHandler().getPeerForUser(*getNetworkIdentifier())->getNetworkStatus().mCurrentPacketLoss;
} }
// string Player::getClientId() { // string Player::getClientId() {

View File

@ -16,11 +16,11 @@ TInstanceHook(void, "?initAsDedicatedServer@Minecraft@@QEAAXXZ", Minecraft) {
original(this); original(this);
} }
//NetworkHandler //NetworkHandler
TInstanceHook(void, "??0WorldTemplateInfo@@QEAA@AEBVWorldTemplatePackManifest@@@Z", WorldTemplateInfo, //TInstanceHook(void, "??0WorldTemplateInfo@@QEAA@AEBVWorldTemplatePackManifest@@@Z", WorldTemplateInfo,
NetworkHandler* a1) { // NetworkHandler* a1) {
Global<NetworkHandler> = a1; // Global<NetworkHandler> = a1;
original(this,a1); // original(this,a1);
} //}
// ServerNetworkHandler // ServerNetworkHandler
TInstanceHook(void, "?allowIncomingConnections@ServerNetworkHandler@@QEAAXAEBV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@_N@Z", TInstanceHook(void, "?allowIncomingConnections@ServerNetworkHandler@@QEAAXAEBV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@_N@Z",
ServerNetworkHandler, std::string const& a1, bool a2) { ServerNetworkHandler, std::string const& a1, bool a2) {