Skip to content

Commit

Permalink
I think git had an stroke
Browse files Browse the repository at this point in the history
  • Loading branch information
Mgamerz committed Sep 30, 2021
2 parents ae5c186 + c0c5af6 commit f78a9e8
Show file tree
Hide file tree
Showing 7 changed files with 316 additions and 48 deletions.
77 changes: 70 additions & 7 deletions KismetLogger/KismetLogger.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -13,15 +13,15 @@

#define MYHOOK "KismetLogger_"

SPI_PLUGINSIDE_SUPPORT(L"KismetLogger", L"2.0.0", L"HenBagle", SPI_GAME_LE1, SPI_VERSION_ANY);
SPI_PLUGINSIDE_SUPPORT(L"KismetLogger", L"3.0.0", L"ME3Tweaks", SPI_GAME_LE1, SPI_VERSION_ANY);
SPI_PLUGINSIDE_POSTLOAD;
SPI_PLUGINSIDE_ASYNCATTACH;

ME3TweaksASILogger logger("Kismet Logger v2", "KismetLog.txt");
ME3TweaksASILogger logger("Kismet Logger v3", "KismetLog.txt");



// ProcessEvent hook
// ProcessEvent hook (for non-native .Activated())
// ======================================================================

typedef void (*tProcessEvent)(UObject* Context, UFunction* Function, void* Parms, void* Result);
Expand Down Expand Up @@ -64,6 +64,46 @@ void ProcessEvent_hook(UObject* Context, UFunction* Function, void* Parms, void*
ProcessEvent_orig(Context, Function, Parms, Result);
}

// ======================================================================
// ProcessInternal hook (for native .Activated())
// ======================================================================

struct OutParmInfo
{
UProperty* Prop;
BYTE* PropAddr;
OutParmInfo* Next;
};

struct LE1FFrame
{
void* vtable;
int unks[3];
UStruct* Node;
UObject* Object;
BYTE* Code;
BYTE* Locals;
LE1FFrame* PreviousFrame;
OutParmInfo* OutParms;
};

typedef void (*tProcessInternal)(UObject* Context, LE1FFrame* Stack, void* Result);
tProcessInternal ProcessInternal = nullptr;
tProcessInternal ProcessInternal_orig = nullptr;
void ProcessInternal_hook(UObject* Context, LE1FFrame* Stack, void* Result)
{
auto func = Stack->Node;
auto obj = Stack->Object;
if (obj->IsA(USequenceOp::StaticClass()) && !strcmp(func->GetName(), "Activated"))
{
const auto op = reinterpret_cast<USequenceOp*>(Context);
char* fullInstancedPath = op->GetFullPath();
char* className = op->Class->Name.GetName();
logger.writeToLog(string_format("%s %s\n", className, fullInstancedPath), true);
}
ProcessInternal_orig(Context, Stack, Result);
}


SPI_IMPLEMENT_ATTACH
{
Expand All @@ -74,15 +114,38 @@ SPI_IMPLEMENT_ATTACH
SDKInitializer::Instance()->GetBioNamePools(),
SDKInitializer::Instance()->GetObjects());

INIT_FIND_PATTERN_POSTHOOK(ProcessEvent, /* 40 55 41 56 41 */ "57 48 81 EC 90 00 00 00 48 8D 6C 24 20");
if (auto rc = InterfacePtr->InstallHook(MYHOOK "ProcessEvent", ProcessEvent, ProcessEvent_hook, (void**)&ProcessEvent_orig);
// Hook ProcessEvent for Non-Native
INIT_FIND_PATTERN_POSTHOOK(ProcessEvent, /* 40 55 41 56 41 */ "57 48 81 EC 90 00 00 00 48 8D 6C 24 20");
if (auto rc = InterfacePtr->InstallHook(MYHOOK "ProcessEvent", ProcessEvent, ProcessEvent_hook, (void**)&ProcessEvent_orig);
rc != SPIReturn::Success)
{
writeln(L"Attach - failed to hook ProcessEvent: %d / %s", rc, SPIReturnToString(rc));
return false;
}

// DOESN'T WORK
//INIT_FIND_PATTERN_POSTHOOK(ProcessInternal, /*"40 53 55 56 57*/ "48 81 EC 88 00 00 00 48 8B 05 B5 25 58 01");
//if (auto rc = InterfacePtr->InstallHook(MYHOOK "ProcessInternal", ProcessInternal, ProcessInternal, reinterpret_cast<void**>(&ProcessInternal_orig));
// rc != SPIReturn::Success)
//{
// writeln(L"Attach - failed to hook ProcessInternal: %d / %s", rc, SPIReturnToString(rc));
// return false;
//}

if (const auto rc = InterfacePtr->FindPattern(reinterpret_cast<void**>(&ProcessInternal), "40 53 55 56 57 48 81 EC 88 00 00 00 48 8B 05 B5 25 58 01");
rc != SPIReturn::Success)
{
writeln(L"Attach - failed to hook ProcessEvent: %d / %s", rc, SPIReturnToString(rc));
writeln(L"Attach - failed to find ProcessInternal pattern: %d / %s", rc, SPIReturnToString(rc));
return false;
}
if (const auto rc = InterfacePtr->InstallHook(MYHOOK "ProcessInternal", ProcessInternal, ProcessInternal_hook, reinterpret_cast<void**>(&ProcessInternal_orig));
rc != SPIReturn::Success)
{
writeln(L"Attach - failed to hook ProcessInternal: %d / %s", rc, SPIReturnToString(rc));
return false;
}

return true;
return true;
}

SPI_IMPLEMENT_DETACH
Expand Down
32 changes: 32 additions & 0 deletions ME3TweaksHeader.h
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,28 @@ std::string GuidToString(FGuid guid)
}
#endif

const std::wstring wstring_format(const wchar_t* const zcFormat, ...) {

// initialize use of the variable argument array
va_list vaArgs;
va_start(vaArgs, zcFormat);

// reliably acquire the size
// from a copy of the variable argument array
// and a functionally reliable call to mock the formatting
va_list vaArgsCopy;
va_copy(vaArgsCopy, vaArgs);
const int iLen = std::vswprintf(NULL, 0, zcFormat, vaArgsCopy);
va_end(vaArgsCopy);

// return a formatted string without risking memory mismanagement
// and without assuming any compiler or platform specific behavior
std::vector<wchar_t> zc(iLen + 1);
std::vswprintf(zc.data(), zc.size(), zcFormat, vaArgs);
va_end(vaArgs);
return std::wstring(zc.data(), iLen);
}

const std::string string_format(const char* const zcFormat, ...) {

// initialize use of the variable argument array
Expand Down Expand Up @@ -179,6 +201,7 @@ class ME3TweaksASILogger
fprintf(log, "\n");
}

numLinesWritten++;
if (numLinesWritten > 10) {
fflush(log);
numLinesWritten = 0;
Expand All @@ -202,6 +225,15 @@ class ME3TweaksASILogger
}
}

void close()
{
if (log)
{
fflush(log);
fclose(log);
}
}

private:
int numLinesWritten = 0;
FILE* log;
Expand Down
10 changes: 8 additions & 2 deletions SDK/LE1SDK/SDK_HEADERS/Core_classes.h
Original file line number Diff line number Diff line change
Expand Up @@ -524,7 +524,7 @@ class UObject
virtual void VirtualFunction03 ( ); // 0x7FF7C6584690 (0x18)
virtual void VirtualFunction04 ( ); // 0x7FF7C6686A70 (0x20)
virtual void VirtualFunction05 ( ); // 0x7FF7C668A060 (0x28)
virtual void VirtualFunction06 ( ); // 0x7FF7C662A4B0 (0x30)
virtual void PostLoad ( ); // 0x7FF7C662A4B0 (0x30)
virtual void VirtualFunction07 ( ); // 0x7FF7C667D840 (0x38)
virtual void VirtualFunction08 ( ); // 0x7FF7C6687020 (0x40)
virtual void VirtualFunction09 ( ); // 0x7FF7C6584690 (0x48)
Expand Down Expand Up @@ -784,7 +784,13 @@ UClass* UMetaData::pClassPointer = NULL;
class ULinker : public UObject
{
public:
unsigned char UnknownData00[ 0x14C ]; // 0x0060 (0x014C) MISSED OFFSET
class UPackage* LinkerRoot; // 0x0060 (0x0008)
unsigned char UnknownData00[ 0xA4 ]; // 0x0068 (0x00A4) MISSED OFFSET
struct TArray<FName> NameMap; // 0x011C (0x0010)
struct TArray<FObjectImport> ImportMap; // 0x011C (0x0010)
unsigned char UnknownData01[ 0x68 ]; // 0x012C (0x0068) MISSED OFFSET
struct FString Filename; // 0x0194 (0x0010)
unsigned char UnknownData02[0x8]; // 0x01A4 (0x0008) MISSED OFFSET

private:
static UClass* pClassPointer;
Expand Down
19 changes: 19 additions & 0 deletions SDK/LE1SDK/SdkHeaders.h
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,10 @@ template< class T > struct TArray
return this->Count > 0;
}

/// <summary>
/// Do not use this on TArrays you don't create yourself, as the Unreal allocator won't work with them.
/// </summary>
/// <param name="InputData"></param>
void Add ( T InputData )
{
if (Count >= Max)
Expand Down Expand Up @@ -210,6 +214,21 @@ struct FScriptInterface
void* Interface;
};

struct FObjectResource
{
struct FName ObjectName;
int OuterIndex;
};

struct FObjectImport : public FObjectResource
{
struct FName ClassPackage;
struct FName ClassName;
class UObject* Object;
class ULinkerLoad* SourceLinker;
int SourceIndex;
};

/*
# ========================================================================================= #
# Includes
Expand Down
46 changes: 46 additions & 0 deletions SelfDebugger/DebugLogger.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@
#include "../Common.h"
#include "../ME3TweaksHeader.h"

#define MYHOOK "DebugLogger_"

SPI_PLUGINSIDE_SUPPORT(L"DebugLogger", L"1.0.0", L"ME3Tweaks", SPI_GAME_LE1 | SPI_GAME_LE2 | SPI_GAME_LE3, SPI_VERSION_ANY);
SPI_PLUGINSIDE_PRELOAD;
SPI_PLUGINSIDE_SEQATTACH;
Expand All @@ -22,6 +24,23 @@ void WINAPI OutputDebugStringW_Hook(LPCWSTR lpcszString)
OutputDebugStringW_Orig(lpcszString);
writeMsg(L"%s", lpcszString); // string already has a newline on the end
logger.writeWideToLog(std::wstring_view{ lpcszString });
logger.flush();
}

typedef UObject* (*tCreateImport)(ULinkerLoad* Context, int UIndex);
tCreateImport CreateImport = nullptr;
tCreateImport CreateImport_orig = nullptr;
UObject* CreateImport_hook(ULinkerLoad* Context, int i)
{
UObject* object = CreateImport_orig(Context, i);
if (object == nullptr)
{
FObjectImport importEntry = Context->ImportMap(i);
writeln("Could not resolve #%d: %hs in file: %s", -i - 1, importEntry.ObjectName.GetName(), Context->Filename.Data);
logger.writeWideLineToLog(wstring_format(L"Could not resolve #%d: %hs in file: %s", -i - 1, importEntry.ObjectName.GetName(), Context->Filename.Data));
logger.flush();
}
return object;
}

SPI_IMPLEMENT_ATTACH
Expand All @@ -36,6 +55,23 @@ SPI_IMPLEMENT_ATTACH
return false;
}
writeln(L"Initialized DebugLogger");


auto _ = SDKInitializer::Instance();
writeln(L"Initializing CreateImport hook...");
if (auto const rc = InterfacePtr->FindPattern(reinterpret_cast<void**>(&CreateImport), "48 8b c4 55 41 54 41 55 41 56 41 57 48 8b ec 48 83 ec 70 48 c7 45 d0 fe ff ff ff 48 89 58 10 48 89 70 18 48 89 78 20 4c 63 e2");
rc != SPIReturn::Success)
{
writeln(L"Attach - failed to find CreateImport pattern: %d / %s", rc, SPIReturnToString(rc));
return false;
}
if (auto const rc = InterfacePtr->InstallHook(MYHOOK "CreateImport", CreateImport, CreateImport_hook, reinterpret_cast<void**>(&CreateImport_orig));
rc != SPIReturn::Success)
{
writeln(L"Attach - failed to hook CreateImport: %d / %s", rc, SPIReturnToString(rc));
return false;
}
writeln(L"Hooked CreateImport");
return true;
}

Expand All @@ -44,5 +80,15 @@ SPI_IMPLEMENT_DETACH
{
//DebugActiveProcessStop(GetCurrentProcessId());
Common::CloseConsole();
logger.close();
return true;
}

BOOL APIENTRY DllMain(HMODULE hModule, DWORD reason, LPVOID) {
if (reason == DLL_PROCESS_DETACH)
{
logger.close();
}

return TRUE;
}
5 changes: 3 additions & 2 deletions SeqActLog Enabler/LE1SeqActLogEnabler.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -200,6 +200,7 @@ SPI_IMPLEMENT_ATTACH

SPI_IMPLEMENT_DETACH
{
Common::CloseConsole();
return true;
logger.flush();
Common::CloseConsole();
return true;
}
Loading

0 comments on commit f78a9e8

Please sign in to comment.