Skip to content

Commit

Permalink
Add messages to asserts so we can tell them apart
Browse files Browse the repository at this point in the history
  • Loading branch information
jbzdarkid committed May 7, 2023
1 parent a37a79b commit 3719bc1
Show file tree
Hide file tree
Showing 6 changed files with 30 additions and 38 deletions.
4 changes: 2 additions & 2 deletions App/Main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -118,8 +118,8 @@ void SetStringText(HWND hwnd, const std::wstring& text) {
}

void SetPosAndAngText(HWND hwnd, const std::vector<float>& pos, const std::vector<float>& ang) {
assert(pos.size() == 3);
assert(ang.size() == 2);
assert(pos.size() == 3, "[Internal error] Attempted to set position of <> 3 elements");
assert(ang.size() == 2, "[Internal error] Attempted to set angle of <> 2 elements");
wchar_t text[128] = {'\0'};
swprintf_s(text, sizeof(text) / sizeof(text[0]), L"X %.3f\nY %.3f\nZ %.3f\n\u0398 %.8f\n\u03A6 %.8f", pos[0], pos[1], pos[2], ang[0], ang[1]);
#pragma push_macro("SetWindowTextW")
Expand Down
3 changes: 2 additions & 1 deletion Source/DebugUtils.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -64,11 +64,12 @@ std::wstring DebugUtils::GetStackTrace() {

std::wstring DebugUtils::version = L"(unknown)"; // Slight hack. Will be overwritten by main during startup.
time_t lastShownAssert = ~0ULL; // MAXINT
void DebugUtils::ShowAssertDialogue() {
void DebugUtils::ShowAssertDialogue(const wchar_t* message) {
// Only show an assert every 30 seconds. This prevents assert loops inside the WndProc, as well as adding a grace period after an assert fires.
if (time(nullptr) - lastShownAssert < 30) return;
std::wstring msg = L"WitnessTrainer version " + version + L" has encountered an error.\n";
msg += L"Please press Control C to copy this error, and paste it to darkid.\n";
msg += message;
msg += GetStackTrace();
MessageBox(NULL, msg.c_str(), L"WitnessTrainer encountered an error.", MB_TASKMODAL | MB_ICONHAND | MB_OK | MB_SETFOREGROUND);
lastShownAssert = time(nullptr);
Expand Down
6 changes: 3 additions & 3 deletions Source/DebugUtils.h
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ class DebugUtils final
{
public:
static void RegenerateCallstack(const std::wstring& callstack);
static void ShowAssertDialogue();
static void ShowAssertDialogue(const wchar_t* message);
static std::wstring version;
// Returns [start of module, end of module)
static std::pair<uint64_t, uint64_t> GetModuleBounds(HANDLE process);
Expand All @@ -24,6 +24,6 @@ void SetCurrentThreadName(const wchar_t* name);
#define DebugPrint(text)
#endif

inline void ShowAssertDialogue() {
DebugUtils::ShowAssertDialogue();
inline void ShowAssertDialogue(const wchar_t* message) {
DebugUtils::ShowAssertDialogue(message);
}
37 changes: 13 additions & 24 deletions Source/Memory.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -110,8 +110,7 @@ void Memory::Heartbeat(HWND window, UINT message) {
}

if (_hwnd == NULL) {
DebugPrint("Couldn't find the HWND for the game");
assert(false);
assert(false, "Couldn't find the HWND for the game");
return;
}

Expand Down Expand Up @@ -294,31 +293,29 @@ std::string Memory::ReadString(std::vector<__int64> offsets) {
}

void Memory::ReadDataInternal(void* buffer, uintptr_t computedOffset, size_t bufferSize) {
assert(bufferSize > 0);
assert(bufferSize > 0, "[Internal error] Attempting to read 0 bytes");
if (!_handle) return;
// Ensure that the buffer size does not cause a read across a page boundary.
if (bufferSize > 0x1000 - (computedOffset & 0x0000FFF)) {
bufferSize = 0x1000 - (computedOffset & 0x0000FFF);
}
if (!ReadProcessMemory(_handle, (void*)computedOffset, buffer, bufferSize, nullptr)) {
DebugPrint("Failed to read process memory.");
assert(false);
assert(false, "Failed to read process memory.");
}
}

void Memory::WriteDataInternal(const void* buffer, const std::vector<__int64>& offsets, size_t bufferSize) {
assert(bufferSize > 0);
assert(bufferSize > 0, "[Internal error] Attempting to read 0 bytes");
if (!_handle) return;
if (offsets.empty() || offsets[0] == 0) return; // Empty offset path passed in.
if (!WriteProcessMemory(_handle, (void*)ComputeOffset(offsets), buffer, bufferSize, nullptr)) {
DebugPrint("Failed to write process memory.");
assert(false);
assert(false, "Failed to write process memory.");
}
}

uintptr_t Memory::ComputeOffset(std::vector<__int64> offsets, bool absolute) {
assert(offsets.size() > 0);
assert(offsets.front() != 0);
assert(offsets.size() > 0, "[Internal error] Attempting to compute 0 offsets");
assert(offsets.front() != 0, "[Internal error] First offset to compute was 0");

// Leave off the last offset, since it will be either read/write, and may not be of type uintptr_t.
const __int64 final_offset = offsets.back();
Expand Down Expand Up @@ -346,21 +343,13 @@ uintptr_t Memory::ComputeOffset(std::vector<__int64> offsets, bool absolute) {
}

MEMORY_BASIC_INFORMATION info;
if (computedAddress == 0) {
DebugPrint("Attempted to dereference NULL!");
assert(false);
} else if (!VirtualQuery(reinterpret_cast<LPVOID>(cumulativeAddress), &info, sizeof(info))) {
DebugPrint("Failed to read process memory, probably because cumulativeAddress was too large.");
assert(false);
} else if (info.State != MEM_COMMIT) {
DebugPrint("Attempted to read unallocated memory.");
assert(false);
} else if ((info.AllocationProtect & 0xC4) == 0) { // 0xC4 = PAGE_EXECUTE_READWRITE | PAGE_EXECUTE_WRITECOPY | PAGE_READWRITE
DebugPrint("Attempted to read unreadable memory.");
assert(false);
assert(computedAddress != 0, "Attempted to dereference NULL!");
if (!VirtualQuery(reinterpret_cast<LPVOID>(cumulativeAddress), &info, sizeof(info))) {
assert(false, "Failed to read process memory, possibly because cumulativeAddress was too large.");
} else {
DebugPrint("Failed to read memory for some as-yet unknown reason.");
assert(false);
assert(info.State == MEM_COMMIT, "Attempted to read unallocated memory.");
assert(info.AllocationProtect & 0xC4, "Attempted to read unreadable memory."); // 0xC4 = PAGE_EXECUTE_READWRITE | PAGE_EXECUTE_WRITECOPY | PAGE_READWRITE
assert(false, "Failed to read memory for some as-yet unknown reason."); // Won't fire an assert dialogue if a previous one did, because that would be within 30s.
}
return 0;
}
Expand Down
2 changes: 1 addition & 1 deletion Source/Trainer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -374,7 +374,7 @@ void Trainer::DisableDistanceGating() {
std::string typeName = _memory->ReadString({_globals, 0x18, id * 8, 0x08, 0x08});
if (typeName != "Machine_Panel") continue;

assert(_globals == 0x62D0A0);
assert(_globals == 0x62D0A0, "DisableDistanceGating is only supported on the latest version");
float distanceGated = _memory->ReadAbsoluteData<float>({entity, 0x3BC}, 1)[0];
if (distanceGated != 0.0f) _memory->WriteData<float>({_globals, 0x18, id * 8, 0x3BC}, {0.0f});
}
Expand Down
16 changes: 9 additions & 7 deletions Source/pch.h
Original file line number Diff line number Diff line change
@@ -1,10 +1,12 @@
#pragma once

#define W(x) W_(x)
#define W_(x) L ## x
#undef assert
#define assert(expr) \
#define assert(expr, message) \
if (!(expr)) { \
void ShowAssertDialogue(); \
ShowAssertDialogue(); \
void ShowAssertDialogue(const wchar_t*); \
ShowAssertDialogue(W_(message)); \
}

#define _HAS_EXCEPTIONS 0
Expand All @@ -13,13 +15,13 @@
#include <crtdbg.h>
#undef _RPT_BASE
#define _RPT_BASE(...) \
void ShowAssertDialogue(); \
ShowAssertDialogue();
void ShowAssertDialogue(const wchar_t*); \
ShowAssertDialogue(nullptr);

#undef _RPT_BASE_W
#define _RPT_BASE_W(...) \
void ShowAssertDialogue(); \
ShowAssertDialogue();
void ShowAssertDialogue(const wchar_t*); \
ShowAssertDialogue(nullptr);

#define WIN32_LEAN_AND_MEAN 1
#define VC_EXTRALEAN 1
Expand Down

0 comments on commit 3719bc1

Please sign in to comment.