Code:
// MOHRadiant Coord Grabber.cpp : Defines the entry point for the console application.
//
#include "stdafx.h"
#include "windows.h"
#include "commctrl.h"
#include <iostream>
using namespace std;
bool setDebug() {
HANDLE hToken;
if(OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, &hToken)) {
TOKEN_PRIVILEGES tp;
LUID luid;
TOKEN_PRIVILEGES tpPrevious;
DWORD cbPrevious = sizeof(TOKEN_PRIVILEGES);
if(LookupPrivilegeValue(NULL, SE_DEBUG_NAME, &luid)) {
tp.PrivilegeCount = 1;
tp.Privileges[0].Luid = luid;
tp.Privileges[0].Attributes = 0;
if(AdjustTokenPrivileges(hToken, FALSE, &tp, sizeof(TOKEN_PRIVILEGES), &tpPrevious, &cbPrevious)) {
tpPrevious.PrivilegeCount = 1;
tpPrevious.Privileges[0].Luid = luid;
tpPrevious.Privileges[0].Attributes |= (SE_PRIVILEGE_ENABLED);
if(AdjustTokenPrivileges( hToken, FALSE, &tpPrevious, cbPrevious, NULL, NULL )) {
CloseHandle(hToken);
return true;
}
}
}
}
CloseHandle(hToken);
return false;
}
void err(const char * msg) {
cout << msg << endl << endl;
system("PAUSE");
}
//Magic in here...
void crazything(wchar_t * lol) {
wchar_t tmp[255];
wcscpy_s(tmp, lol);
wchar_t * tok = wcstok(tmp, L" ");
while( wcstok(NULL, L" ") != NULL ) {
tok = wcstok(NULL, L" ");
}
short c = 0;
wcout << "( ";
for(UINT i=0; i < wcslen(lol); i++) {
if(lol[i] == 32) {
if(++c==2) {
break;
}
}
wcout << lol[i];
}
wcout << " " << _wtoi(tok) - 64 << " ) ";
}
int _tmain(int argc, _TCHAR* argv[])
{
//Set debug privelages to prevent any access errors
setDebug();
cout << "Ensure that the Entities window is open in Radiant\n(Edit->Entity Info)\n--------------------------\n";
HWND hwnd=FindWindow(NULL, L"Entities");
//Check that the Entities window is open
if(!hwnd) {
err("Entitys window not found");
return 1;
}
HWND listview=FindWindowEx(hwnd, NULL, L"SysListView32", NULL);
HWND treeview=FindWindowEx(hwnd, NULL, L"SysTreeView32", NULL);
//Check we have a treeview and a list view
if(!listview || !treeview) {
err("Entitys window dosnt contain required controls");
return 1;
}
DWORD pID;
GetWindowThreadProcessId(treeview, &pID);
HANDLE hProcess = OpenProcess(PROCESS_ALL_ACCESS, false, pID);
//Open Radiant process
if(!hProcess) {
err("Error opening process");
return 1;
}
DWORD tvRemoteBuffer = (DWORD)::VirtualAllocEx(hProcess, NULL, 335, MEM_COMMIT, PAGE_READWRITE);
//Allocate tvnode memory
if(!tvRemoteBuffer) {
CloseHandle(hProcess);
err("Error allocating memory");
return 1;
}
//Assume that all memory allocating will work since i cba to write more if's
LVITEM * lvRemoteBuffer=(LVITEM*)VirtualAllocEx(hProcess, NULL, sizeof(LVITEM), MEM_COMMIT, PAGE_READWRITE);
wchar_t * key=(wchar_t*)VirtualAllocEx(hProcess, NULL, 255, MEM_COMMIT, PAGE_READWRITE);
HTREEITEM Root = (HTREEITEM)SendMessage(treeview, TVM_GETNEXTITEM, TVGN_ROOT, 0);
bool foundDoor = false;
wchar_t * msg = L"func_rotatingdoor";
int doorCount = 0;
//Parse nodes in treeview
while(Root) {
TVITEM tvItem;
tvItem.mask = TVIF_TEXT;
tvItem.hItem = Root;
tvItem.pszText = (LPWSTR)tvRemoteBuffer + sizeof(TVITEM);
tvItem.cchTextMax = 255;
//Write treeview to external buffer
if(WriteProcessMemory(hProcess, (LPVOID)tvRemoteBuffer, (LPCVOID)&tvItem, sizeof(TVITEM), 0)) {
//Load the item to the buffer
SendMessage(treeview, TVM_GETITEM, 0, tvRemoteBuffer);
wchar_t bytRtn[255];
int rAdd = tvRemoteBuffer + sizeof(TVITEM)*2;
//Read the text
if(ReadProcessMemory(hProcess, (LPCVOID)rAdd, (LPVOID)&bytRtn, 255, 0)) {
//Check if its a door!
if(wcscmp(bytRtn, msg) == 0) {
if(!foundDoor) {
//Found the root door node
SendMessage( treeview, TVM_SELECTITEM, TVGN_CARET, (LPARAM)Root );
SendMessage( treeview, TVM_EXPAND, TVE_EXPAND, (LPARAM)Root );
foundDoor = true;
} else {
//Found a child door node
SendMessage( treeview, TVM_SELECTITEM, TVGN_CARET, (LPARAM)Root );
doorCount++;
//Get listview stuff now
LVITEM lvi;
lvi.cchTextMax=255;
int count=(int)SendMessage(listview, LVM_GETITEMCOUNT, 0, 0);
wchar_t gots[255];
char got = 0;
//Loop through listview items
for(int i=0; i<count; i++) {
lvi.iSubItem=0;
lvi.pszText=key;
WriteProcessMemory(hProcess, lvRemoteBuffer, &lvi, sizeof(LVITEM), NULL);
SendMessage(listview, LVM_GETITEMTEXT, (WPARAM)i, (LPARAM)lvRemoteBuffer);
ReadProcessMemory(hProcess, key, bytRtn, 255, NULL);
//Find the nodes
if(wcscmp(bytRtn, L"origin") == 0 || wcscmp(bytRtn, L"angle") == 0) {
//Read the value
lvi.iSubItem=1;
lvi.pszText=key;
WriteProcessMemory(hProcess, lvRemoteBuffer, &lvi, sizeof(LVITEM), NULL);
SendMessage(listview, LVM_GETITEMTEXT, (WPARAM)i, (LPARAM)lvRemoteBuffer);
ReadProcessMemory(hProcess, key, bytRtn, 255, NULL);
if(got != 0)
break;
else
wcscpy_s(gots, bytRtn);
got = wcscmp(bytRtn, L"origin") == 0 ? 1 : 2;
}
}
//How the hell am i supposed to do this?
if (wcscmp(bytRtn, gots) == 0) {
crazything(bytRtn);
wcout << "0" << endl;
} else if(got == 1) {
crazything(gots);
wcout << bytRtn << endl;
} else if(got == 2) {
crazything(bytRtn);
wcout << gots << endl;
}
}
} else {
//All doors found
if(foundDoor) {
cout << "Number of doors found: " << doorCount << endl;
break;
}
}
}
Root = (HTREEITEM)SendMessage(treeview, TVM_GETNEXTITEM, TVGN_NEXTVISIBLE, (LPARAM)Root);
}
}
VirtualFreeEx(hProcess, (LPVOID)tvRemoteBuffer, 335, MEM_RELEASE);
VirtualFreeEx(hProcess, lvRemoteBuffer, 0, MEM_RELEASE);
VirtualFreeEx(hProcess, key, 0, MEM_RELEASE);
CloseHandle(hProcess);
err("Success");
return 0;
}