Skip to content

Instantly share code, notes, and snippets.

@bartku
Created July 25, 2011 18:34
Show Gist options
  • Save bartku/1104817 to your computer and use it in GitHub Desktop.
Save bartku/1104817 to your computer and use it in GitHub Desktop.
Logs users joining server (name, IP, GUID, MAC, experience points)
#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