Skip to content

Commit

Permalink
Merge pull request #48 from jbzdarkid/patch-2
Browse files Browse the repository at this point in the history
Improve findGlobals by using a sigscan
  • Loading branch information
sigma144 authored Oct 1, 2021
2 parents e63c6f0 + 67ebc72 commit ff46042
Show file tree
Hide file tree
Showing 7 changed files with 50 additions and 52 deletions.
15 changes: 7 additions & 8 deletions App/Main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -406,20 +406,19 @@ int APIENTRY wWinMain(_In_ HINSTANCE hInstance, _In_opt_ HINSTANCE hPrevInstance
file.close();
}
else {
std::string str = "Globals ptr not found. Press OK to search for globals ptr (may take a minute or two). Please keep The Witness open during this time.";
if (MessageBox(GetActiveWindow(), std::wstring(str.begin(), str.end()).c_str(), NULL, MB_OK) != IDOK) return 0;
int address = Special::findGlobals();
std::wstring str = L"Globals ptr not found. Press OK to search for globals ptr (may take a minute or two). Please keep The Witness open during this time.";
if (MessageBox(GetActiveWindow(), str.c_str(), NULL, MB_OK) != IDOK) return 0;
int address = memory.findGlobals();
if (address) {
std::stringstream ss; ss << std::hex << "Address found: 0x" << address << ". This address wil be automatically loaded next time. Please post an issue on Github with this address so that it can be added in the future.";
std::string str = ss.str();
MessageBox(GetActiveWindow(), std::wstring(str.begin(), str.end()).c_str(), NULL, MB_OK);
std::wstringstream ss; ss << std::hex << "Address found: 0x" << address << ". This address wil be automatically loaded next time. Please post an issue on Github with this address so that it can be added in the future.";
MessageBox(GetActiveWindow(), ss.str().c_str(), NULL, MB_OK);
std::ofstream ofile("WRPGglobals.txt", std::ofstream::app);
ofile << std::hex << address << std::endl;
ofile.close();
}
else {
str = "Address could not be found. Please post an issue on the Github page.";
MessageBox(GetActiveWindow(), std::wstring(str.begin(), str.end()).c_str(), NULL, MB_OK);
str = L"Address could not be found. Please post an issue on the Github page.";
MessageBox(GetActiveWindow(), str.c_str(), NULL, MB_OK);
return 0;
}
}
Expand Down
4 changes: 2 additions & 2 deletions App/Version.h
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
#pragma once

#define TO_STRING2(s) L#s
#define TO_STRING2(s) #s
#define TO_STRING(s) TO_STRING2(s)

#define MAJOR 1
#define MINOR 2
#define PATCH 3

#define VERSION_STR TO_STRING(MAJOR) L"." TO_STRING(MINOR) L"." TO_STRING(PATCH)
#define VERSION_STR TO_STRING(MAJOR) "." TO_STRING(MINOR) "." TO_STRING(PATCH)
#define VERSION MAJOR, MINOR, PATCH

#define PRODUCT_NAME L"Witness Random Puzzle Generator"
Expand Down
40 changes: 34 additions & 6 deletions Source/Memory.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -50,28 +50,56 @@ Memory::~Memory() {
CloseHandle(_handle);
}

int find(const std::vector<byte> &data, const std::vector<byte>& search, size_t startIndex = 0) {
for (size_t i=startIndex; i<data.size() - search.size(); i++) {
// Copied from Witness Trainer https://github.com/jbzdarkid/witness-trainer/blob/master/Source/Memory.cpp#L218
int find(const std::vector<byte> &data, const std::vector<byte> &search) {
const byte* dataBegin = &data[0];
const byte* searchBegin = &search[0];
size_t maxI = data.size() - search.size();
size_t maxJ = search.size();

for (int i=0; i<maxI; i++) {
bool match = true;
for (size_t j=0; j<search.size(); j++) {
if (data[i+j] == search[j]) {
for (size_t j=0; j<maxJ; j++) {
if (*(dataBegin + i + j) == *(searchBegin + j)) {
continue;
}
match = false;
break;
}
if (match) return static_cast<int>(i);
if (match) return i;
}
return -1;
}

int Memory::findGlobals() {
const std::vector<byte> scanBytes = {0x74, 0x41, 0x48, 0x85, 0xC0, 0x74, 0x04, 0x48, 0x8B, 0x48, 0x10};
#define BUFFER_SIZE 0x10000 // 10 KB
std::vector<byte> buff;
buff.resize(BUFFER_SIZE + 0x100); // padding in case the sigscan is past the end of the buffer

for (uintptr_t i = 0; i < 0x500000; i += BUFFER_SIZE) {
SIZE_T numBytesWritten;
if (!ReadProcessMemory(_handle, reinterpret_cast<void*>(_baseAddress + i), &buff[0], buff.size(), &numBytesWritten)) continue;
buff.resize(numBytesWritten);
int index = find(buff, scanBytes);
if (index == -1) continue;

index = index + 0x14; // This scan targets a line slightly before the key instruction
// (address of next line) + (index interpreted as 4byte int)
Memory::GLOBALS = (int)(i + index + 4) + *(int*)&buff[index];
break;
}

return Memory::GLOBALS;
}

void Memory::ThrowError(std::string message) {
if (!showMsg) throw std::exception(message.c_str());
DWORD exitCode;
GetExitCodeProcess(_handle, &exitCode);
if (exitCode != STILL_ACTIVE) throw std::exception(message.c_str());
message += "\nPlease close The Witness and try again. If the error persists, please report the issue on the Github Issues page.";
MessageBox(GetActiveWindow(), std::wstring(message.begin(), message.end()).c_str(), NULL, MB_OK);
MessageBoxA(GetActiveWindow(), message.c_str(), NULL, MB_OK);
throw std::exception(message.c_str());
}

Expand Down
1 change: 1 addition & 0 deletions Source/Memory.h
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ class Memory
{
public:
Memory(const std::string& processName);
int findGlobals();
~Memory();

Memory(const Memory& memory) = delete;
Expand Down
34 changes: 3 additions & 31 deletions Source/Special.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -146,7 +146,7 @@ void Special::generateColorFilterPuzzle(int id, Point size, const std::vector<st
for (Color &c : symbolColors) {
colorCounts[c]++;
}
for (auto pair : colorCounts) {
for (const auto& pair : colorCounts) {
if (pair.second % 2) {
pass = true;
break;
Expand Down Expand Up @@ -1505,8 +1505,8 @@ void Special::drawSeedAndDifficulty(int id, int seed, bool hard, bool setSeed, b
std::string seedStr = std::to_string(seed);
createText(id, seedStr, intersections, connectionsA, connectionsB, 0.5f - seedStr.size()*0.06f, 0.5f + seedStr.size()*0.06f, setSeed ? 0.6f : 0.65f, setSeed ? 0.75f : 0.8f);
if (setSeed) createText(id, "set seed", intersections, connectionsA, connectionsB, 0.1f, 0.9f, 0.86f, 0.96f);
std::wstring version = VERSION_STR;
createText(id, std::string(version.begin(), version.end()), intersections, connectionsA, connectionsB, 0.98f - version.size()*0.06f, 0.98f, 0.02f, 0.10f);
std::string version = VERSION_STR;
createText(id, version, intersections, connectionsA, connectionsB, 0.98f - version.size()*0.06f, 0.98f, 0.02f, 0.10f);
if (options) createText(id, "option", intersections, connectionsA, connectionsB, 0.02f, 0.5f, 0.02f, 0.10f);

drawText(id, intersections, connectionsA, connectionsB, { 0.1f, 0.5f, 0.9f, 0.5f });
Expand All @@ -1522,34 +1522,6 @@ void Special::drawGoodLuckPanel(int id)
drawText(id, intersections, connectionsA, connectionsB, { 0.66f, 0.62f, 0.66f, 0.69f, 0.32f, 0.69f, 0.51f, 0.51f, 0.32f, 0.32f, 0.66f, 0.32f, 0.66f, 0.39f });
}

int Special::findGlobals() {
Panel panel;
panel._memory->retryOnFail = false; //Too slow to retry every read
int address = 0;
for (int j = 0; j < 10; j++) { //Do several passes through memory, in case of memory faults
for (int i = 0x600000; i < 0x800000; i += 4) {
Memory::GLOBALS = i;
try {
if ((address = panel._memory->ReadPanelData<int>(0x17E52, STYLE_FLAGS, 1)[0]) == 0x0000A040) {
return i;
}
}
catch (std::exception) {}
}
for (int i = 0x400000; i < 0x600000; i += 4) {
Memory::GLOBALS = i;
try {
if ((address = panel._memory->ReadPanelData<int>(0x17E52, STYLE_FLAGS, 1)[0]) == 0x0000A040) {
return i;
}
}
catch (std::exception) {}
}
Sleep(10);
}
return 0;
}

//For testing/debugging purposes only
void Special::test() {

Expand Down
2 changes: 0 additions & 2 deletions Source/Special.h
Original file line number Diff line number Diff line change
Expand Up @@ -196,8 +196,6 @@ class Special {
return -1;
}

static int findGlobals();

private:

std::shared_ptr<Generate> generator;
Expand Down
6 changes: 3 additions & 3 deletions Source/Watchdog.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -85,7 +85,7 @@ void ArrowWatchdog::initPath()
tracedLength = numTraced;
complete = false;
if (traced.size() == 0) return;
for (SolutionPoint p : traced) {
for (const SolutionPoint& p : traced) {
int p1 = p.pointA, p2 = p.pointB;
if (p1 == exitPoint || p2 == exitPoint) {
complete = true;
Expand Down Expand Up @@ -198,7 +198,7 @@ bool BridgeWatchdog::checkTouch(int id)
int numIntersections = _memory->ReadPanelData<int>(id, NUM_DOTS);
std::vector<int> intersectionFlags = _memory->ReadArray<int>(id, DOT_FLAGS, numIntersections);
std::vector<SolutionPoint> edges = _memory->ReadArray<SolutionPoint>(id, TRACED_EDGE_DATA, length);
for (SolutionPoint sp : edges) if (intersectionFlags[sp.pointA] == Decoration::Dot_Intersection || intersectionFlags[sp.pointB] == Decoration::Dot_Intersection) return true;
for (const SolutionPoint& sp : edges) if (intersectionFlags[sp.pointA] == Decoration::Dot_Intersection || intersectionFlags[sp.pointB] == Decoration::Dot_Intersection) return true;
return false;
}

Expand All @@ -220,7 +220,7 @@ void JungleWatchdog::action()
if (!tracedptr) return;
std::vector<SolutionPoint> traced = ReadArray<SolutionPoint>(id, TRACED_EDGE_DATA, numTraced);
int seqIndex = 0;
for (SolutionPoint p : traced) {
for (const SolutionPoint& p : traced) {
if ((sizes[p.pointA] & IntersectionFlags::DOT) == 0) continue;
if (sizes[p.pointA] & (0x1000 << (state ? correctSeq1[seqIndex] : correctSeq2[seqIndex])))
seqIndex++;
Expand Down

0 comments on commit ff46042

Please sign in to comment.