Created
July 25, 2011 18:34
-
-
Save bartku/1104817 to your computer and use it in GitHub Desktop.
Logs users joining server (name, IP, GUID, MAC, experience points)
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include "stdafx.h" | |
#include "misc.h" | |
#include <detours.h> | |
#include <tchar.h> | |
#pragma comment(lib, "detours.lib") | |
#pragma comment(lib, "detoured.lib") | |
struct player_data { | |
FString guid; | |
FString name; | |
FString ip; | |
FString mac; | |
INT experience; | |
} player; | |
// ?ProcessRemoteFunction@AActor@@UAEHPAVUFunction@@PAXPAUFFrame@@@Z | |
// public: virtual int __thiscall AActor::ProcessRemoteFunction(class UFunction *,void *,struct FFrame *) | |
typedef int (__stdcall *processRemoteFunction_t)(class UFunction *, void *, struct FFrame *); | |
processRemoteFunction_t processRemoteFunction = NULL; | |
// ?UpdateTime@ULevel@@UAEXPAVALevelInfo@@@Z | |
// public: virtual void __thiscall ULevel::UpdateTime(class ALevelInfo *) | |
typedef void (__stdcall *updateTime_t)(class ALevelInfo *); | |
updateTime_t updateTime = NULL; | |
UObject *pObject; | |
APlayerController *MyAPC = NULL; | |
class ALevelInfo *MyLevelInfo = NULL; | |
UFunction *fClientMessage = FIND_FUNCTION("ENGINE.Playercontroller.ClientMessage"); | |
UFunction *fPlayerNetworkAddress = FIND_FUNCTION("Engine.PlayerController.GetPlayerNetworkAddress"); | |
UFunction *fGetPBGUID = FIND_FUNCTION("Engine.LevelInfo.GetPBGUID"); | |
void ClientMessage(FString msg, APlayerController *APC) | |
{ | |
if (fClientMessage != NULL && APC != NULL) { | |
if (APC->bIsPlayer) { | |
APlayerController_eventClientMessage_Parms CMParms; | |
CMParms.S = msg; | |
APC->ProcessEvent(fClientMessage, &CMParms, NULL); | |
} | |
} | |
} | |
int __stdcall MyUpdateTime(class ALevelInfo *arg1) | |
{ | |
__asm pushad; | |
if (arg1 != NULL && MyLevelInfo == NULL) { | |
MyLevelInfo = arg1; | |
} | |
__asm popad; | |
__asm push arg1; | |
__asm call updateTime; | |
} | |
int __stdcall MyProcessRemoteFunction(class UFunction *arg1, void *arg2, struct FFrame *arg3) | |
{ | |
__asm mov pObject, ecx; | |
__asm pushad; | |
if (_tcscmp(arg1->GetFullName(), TEXT("Function AGP_Gameplay.AGP_GameMultiPlayer.EvaluatePlayerStatus")) == 0) { | |
if (((AAGP_GameMultiPlayer_execEvaluatePlayerStatus_Parms *)arg2)->PC != NULL) { | |
MyAPC = ((AAGP_GameMultiPlayer_execEvaluatePlayerStatus_Parms *)arg2)->PC; | |
player.experience = MyAPC->PlayerReplicationInfo->_Experience; | |
player.name = MyAPC->PlayerReplicationInfo->PlayerName; | |
player.mac = MyAPC->PlayerReplicationInfo->PlayerMAC; | |
if (fPlayerNetworkAddress != NULL) { | |
APlayerController_execGetPlayerNetworkAddress_Parms NetworkAddressParms; | |
MyAPC->ProcessEvent(fPlayerNetworkAddress, &NetworkAddressParms, NULL); | |
player.ip = NetworkAddressParms.ReturnValue; | |
} | |
else | |
player.ip = FString(TEXT("?")); | |
if (MyLevelInfo != NULL && fGetPBGUID != NULL) { | |
ALevelInfo_execGetPBGUID_Parms GUIDParms; | |
GUIDParms.PC = MyAPC; | |
MyLevelInfo->ProcessEvent(fGetPBGUID, &GUIDParms, NULL); | |
player.guid = GUIDParms.ReturnValue; | |
} | |
else { | |
player.guid = FString(TEXT("?")); | |
} | |
GLog->Logf(TEXT("[KutMod] User %s [%s, %s, %s, %d]"), player.name, player.guid, player.ip, player.mac, player.experience); | |
} | |
} | |
__asm popad; | |
/* Normal return should be working, but it crashes server after few executions of MyProcessRemoteFunction(). */ | |
//return prft(arg1, arg2, arg3); | |
__asm push arg3; | |
__asm push arg2; | |
__asm push arg1; | |
__asm call processRemoteFunction; | |
} | |
void Hook(void) | |
{ | |
processRemoteFunction = (processRemoteFunction_t) GetProcAddress(GetModuleHandle(TEXT("Engine.dll")), | |
"?ProcessRemoteFunction@AActor@@UAEHPAVUFunction@@PAXPAUFFrame@@@Z"); | |
updateTime = (updateTime_t) GetProcAddress(GetModuleHandle(TEXT("Engine.dll")), | |
"?UpdateTime@ULevel@@UAEXPAVALevelInfo@@@Z"); | |
DetourTransactionBegin(); | |
DetourUpdateThread(GetCurrentThread()); | |
DetourAttach(&(PVOID &)processRemoteFunction, MyProcessRemoteFunction); | |
DetourAttach(&(PVOID &)updateTime, MyUpdateTime); | |
DetourTransactionCommit(); | |
GLog->Logf(TEXT("[Logger] Hooking...")); | |
} | |
void UnHook(void) | |
{ | |
GLog->Logf(TEXT("[Logger] Unhooking...")); | |
DetourTransactionBegin(); | |
DetourUpdateThread(GetCurrentThread()); | |
DetourDetach(&(PVOID &)updateTime, MyUpdateTime); | |
DetourDetach(&(PVOID &)processRemoteFunction, MyProcessRemoteFunction); | |
DetourTransactionCommit(); | |
} | |
BOOL APIENTRY DllMain(HMODULE module, DWORD reason, | |
LPVOID reserved) | |
{ | |
switch (reason) | |
{ | |
case DLL_PROCESS_ATTACH: | |
GLog->Logf(TEXT("[Logger] ATTACH")); | |
DisableThreadLibraryCalls(module); | |
Hook(); | |
break; | |
case DLL_PROCESS_DETACH: | |
GLog->Logf(TEXT("[Logger] DETACH")); | |
UnHook(); | |
break; | |
} | |
return TRUE; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment