Skip to content

Commit

Permalink
Bug Fix and Exception Handler Improvement (#168)
Browse files Browse the repository at this point in the history
  • Loading branch information
Mr-X-GTA authored Jul 21, 2024
1 parent 9944cbd commit 9062a74
Show file tree
Hide file tree
Showing 5 changed files with 91 additions and 31 deletions.
20 changes: 19 additions & 1 deletion src/core/logger/ExceptionHandler.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,25 @@ namespace YimMenu
LOG(FATAL) << "Cannot resume execution, crashing";
return EXCEPTION_CONTINUE_SEARCH;
}
exception_info->ContextRecord->Rip += opcode.len;

if (opcode.opcode == 0xFF && opcode.modrm_reg == 4) // JMP (FF /4)
{
auto return_address_ptr = (uint64_t*)exception_info->ContextRecord->Rsp;
if (IsBadReadPtr(reinterpret_cast<void*>(return_address_ptr), 8))
{
LOG(FATAL) << "Cannot resume execution, crashing";
return EXCEPTION_CONTINUE_SEARCH;
}
else
{
exception_info->ContextRecord->Rip = *return_address_ptr;
exception_info->ContextRecord->Rsp += 8;
}
}
else
{
exception_info->ContextRecord->Rip += opcode.len;
}
}

return EXCEPTION_CONTINUE_EXECUTION;
Expand Down
72 changes: 55 additions & 17 deletions src/core/logger/StackTrace.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -27,12 +27,14 @@ namespace YimMenu

m_ExceptionInfo = exception_info;

Clear();

m_Dump << ExceptionCodeToString(exception_info->ExceptionRecord->ExceptionCode) << '\n';

DumpModuleInfo();
DumpRegisters();
DumpStacktrace();
DumpCPPExceptionInfo();
DumpExceptionInfo();

m_Dump << "\n--------End of exception--------\n";
}
Expand All @@ -42,6 +44,12 @@ namespace YimMenu
return m_Dump.str();
}

void StackTrace::Clear()
{
m_Dump.str("");
m_Dump.clear();
}

// I'd prefer to make some sort of global instance that cache all modules once instead of doing this every time
void StackTrace::DumpModuleInfo()
{
Expand Down Expand Up @@ -71,8 +79,7 @@ namespace YimMenu
{
auto mod_info = ModuleInfo(table_entry->FullDllName.Buffer, table_entry->DllBase);

m_Dump << mod_info.m_Path.filename().string() << " Base Address: " << HEX(mod_info.m_Base)
<< " Size: " << mod_info.m_Size << '\n';
m_Dump << mod_info.m_Name << " Base Address: " << HEX(mod_info.m_Base) << " Size: " << mod_info.m_Size << '\n';

m_Modules.emplace_back(std::move(mod_info));
}
Expand Down Expand Up @@ -122,39 +129,70 @@ namespace YimMenu

for (size_t i = 0; i < m_FramePointers.size() && m_FramePointers[i]; ++i)
{
const auto addr = m_FramePointers[i];
const auto addr = m_FramePointers[i];
const auto module_info = GetModuleByAddress(addr);

m_Dump << "\n[" << i << "]\t";
if (SymFromAddr(GetCurrentProcess(), addr, &displacement64, symbol))
{
if (SymGetLineFromAddr64(GetCurrentProcess(), addr, &displacement, &line))
{
m_Dump << line.FileName << " L: " << line.LineNumber << " " << std::string_view(symbol->Name, symbol->NameLen);
m_Dump << line.FileName << " L: " << line.LineNumber << ' ' << std::string_view(symbol->Name, symbol->NameLen);

continue;
}

if (module_info)
{
m_Dump << module_info->m_Name << ' ' << std::string_view(symbol->Name, symbol->NameLen) << " ("
<< module_info->m_Name << '+' << HEX(addr - module_info->m_Base) << ')';

continue;
}
const auto module_info = GetModuleByAddress(addr);

if (module_info->m_Base == (uint64_t)GetModuleHandle(0))
m_Dump << module_info->m_Path.filename().string() << " " << std::string_view(symbol->Name, symbol->NameLen) << " ("
<< module_info->m_Path.filename().string() << "+" << HEX(addr - module_info->m_Base) << ")";
else
m_Dump << module_info->m_Path.filename().string() << " " << std::string_view(symbol->Name, symbol->NameLen);
m_Dump << HEX(addr) << ' ' << std::string_view(symbol->Name, symbol->NameLen);

continue;
}
const auto module_info = GetModuleByAddress(addr);
m_Dump << module_info->m_Path.filename().string() << "+" << HEX(addr - module_info->m_Base) << " " << HEX(addr);

if (module_info)
{
m_Dump << module_info->m_Name << '+' << HEX(addr - module_info->m_Base) << ' ' << HEX(addr);

continue;
}

m_Dump << HEX(addr);
}
}

void StackTrace::DumpCPPExceptionInfo()
void StackTrace::DumpExceptionInfo()
{
DWORD exception_code = m_ExceptionInfo->ExceptionRecord->ExceptionCode;

constexpr DWORD msvc_exception_code = 0xe06d7363;
if (m_ExceptionInfo->ExceptionRecord->ExceptionCode == msvc_exception_code)
if (exception_code == msvc_exception_code)
{
m_Dump << '\n'
<< reinterpret_cast<const std::exception*>(m_ExceptionInfo->ExceptionRecord->ExceptionInformation[1])->what() << '\n';
}
else if (exception_code == EXCEPTION_ACCESS_VIOLATION || exception_code == EXCEPTION_IN_PAGE_ERROR)
{
m_Dump
<< reinterpret_cast<const std::exception*>(m_ExceptionInfo->ExceptionRecord->ExceptionInformation[1])->what() << '\n';
const auto flag = m_ExceptionInfo->ExceptionRecord->ExceptionInformation[0];
const auto addr = m_ExceptionInfo->ExceptionRecord->ExceptionInformation[1];

switch (flag)
{
case EXCEPTION_READ_FAULT: m_Dump << '\n' << "Attempted to read from " << HEX(addr) << '\n'; break;
case EXCEPTION_WRITE_FAULT: m_Dump << '\n' << "Attempted to write to " << HEX(addr) << '\n'; break;
case EXCEPTION_EXECUTE_FAULT: m_Dump << '\n' << "DEP at " << HEX(addr) << '\n'; break;
default: m_Dump << '\n' << "Inaccessible data at " << HEX(addr) << '\n';
}

if (exception_code == EXCEPTION_IN_PAGE_ERROR)
{
m_Dump << "NTSTATUS code " << HEX(m_ExceptionInfo->ExceptionRecord->ExceptionInformation[2]) << '\n';
}
}
}

Expand Down
7 changes: 4 additions & 3 deletions src/core/logger/StackTrace.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ namespace YimMenu
const std::vector<uint64_t>& GetFramePointers();
void NewStackTrace(EXCEPTION_POINTERS* exception_info);
std::string GetString() const;
void Clear();

friend std::ostream& operator<<(std::ostream& os, const StackTrace& st);
friend std::ostream& operator<<(std::ostream& os, const StackTrace* st);
Expand All @@ -19,7 +20,7 @@ namespace YimMenu
struct ModuleInfo
{
ModuleInfo(std::filesystem::path path, void* base) :
m_Path(path),
m_Name(path.filename().string()),
m_Base(reinterpret_cast<uintptr_t>(base))
{
const auto dos_header = reinterpret_cast<IMAGE_DOS_HEADER*>(base);
Expand All @@ -28,7 +29,7 @@ namespace YimMenu
m_Size = nt_header->OptionalHeader.SizeOfCode;
}

std::filesystem::path m_Path;
std::string m_Name;
uintptr_t m_Base;
size_t m_Size;
};
Expand All @@ -37,7 +38,7 @@ namespace YimMenu
void DumpModuleInfo();
void DumpRegisters();
void DumpStacktrace();
void DumpCPPExceptionInfo();
void DumpExceptionInfo();
void GrabStacktrace();
const ModuleInfo* GetModuleByAddress(uint64_t addr) const;

Expand Down
2 changes: 1 addition & 1 deletion src/game/frontend/submenus/Network.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -192,7 +192,7 @@ namespace YimMenu::Submenus
}
if (ImGui::IsItemHovered())
{
ImGui::SetTooltip("This will take affect once a new player joins the session. This effect does not appear locally unless enabled above.");
ImGui::SetTooltip("This will take affect once a new player joins the session. This effect does not appear locally.");
}
}));
blipSpoofingGroup->AddItem(std::make_shared<BoolCommandItem>("spoofprimaryicon"_J));
Expand Down
21 changes: 12 additions & 9 deletions src/game/frontend/submenus/World.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -28,19 +28,16 @@ namespace YimMenu::Submenus


time->AddItem(std::make_shared<ImGuiItem>([] {
static std::string hour, minute, second;
static int hour, minute, second;
static bool freeze;
InputTextWithHint("Hour", "Enter Hour", &hour).Draw();
InputTextWithHint("Minute", "Enter Minute", &minute).Draw();
InputTextWithHint("Second", "Enter Second", &second).Draw();
ImGui::SliderInt("Hour", &hour, 0, 23);
ImGui::SliderInt("Minute", &minute, 0, 59);
ImGui::SliderInt("Second", &second, 0, 59);
ImGui::Checkbox("Freeze", &freeze);
if (ImGui::Button("Change Time"))
{
int h = std::stoi(hour);
int m = std::stoi(minute);
int s = std::stoi(second);
FiberPool::Push([=] {
ChangeTime(h, m, s, 0, freeze);
FiberPool::Push([] {
ChangeTime(hour, minute, second, 0, freeze);
});
}
if (ImGui::Button("Restore"))
Expand Down Expand Up @@ -71,6 +68,12 @@ namespace YimMenu::Submenus
}
ImGui::EndCombo();
}
if (ImGui::Button("Restore"))
{
FiberPool::Push([] {
MISC::CLEAR_OVERRIDE_WEATHER();
});
}
}));


Expand Down

0 comments on commit 9062a74

Please sign in to comment.