Wäre es eventuell möglich für jemanden das auf Deutsch zu übersetzen, mit meinem Schulenglisch komme ich leider nicht sooo weit.. ^^
Do you think you could explain how this tool works?Quote:
The inspector.pak (contained in the awesomium sdk) must be placed into awesomiums working directory, typically in your temp folder starting with gw2cache-.
I've written a small tool to enable the remote debugger.
Run it to start Guild Wars 2.
Try to enter localhost:81 in Chrome.
Source:
PHP Code:#include <iostream>
#include <vector>
#include <string>
#include <windows.h>
#include <algorithm>
#include <iterator>
#include <Psapi.h>
#include <set>
using namespace std;
enum LogLevel {
kLogLevel_None = 0,
kLogLevel_Normal,
kLogLevel_Verbose,
};
set<wstring> findGw2() {
set<wstring> result;
HKEY hKey;
wstring muiCacheKeys[] = {
L"Software\\Microsoft\\Windows\\ShellNoRoam\\MUICache",
L"Software\\Classes\\Local Settings\\Software\\Microsoft\\Windows\\Shell\\MuiCache"
};
bool success = false;
for (int i = 0; i < 2; i++) {
if (RegOpenKeyExW(HKEY_CURRENT_USER, muiCacheKeys[i].c_str(), 0, KEY_READ, &hKey) == ERROR_SUCCESS) {
success = true;
}
}
if (!success)
return result;
int index = 0;
wstring t = L"Guild Wars 2 Game Client";
wchar_t path[MAX_PATH];
byte data[sizeof(L"Guild Wars 2 Game Client") * sizeof(wchar_t)];
DWORD type;
LSTATUS status;
do {
DWORD sPath = sizeof(path) * sizeof(wchar_t);
DWORD sData = sizeof(data);
status = RegEnumValueW(hKey, index, path, &sPath, NULL, &type, data, &sData);
if (status == ERROR_SUCCESS && type == REG_SZ && wstring((wchar_t*) data, 0, sData / sizeof(wchar_t) -1) == t)
result.insert(wstring(path, 0, sPath));
index++;
} while (status != ERROR_NO_MORE_ITEMS);
RegCloseKey(hKey);
return result;
}
int main(int argc, char **argv) {
////////////////////////////////////////////////////////////////////
// Change this if you want: //
int port = 81;
LogLevel log_level = kLogLevel_Normal;
// //
////////////////////////////////////////////////////////////////////
PROCESS_INFORMATION processInfo;
int pid;
set<wstring> paths = findGw2();
cout << "start Guild Wars 2" << endl;
bool success = false;
for (set<wstring>::iterator i = paths.begin(); i != paths.end(); i++) {
STARTUPINFOW info;
ZeroMemory(&info, sizeof(info));
if (CreateProcessW((*i).c_str(), NULL, NULL, NULL, TRUE, 0, NULL, NULL, &info, &processInfo)) {
success = true;
break;
}
}
if (!success) {
cout << "Error CreateProcess(...)" << endl;
system("pause");
return 1;
}
WaitForInputIdle(processInfo.hProcess, INFINITE);
CloseHandle(processInfo.hThread);
pid = GetProcessId(processInfo.hProcess);
cout << "atach debugger" << endl;
cout << "wait for awesomium.dll" << endl;
if (!DebugActiveProcess(pid)) {
cout << "Error DebugActiveProcess(" << pid << ")" << endl;
system("pause");
return 1;
}
DEBUG_EVENT e;
ZeroMemory(&e, sizeof(e));
const LPDEBUG_EVENT DebugEv = &e;
int dwContinueStatus = DBG_EXCEPTION_NOT_HANDLED;
SIZE_T c;
char backup;
PVOID breakPoint = NULL;
const char debugBreak = 0xCC;
bool done = false;
do {
dwContinueStatus = DBG_EXCEPTION_NOT_HANDLED;
ZeroMemory(DebugEv, sizeof(DebugEv));
// Wait for a debugging event to occur. The second parameter indicates
// that the function does not return until a debugging event occurs.
WaitForDebugEvent(DebugEv, INFINITE);
// Process the debugging event code.
switch (DebugEv->dwDebugEventCode) {
case EXCEPTION_DEBUG_EVENT:
if (breakPoint && DebugEv->u.Exception.ExceptionRecord.ExceptionAddress == breakPoint) {
cout << "reached debugbreak" << endl;
// restore backup instruction
WriteProcessMemory(processInfo.hProcess, breakPoint, &backup, sizeof(backup), &c);
FlushInstructionCache(processInfo.hProcess, breakPoint, sizeof(backup));
processInfo.hThread = OpenThread(THREAD_GET_CONTEXT | THREAD_SET_CONTEXT | THREAD_SUSPEND_RESUME, false, DebugEv->dwThreadId);
CONTEXT context;
ZeroMemory(&context, sizeof(context));
context.ContextFlags = CONTEXT_FULL;
GetThreadContext(processInfo.hThread, &context);
context.Eip--; // -1 to execute the backup instruction
cout << "patch log_level <-- " << log_level << endl;
WriteProcessMemory(processInfo.hProcess, (PVOID) context.Eax, &log_level, sizeof(log_level), &c);
cout << "patch port <-- " << port << endl;
WriteProcessMemory(processInfo.hProcess, (PVOID) (context.Eax + 6 * sizeof(int)), &port, sizeof(port), &c);
SetThreadContext(processInfo.hThread, &context);
CloseHandle(processInfo.hThread);
dwContinueStatus = DBG_CONTINUE;
done = true;
}
break;
case EXIT_PROCESS_DEBUG_EVENT:
return 1;
case LOAD_DLL_DEBUG_EVENT:
char name[MAX_PATH];
int ptr;
ptr = 0;
ReadProcessMemory(processInfo.hProcess, DebugEv->u.LoadDll.lpImageName, &ptr, sizeof(ptr), &c);
ReadProcessMemory(processInfo.hProcess, (void*) ptr, name, sizeof(name), &c);
if (DebugEv->u.LoadDll.fUnicode) {
wstring f;
f = wstring((wchar_t*) name);
wstring t;
t = L"awesomium.dll";
if (f.length() > t.length() && f.substr(f.length() - t.length(), t.length()) == t) {
cout << "awesomium.dll loaded" << endl;
cout << "insert debugbreak at Awesomium::WebCore::Initialize(Awesomium::WebConfig)" << endl;
breakPoint = (PVOID) ((unsigned) DebugEv->u.LoadDll.lpBaseOfDll + 0x43D80);
ReadProcessMemory(processInfo.hProcess, breakPoint, &backup, sizeof(backup), &c);
WriteProcessMemory(processInfo.hProcess, breakPoint, &debugBreak, sizeof(debugBreak), &c);
}
}
break;
}
// Resume executing the thread that reported the debugging event.
for (int i = 0; i < 3 && (!ContinueDebugEvent(DebugEv->dwProcessId,
DebugEv->dwThreadId,
dwContinueStatus)); i++){
};
} while (!done);
cout << "detach debugger" << endl;
if (!DebugActiveProcessStop(pid)) {
cout << "Error DebugActiveProcessStop(" << pid << ")" << endl;
system("pause");
return 1;
}
CloseHandle(processInfo.hProcess);
cout << "try to enter localhost:" << port << " in Chrome" << endl;
Sleep(5000);
return 0;
}