In efforts to learn more C++, I have chosen - you know - something fun to do and that is writing to random application's memory. The code I have written seems to work on all applications but I am having difficulties getting it to work with Google Chrome tabs.
What I am trying to do is simply change my score on Slope (on y8.com) for which I have the memory address with the help of cheat engine. The problem seems to be retrieving the Process ID of the tab. Using Chrome's Task Manager, I translated the tab's address to hex, opened the process in cheat engine and found the score address.
Here the problem comes. Whenever I use GetWindowThreadProcessId(window, &processID); cout << processID
, it doesn't print the ID which can be seen in chrome's task manager for the game's tab. In fact, it prints the ID of chrome as a whole (which I know because in chrome's task manager, "chrome" has that ID). And the score cannot be written to or read from chrome's processID. If I ignore this problem, buffer
seems to always print as 0.. no changes.
I am very new to this, and expect myself not to know what I am talking about. If you test the game yourself, you'll have to find the address that your chrome is using at the time. But here's the code (I have commented out the WriteProcessMemory
and put Read
just so I get it working before I write anything):
#include <iostream>
#include <string>
#include <Windows.h>
using namespace std;
int main() {
int buffer = 0;
LPVOID address = (LPVOID)0x15E7E1B0FB8/*(0x000000000192DFA0 + 0x0000291D8FE04000 + 0x18)*/;
cout << "Begin playing the game and wait for the 0 score to appear" << endl;
HWND window = FindWindow(NULL, "Slope Game - Play online at Y8.com");
if (window) {
cout << "Game found running! You ready to hax?" << endl;
DWORD processID = 11180;
GetWindowThreadProcessId(window, &processID);
HANDLE handle = OpenProcess(PROCESS_ALL_ACCESS, false, processID);
if (handle) {
/*string hackedScoreInput = "0";
cout << "Desired Score: " << flush; getline(cin, hackedScoreInput);
int hackedScore = stoi(hackedScoreInput);
int suc = WriteProcessMemory(handle, address, &hackedScore, sizeof(hackedScore), NULL);
if (suc > 0) {
cout << "HAXED!" << endl;
CloseHandle(handle);
}
else {
cerr << GetLastError() << endl;
cerr << hackedScore << " of size: " << sizeof(hackedScore) << endl;
return 3;
}*/
while (true) {
ReadProcessMemory(handle, address, &buffer, sizeof(buffer), NULL);
cout << buffer << " at adress: " << processID << endl;
Sleep(100);
system("CLS");
}
}
else {
cerr << "Could not open the process" << endl;
return 2;
}
}
else {
cerr << "Error! Could not find window!" << endl;
Sleep(3000);
return 1;
}
return 0;
}
What's wrong with the code?
Modern browsers use multiple processes and there is no rule that says that a browser tab HWND has to be owned by the process where the web page "runs".
Some browser implementations might have one main process that hosts the UI including all tabs but the actual web page content might be rendered to a shared bitmap/memory in a different process where it is safe to run scripts etc.
Chrome is open source so you could take a look and see if there is a way to find out which render process renders a certain tab by looking at the child processes command line arguments.