Skip to content

Commit

Permalink
Merge pull request #206 from gibbed/more-improvements
Browse files Browse the repository at this point in the history
More console improvements.
  • Loading branch information
Yamashi authored Dec 21, 2020
2 parents 51f2e33 + 4ee006b commit a843dfa
Show file tree
Hide file tree
Showing 5 changed files with 191 additions and 16 deletions.
122 changes: 110 additions & 12 deletions src/overlay/Overlay.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
#include <Pattern.h>
#include <kiero/kiero.h>
#include <spdlog/spdlog.h>
#include <RED4ext/REDhash.hpp>

#include "imgui_impl_dx12.h"
#include "imgui_impl_win32.h"
Expand Down Expand Up @@ -152,7 +153,19 @@ LRESULT APIENTRY Overlay::WndProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lP
return CallWindowProc(s_pOverlay->m_wndProc, hwnd, uMsg, wParam, lParam);
}

using TScriptCall = void*(uint8_t*, uint8_t**, REDString*, void*);
struct ScriptContext
{
};

struct ScriptStack
{
uint8_t* m_code;
uint8_t pad[0x28];
void* unk30;
void* unk38;
ScriptContext* m_context;
};
static_assert(offsetof(ScriptStack, m_context) == 0x40);

TScriptCall** GetScriptCallArray()
{
Expand All @@ -162,23 +175,109 @@ TScriptCall** GetScriptCallArray()
return reinterpret_cast<TScriptCall**>(finalLocation);
}


void* Overlay::HookLog(uintptr_t apThis, uint8_t** apStack)
void Overlay::HookLog(ScriptContext* apContext, ScriptStack* apStack, void*, void*)
{
REDString result("");
apStack[6] = nullptr;
apStack[7] = nullptr;
auto stack = *(*apStack)++;
GetScriptCallArray()[stack](apStack[8], apStack, &result, nullptr);
++(*apStack);
REDString text("");
apStack->unk30 = nullptr;
apStack->unk38 = nullptr;
auto opcode = *(apStack->m_code++);
GetScriptCallArray()[opcode](apStack->m_context, apStack, &text, nullptr);
apStack->m_code++; // skip ParamEnd

Get().Log(result.ToString());
Get().Log(text.ToString());

result.Destroy();
text.Destroy();
}

const char* GetChannelStr(uint64_t hash)
{
switch (hash)
{
#define HASH_CASE(x) case RED4ext::FNV1a(x): return x
HASH_CASE("AI");
HASH_CASE("AICover");
HASH_CASE("ASSERT");
HASH_CASE("Damage");
HASH_CASE("DevelopmentManager");
HASH_CASE("Device");
HASH_CASE("Items");
HASH_CASE("ItemManager");
HASH_CASE("Puppet");
HASH_CASE("Scanner");
HASH_CASE("Stats");
HASH_CASE("StatPools");
HASH_CASE("Strike");
HASH_CASE("TargetManager");
HASH_CASE("Test");
HASH_CASE("UI");
HASH_CASE("Vehicles");
#undef HASH_CASE
}
return nullptr;
}

void Overlay::HookLogChannel(ScriptContext* apContext, ScriptStack* apStack, void*, void*)
{
uint8_t opcode;

uint64_t channel_hash = 0;
apStack->unk30 = nullptr;
apStack->unk38 = nullptr;
opcode = *(apStack->m_code++);
GetScriptCallArray()[opcode](apStack->m_context, apStack, &channel_hash, nullptr);

REDString text("");
apStack->unk30 = nullptr;
apStack->unk38 = nullptr;
opcode = *(apStack->m_code++);
GetScriptCallArray()[opcode](apStack->m_context, apStack, &text, nullptr);

apStack->m_code++; // skip ParamEnd

auto channel_str = GetChannelStr(channel_hash);
std::string channel = channel_str == nullptr
? "?" + std::to_string(channel_hash)
: std::string(channel_str);
Get().Log("[" + channel + "] " +text.ToString());

text.Destroy();
}

void Overlay::HookTDBIDToStringDEBUG(ScriptContext* apContext, ScriptStack* apStack, void* result, void*)
{
uint8_t opcode;

#pragma pack(push,1)
struct TDBID
{
uint32_t hash;
uint8_t unk4;
uint16_t unk5;
uint8_t unk7;
};
#pragma pack(pop)
static_assert(sizeof(TDBID) == 8);

TDBID tdbid_value{};
apStack->unk30 = nullptr;
apStack->unk38 = nullptr;
opcode = *(apStack->m_code++);
GetScriptCallArray()[opcode](apStack->m_context, apStack, &tdbid_value, nullptr);
apStack->m_code++; // skip ParamEnd

if (result)
{
std::string tdbid_debug = (tdbid_value.unk5 == 0 && tdbid_value.unk7 == 0)
? fmt::format("<TDBID:{:08X}:{:02X}>",
tdbid_value.hash, tdbid_value.unk4)
: fmt::format("<TDBID:{:08X}:{:02X}:{:04X}:{:02X}>",
tdbid_value.hash, tdbid_value.unk4, tdbid_value.unk5, tdbid_value.unk7);
REDString s(tdbid_debug.c_str());
((REDString*)result)->Copy(&s);
s.Destroy();
}
}

void Overlay::Toggle()
{
struct Singleton
Expand Down Expand Up @@ -215,4 +314,3 @@ void Overlay::Log(const std::string& acpText)
Overlay::Overlay() = default;

Overlay::~Overlay() = default;

16 changes: 12 additions & 4 deletions src/overlay/Overlay.h
Original file line number Diff line number Diff line change
Expand Up @@ -9,10 +9,14 @@

#include "reverse/Engine.h"

struct ScriptContext;
struct ScriptStack;
struct REDString;

using TPresentD3D12 = long(IDXGISwapChain3* pSwapChain, UINT SyncInterval, UINT Flags);
using TSetMousePosition = BOOL(void* apThis, HWND Wnd, long X, long Y);
using TClipToCenter = HWND(CGameEngine::UnkC0* apThis);
using TLog = void*(uintptr_t a1, uint8_t** a2);
using TScriptCall = void(ScriptContext*, ScriptStack*, void*, void*);

struct Image;
struct Overlay
Expand Down Expand Up @@ -49,8 +53,10 @@ struct Overlay
static BOOL SetMousePosition(void* apThis, HWND Wnd, long X, long Y);
static BOOL ClipToCenter(CGameEngine::UnkC0* apThis);
static LRESULT APIENTRY WndProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam);
static void* HookLog(uintptr_t apThis, uint8_t** apStack);

static void HookLog(ScriptContext* apContext, ScriptStack* apStack, void*, void*);
static void HookLogChannel(ScriptContext* apContext, ScriptStack* apStack, void*, void*);
static void HookTDBIDToStringDEBUG(ScriptContext* apContext, ScriptStack* apStack, void*, void*);

private:

Overlay();
Expand All @@ -61,7 +67,9 @@ struct Overlay
ID3D12DescriptorHeap* m_pd3dSrvDescHeap;
ID3D12GraphicsCommandList* m_pd3dCommandList;
TClipToCenter* m_realClipToCenter{nullptr};
TLog* m_realLog{nullptr};
TScriptCall* m_realLog{nullptr};
TScriptCall* m_realLogChannel{ nullptr };
TScriptCall* m_realTDBIDToStringDEBUG{ nullptr };
HWND m_hwnd;
WNDPROC m_wndProc{nullptr};
bool m_enabled{ false };
Expand Down
52 changes: 52 additions & 0 deletions src/overlay/Overlay_Hooks.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,58 @@ void Overlay::EarlyHooks(Image* apImage)
else
spdlog::info("\tLog function hook complete!");
}

pLocation = FindSignature({
0x48, 0x89, 0x5C, 0x24, 0x08, 0x48, 0x89, 0x74,
0x24, 0x18, 0x57, 0x48, 0x83, 0xEC, 0x40, 0x48,
0x8B, 0x02, 0x48, 0x8D, 0x3D, 0xCC, 0xCC, 0xCC,
0xCC, 0x33, 0xF6, 0x4C, 0x8D, 0x44, 0x24, 0x58,
0x48, 0x89, 0x74, 0x24, 0x58, 0x45, 0x33, 0xC9,
0x48, 0x89, 0x72, 0x30, 0x48, 0x8B, 0xDA, 0x48,
0x89, 0x72, 0x38, 0x0F, 0xB6, 0x08, 0x48, 0xFF,
0xC0, 0x48, 0x89, 0x02, 0x8B, 0xC1, 0x48, 0x8B,
0x4A, 0x40, 0xFF, 0x14, 0xC7, 0xE8, 0xCC, 0xCC,
0xCC, 0xCC, 0x48, 0x8B, 0xD0
});

if (pLocation)
{
if (MH_CreateHook(pLocation, &HookLogChannel, reinterpret_cast<void**>(&m_realLogChannel)) != MH_OK || MH_EnableHook(pLocation) != MH_OK)
{
spdlog::error("\tCould not hook LogChannel function!");
}
else
spdlog::info("\LogChannel function hook complete!");
}

pLocation = FindSignature({
0x48, 0xBF, 0x58, 0xD1, 0x78, 0xA0, 0x18, 0x09,
0xBA, 0xEC, 0x75, 0x16, 0x48, 0x8D, 0x15, 0xCC,
0xCC, 0xCC, 0xCC, 0x48, 0x8B, 0xCF, 0xE8, 0xCC,
0xCC, 0xCC, 0xCC, 0xC6, 0x05, 0xCC, 0xCC, 0xCC,
0xCC, 0x01, 0x41, 0x8B, 0x06, 0x39, 0x05, 0xCC,
0xCC, 0xCC, 0xCC, 0x7F
});

if (pLocation)
{
pLocation = &pLocation[45] + static_cast<int8_t>(pLocation[44]);
pLocation = FindSignature(pLocation, pLocation + 45, {
0x48, 0x8D, 0x0D, 0xCC, 0xCC, 0xCC, 0xCC, 0xE8,
0xCC, 0xCC, 0xCC, 0xCC, 0x83, 0x3D, 0xCC, 0xCC,
0xCC, 0xCC, 0xFF, 0x75, 0xCC, 0x48, 0x8D, 0x05,
});
if (pLocation)
{
pLocation = &pLocation[28] + *reinterpret_cast<int32_t*>(&pLocation[24]);
if (MH_CreateHook(pLocation, &HookTDBIDToStringDEBUG, reinterpret_cast<void**>(&m_realTDBIDToStringDEBUG)) != MH_OK || MH_EnableHook(pLocation) != MH_OK)
{
spdlog::error("\tCould not hook TDBID::ToStringDEBUG function!");
}
else
spdlog::info("\tTDBID::ToStringDEBUG function hook complete!");
}
}
}

long Overlay::PresentD3D12(IDXGISwapChain3* pSwapChain, UINT SyncInterval, UINT Flags)
Expand Down
16 changes: 16 additions & 0 deletions src/reverse/REDString.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,22 @@ REDString::REDString(const char* acpData)
RealStringCtor(this, acpData);
}

REDString* REDString::Copy(REDString* other)
{
static uint8_t* CopyCaller = FindSignature({
0x40, 0x53, 0x48, 0x83, 0xEC, 0x20, 0x48, 0x8B,
0xCA, 0x49, 0x8B, 0xD8, 0xE8, 0xCC, 0xCC, 0xCC,
0xCC, 0x48, 0x8B, 0xD0, 0x48, 0x8B, 0xCB, 0xE8,
0xCC, 0xCC, 0xCC, 0xCC, 0xB0, 0x01, 0x48, 0x83,
0xC4, 0x20, 0x5B, 0xC3
});
using TStringCopy = REDString*(REDString*, REDString*);
static TStringCopy* RealStringCopy = reinterpret_cast<TStringCopy*>(
&CopyCaller[28] + *reinterpret_cast<int32_t*>(&CopyCaller[24]));

return RealStringCopy(this, other);
}

void REDString::Destroy()
{
using TStringDtor = void(REDString*);
Expand Down
1 change: 1 addition & 0 deletions src/reverse/REDString.h
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ struct REDString
{
REDString();
REDString(const char* acpData);
REDString* Copy(REDString* other);
void Destroy();

char* ToString()
Expand Down

0 comments on commit a843dfa

Please sign in to comment.