hello iam using the hkPostReceivedNetMessage to get the network message
l
the response iam getting is always
When CreateNetChannel is Called
PostReceivedNetMessage Hook
Key Points:
Two Approaches: We try both approaches to get NetChannel:
Primary: Hook CreateNetChannel and wait for it to be called
Fallback: Try to find existing NetChannel through NetworkClientService
VFunc Index Discovery: We try vfunc indices 80-90 because the exact index might vary between game versions
Interface Names: We use the same interface names as rip-crimson:
"NetworkSystemVersion001" from networksystem.dll
"NetworkClientService_001" from engine2.dll
Function Signature: The key fix was changing from void* msg to google::protobuf::Message* msg to match the actual function signature[/CODE]
l
hkPostReceivedNetMessage message id:
// PostReceivedNetMessage hook callback
void NetChannel::hkPostReceivedNetMessage(INetChannel* thisptr, NetMessageHandle_t* messageHandle,
void* msg, NetChannelBufType_t const* type, int bits) {
typedef void (*PostReceivedNetMessageFn)(INetChannel*, NetMessageHandle_t*, void*, NetChannelBufType_t const*, int);
auto original = reinterpret_cast<PostReceivedNetMessageFn>(oPostReceivedNetMessage);
// Wrap everything in try-catch to prevent crashes
try {
Logger::LogInfo("[NetChannel] Entering hkPostReceivedNetMessage\n");
// Add null checks to prevent crashes
if (!messageHandle || !msg) {
Logger::LogInfo("[NetChannel] Null messageHandle or msg, skipping\n");
return original(thisptr, messageHandle, msg, type, bits);
}
Logger::LogInfo("[NetChannel] Got messageHandle and msg\n");
short messageID = messageHandle->messageID;
// Always print the message ID for debugging
Logger::LogInfo("[NetChannel] Message ID: %d (0x%04X)\n", messageID, static_cast<unsigned short>(messageID));
// Only log detailed debugging info for valid message IDs
if (messageID > 0) {
Logger::LogInfo("[NetChannel] messageHandle pointer: %p\n", static_cast<void*>(messageHandle));
Logger::LogInfo("[NetChannel] messageHandle->unscopedName: %p\n", static_cast<void*>(const_cast<char*>(messageHandle->unscopedName)));
Logger::LogInfo("[NetChannel] messageHandle->groupName: %p\n", static_cast<void*>(const_cast<char*>(messageHandle->groupName)));
Logger::LogInfo("[NetChannel] messageHandle->protobufBinding: %p\n", static_cast<void*>(messageHandle->protobufBinding));
}
// Check if messageHandle appears to be valid
if (messageID == -1 || messageID == 0xFFFF) {
// Log invalid messages but skip processing
Logger::LogInfo("[NetChannel] Skipping invalid message ID: %d\n", messageID);
return original(thisptr, messageHandle, msg, type, bits);
}
// Skip high-frequency messages
if (Skip(messageID)) {
return original(thisptr, messageHandle, msg, type, bits);
}
// Log messages if enabled
if (gNetworkMessageLogging) {
MessageCounter++;
float currentTime = static_cast<float>(GetTickCount()) / 1000.0f;
// Log every 100th message to show progress
if (MessageCounter % 100 == 0) {
Logger::LogInfo("[NetChannel] Processed %d total messages, found %d valid ones\n",
MessageCounter, ValidMessageCounter);
}
// Only log messages with valid message IDs (greater than 0)
if (messageID > 0) {
ValidMessageCounter++;
Logger::LogInfo("[NetChannel] [%d] VALID MESSAGE ID: %d (0x%04X)\n",
MessageCounter, messageID, messageID);
// Log additional message details with null checks
if (messageHandle->unscopedName) {
Logger::LogInfo("[NetChannel] Message name: %s\n", messageHandle->unscopedName);
}
if (messageHandle->groupName) {
Logger::LogInfo("[NetChannel] Message group: %s\n", messageHandle->groupName);
}
Logger::LogInfo("[NetChannel] Message bits: %d\n", bits);
// Log raw message data for debugging
Logger::LogInfo("[NetChannel] Raw message pointer: %p\n", static_cast<void*>(msg));
if (msg) {
// Try to read the first few bytes of the message
unsigned char* msgBytes = static_cast<unsigned char*>(msg);
Logger::LogInfo("[NetChannel] First 16 bytes of message: ");
for (int i = 0; i < 16 && i < bits / 8; i++) {
Logger::LogInfo("%02X ", msgBytes[i]);
}
Logger::LogInfo("\n");
}
Logger::LogInfo("[NetChannel] --- End of valid message ---\n");
}
// Log progress every 1000 messages
if (MessageCounter % 1000 == 0) {
Logger::LogInfo("[NetChannel] Processed %d messages, found %d valid message IDs\n",
MessageCounter, ValidMessageCounter);
float timeDiff = currentTime - LastLogTime;
float rate = 1000.0f / timeDiff;
Logger::LogInfo("[NetChannel] Message rate: %.2f msgs/sec\n", rate);
LastLogTime = currentTime;
}
}
// Only process specific message types if we have a local hero
if (!LocalHero) {
return original(thisptr, messageHandle, msg, type, bits);
}
// Process different message types
Logger::LogInfo("[NetChannel] Processing message ID: %d\n", messageID);
switch (messageID) {
case DOTA_UM_TE_Projectile:
ProcessProjectileMessage(messageHandle, msg);
break;
case DOTA_UM_TE_UnitAnimation:
ProcessUnitAnimationMessage(messageHandle, msg);
break;
case DOTA_UM_CreateLinearProjectile:
ProcessCreateLinearProjectileMessage(messageHandle, msg);
break;
case DOTA_UM_DestroyLinearProjectile:
ProcessDestroyLinearProjectileMessage(messageHandle, msg);
break;
case UM_ParticleManager:
ProcessParticleManagerMessage(messageHandle, msg);
break;
}
// Call original function
return original(thisptr, messageHandle, msg, type, bits);
}
catch (...) {
// Log the crash and continue
Logger::LogInfo("[NetChannel] Exception caught in hkPostReceivedNetMessage, continuing...\n");
return original(thisptr, messageHandle, msg, type, bits);
}
}
the response iam getting is always
Код:
[NetChannel] Skipping invalid message ID: -1
[NetChannel] Entering hkPostReceivedNetMessage
[NetChannel] Got messageHandle and msg
[NetChannel] Message ID: -1 (0xFFFF)
[NetChannel] Skipping invalid message ID: -1
[NetChannel] Entering hkPostReceivedNetMessage
[NetChannel] Got messageHandle and msg
[NetChannel] Message ID: -1 (0xFFFF)
[NetChannel] Skipping invalid message ID: -1
[NetChannel] Entering hkPostReceivedNetMessage
[NetChannel] Got messageHandle and msg
[NetChannel] Message ID: -1 (0xFFFF)
[NetChannel] Skipping invalid message ID: -1
[NetChannel] Entering hkPostReceivedNetMessage
[NetChannel] Got messageHandle and msg
[NetChannel] Message ID: -1 (0xFFFF)
[NetChannel] Skipping invalid message ID: -1
[NetChannel] Entering hkPostReceivedNetMessage
[NetChannel] Got messageHandle and msg
[NetChannel] Message ID: -1 (0xFFFF)
[NetChannel] Skipping invalid message ID: -1
[NetChannel] Entering hkPostReceivedNetMessage
[NetChannel] Got messageHandle and msg
[NetChannel] Message ID: -1 (0xFFFF)
[NetChannel] Skipping invalid message ID: -1[/CODE ]
this is how iam getting the netchan and the hooks
[CODE]// 1. Get networksystem.dll handle
auto networksystem = GetModuleHandleA("networksystem.dll");
// 2. Get CreateInterface function
auto create_interface_fn = GetProcAddress(networksystem, "CreateInterface");
// 3. Get NetworkSystem interface using "NetworkSystemVersion001"
auto networkSystem = reinterpret_cast<CNetworkSystem* (*)(const char*, int*)>(create_interface_fn)
("NetworkSystemVersion001", &status);
// 4. Get CreateNetChannel function from NetworkSystem VTable (index 26)
void* createNetChannelFunc = Memory::GetVFunc<void*>(networkSystem, 26);
// 5. Create hook on CreateNetChannel
MH_CreateHook(createNetChannelFunc, &hkCreateNetChannel, &oCreateNetChannel);
// 6. Try to get existing NetChannel through NetworkClientService
auto engine2 = GetModuleHandleA("engine2.dll");
auto networkClientService = reinterpret_cast<CNetworkClientService* (*)(const char*, int*)>(create_interface_fn2)
("NetworkClientService_001", &status2);
// 7. Get existing NetChannel
INetChannel* existingNetChannel = networkClientService->GetNetChannel(0);
// 8. If found, hook PostReceivedNetMessage directly (vfunc index 86)
void* postReceivedNetMessageFunc = Memory::GetVFunc<void*>(existingNetChannel, 86);
MH_CreateHook(postReceivedNetMessageFunc, &hkPostReceivedNetMessage, &oPostReceivedNetMessage);
When CreateNetChannel is Called
Код:
// 9. When game calls CreateNetChannel, our hook intercepts it
INetChannel* NetChannel::hkCreateNetChannel(CNetworkSystem* thisptr, ...) {
// Call original function to get the new NetChannel
INetChannel* ret = original(thisptr, ...);
// 10. Hook PostReceivedNetMessage on the NEW NetChannel
// Try different vfunc indices (80-90) to find the right one
for (int i = 80; i <= 90; i++) {
postReceivedNetMessageFunc = Memory::GetVFunc<void*>(ret, i);
if (postReceivedNetMessageFunc) {
// Found it! Create the hook
MH_CreateHook(postReceivedNetMessageFunc, &hkPostReceivedNetMessage, &oPostReceivedNetMessage);
break;
}
}
}
PostReceivedNetMessage Hook
Код:
// 11. Now every network message goes through our hook
void NetChannel::hkPostReceivedNetMessage(INetChannel* thisptr, NetMessageHandle_t* messageHandle,
google::protobuf::Message* msg, NetChannelBufType_t const* type, int bits) {
// Process the message
short messageID = messageHandle->messageID;
// ... our processing logic
}
Key Points:
Two Approaches: We try both approaches to get NetChannel:
Primary: Hook CreateNetChannel and wait for it to be called
Fallback: Try to find existing NetChannel through NetworkClientService
VFunc Index Discovery: We try vfunc indices 80-90 because the exact index might vary between game versions
Interface Names: We use the same interface names as rip-crimson:
"NetworkSystemVersion001" from networksystem.dll
"NetworkClientService_001" from engine2.dll
Function Signature: The key fix was changing from void* msg to google::protobuf::Message* msg to match the actual function signature[/CODE]
Последнее редактирование: