Added ConVar/Command dumper to log.

This commit is contained in:
PixieCore 2021-08-12 01:43:34 +02:00 committed by GitHub
commit 9a2b086f16
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 58 additions and 72 deletions

View File

@ -304,6 +304,15 @@ public:
float m_flMaxValue; //0x007C
}; //Size: 0x0080
class CCVarIteratorInternal // Fully reversed table, just look at the virtual function table and rename the function.
{
public:
virtual void SetFirst(void) = 0; //0
virtual void Next(void) = 0; //1
virtual bool IsValid(void) = 0; //2
virtual ConCommandBase* Get(void) = 0; //3
};
class CCVar
{
public:
@ -324,6 +333,29 @@ public:
using OriginalFn = void*(__thiscall*)(CCVar*, const char*);
return (*reinterpret_cast<OriginalFn**>(this))[18](this, szCommandName);
}
CCVarIteratorInternal* FactoryInternalIterator() // @0x140597C10 in R5pc_r5launch_N1094_CL456479_2019_10_30_05_20_PM
{
using OriginalFn = CCVarIteratorInternal*(__thiscall*)(CCVar*);
return (*reinterpret_cast<OriginalFn**>(this))[41](this);
}
std::unordered_map<std::string, ConCommandBase*> DumpToMap()
{
std::stringstream ss;
CCVarIteratorInternal* itint = FactoryInternalIterator(); // Allocatd new InternalIterator.
std::unordered_map<std::string, ConCommandBase*> allConVars;
for (itint->SetFirst(); itint->IsValid(); itint->Next()) // Loop through all instances.
{
ConCommandBase* command = itint->Get();
const char* commandName = command->m_pszName;
allConVars[commandName] = command;
}
return allConVars;
}
};
struct Interface

View File

@ -104,6 +104,16 @@ void CGameConsole::Draw(const char* title)
ProcessCommand("exec netchan");
}
ImGui::PopStyleColor(); // Pop color override.
if (ImGui::SmallButton("Commands/Convars to Console"))
{
if (GameGlobals::Cvar)
{
for (auto map : GameGlobals::Cvar->DumpToMap())
{
AddLog("%s\n", map.first.c_str());
}
}
}
ImGui::EndPopup();
}
if (ImGui::Button("Tools"))
@ -125,9 +135,8 @@ void CGameConsole::Draw(const char* title)
{
const char* item = Items[i];
if (!Filter.PassFilter(item))
{
continue;
}
///////////////////////////////////////////////////////////////////
ImVec4 color;
bool has_color = false;
@ -176,11 +185,23 @@ void CGameConsole::Draw(const char* title)
// Filters
//if (strstr(item, ") -> ")) { color = ImVec4(1.00f, 1.00f, 1.00f, 0.70f); has_color = true; }
if (has_color) { ImGui::PushStyleColor(ImGuiCol_Text, color); }
ImGui::TextWrapped(item);
if (has_color) { ImGui::PopStyleColor(); }
if (has_color)
{
ImGui::PushStyleColor(ImGuiCol_Text, color);
}
ImGui::TextWrapped(item);
if (has_color)
{
ImGui::PopStyleColor();
}
}
if (copy_to_clipboard)
{
ImGui::LogFinish();
}
if (copy_to_clipboard) { ImGui::LogFinish(); }
if (ScrollToBottom || (AutoScroll && ImGui::GetScrollY() >= ImGui::GetScrollMaxY())) { ImGui::SetScrollHereY(1.0f); }
ScrollToBottom = false;

View File

@ -557,7 +557,6 @@ public:
}
}
}
return MemoryAddress(latestOccurence);
}

View File

@ -29,72 +29,6 @@ MODULEINFO GetModuleInfo(const char* szModule)
return modinfo;
}
///////////////////////////////////////////////////////////////////////////////
// For finding a byte pattern in memory of the game process
std::uint8_t* PatternScan(const char* module, const char* signature)
{
static auto PatternToBytes = [](const char* pattern)
{
char* PatternStart = const_cast<char*>(pattern); // Cast const away and get start of pattern.
char* PatternEnd = PatternStart + std::strlen(pattern); // Get end of pattern.
std::vector<std::int32_t> Bytes = std::vector<std::int32_t>{ }; // Initialize byte vector.
for (char* CurrentByte = PatternStart; CurrentByte < PatternEnd; ++CurrentByte)
{
if (*CurrentByte == '?') // Is current char(byte) a wildcard?
{
++CurrentByte; // Skip 1 character.
if (*CurrentByte == '?') // Is it a double wildcard pattern?
++CurrentByte; // If so skip the next space that will come up so we can reach the next byte.
Bytes.push_back(-1); // Push the byte back as invalid.
}
else
{
// https://stackoverflow.com/a/43860875/12541255
// Here we convert our string to a unsigned long integer. We pass our string then we use 16 as the base because we want it as hexadecimal.
// Afterwards we push the byte into our bytes vector.
Bytes.push_back(std::strtoul(CurrentByte, &CurrentByte, 16));
}
}
return Bytes;
};
const MODULEINFO mInfo = GetModuleInfo(module); // Get module info.
const DWORD64 SizeOfModule = (DWORD64)mInfo.SizeOfImage; // Grab the module size.
std::uint8_t* ScanBytes = reinterpret_cast<std::uint8_t*>(mInfo.lpBaseOfDll); // Get the base of the module.
const std::vector<int> PatternBytes = PatternToBytes(signature); // Convert our pattern to a byte array.
const std::pair BytesInfo = std::make_pair(PatternBytes.size(), PatternBytes.data()); // Get the size and data of our bytes.
for (DWORD i = 0ul; i < SizeOfModule - BytesInfo.first; ++i)
{
bool FoundAddress = true;
for (DWORD j = 0ul; j < BytesInfo.first; ++j)
{
// If either the current byte equals to the byte in our pattern or our current byte in the pattern is a wildcard
// our if clause will be false.
if (ScanBytes[i + j] != BytesInfo.second[j] && BytesInfo.second[j] != -1)
{
FoundAddress = false;
break;
}
}
if (FoundAddress)
{
return &ScanBytes[i];
}
}
return nullptr;
}
///////////////////////////////////////////////////////////////////////////////
//
void DbgPrint(LPCSTR sFormat, ...)