Code:
#include <Windows.h>
#include <stdio.h>
#include <iostream>
#include <TlHelp32.h>
using namespace std;
int AddDebugPrivileges();
DWORD dwGetObjManager( DWORD dwPID )
{
//AddDebugPrivileges();
HANDLE hSnapShot = CreateToolhelp32Snapshot( TH32CS_SNAPTHREAD, dwPID );
THREADENTRY32 te32;
te32.dwSize = sizeof(THREADENTRY32);
if ( Thread32First( hSnapShot, &te32 ) )
{
do
{
if ( te32.th32OwnerProcessID == dwPID )
{
HANDLE hThread = OpenThread( THREAD_ALL_ACCESS, false, te32.th32ThreadID );
CONTEXT ctx = { CONTEXT_SEGMENTS };
LDT_ENTRY ldtEntry;
GetThreadContext( hThread, &ctx );
GetThreadSelectorEntry( hThread, ctx.SegFs, &ldtEntry );
DWORD dwThreadBase = ldtEntry.BaseLow|(ldtEntry.HighWord.Bytes.BaseMid<<16)|(ldtEntry.HighWord.Bytes.BaseHi<<24);
DWORD dwThreadStorage = NULL;
DWORD dwBytesRead = NULL;
DWORD dwObjManager = NULL;
CloseHandle( hThread );
AddDebugPrivileges();
HANDLE hProcess = OpenProcess( PROCESS_ALL_ACCESS, false, dwPID );
ReadProcessMemory( hProcess, (LPVOID)(dwThreadBase + 0x2C), (LPVOID)&dwThreadStorage, 4, &dwBytesRead );
ReadProcessMemory( hProcess, (LPVOID)(dwThreadStorage), (LPVOID)&dwThreadStorage, 4, &dwBytesRead );
ReadProcessMemory( hProcess, (LPVOID)(dwThreadStorage + 0x10), (LPVOID)&dwObjManager, 4, &dwBytesRead );
CloseHandle( hProcess );
return dwObjManager;
}
} while ( Thread32Next( hSnapShot, &te32 ) );
}
CloseHandle( hSnapShot );
return NULL;
}
int main( int argc, char* argv[] )
{
AddDebugPrivileges();
cout << "WoW Object Dumper (Out of Process) " << endl << "by kynox" << endl << endl;
HANDLE hSnapShot = CreateToolhelp32Snapshot( TH32CS_SNAPPROCESS, NULL );
HANDLE hProcess;
PROCESSENTRY32 pe32;
pe32.dwSize = sizeof(PROCESSENTRY32);
DWORD dwPids[10];
int iCurrentPids = 0;
DWORD dwObjMgr = 0;
if ( Process32First( hSnapShot, &pe32 ) )
{
do
{
if ( !stricmp( pe32.szExeFile, "Wow.exe" ) )
{
dwPids[iCurrentPids++] = pe32.th32ProcessID;
}
} while ( Process32Next( hSnapShot, &pe32 ) );
}
CloseHandle( hSnapShot );
if ( iCurrentPids > 1 )
{
cout << "Multiple WoW processes have been found" << endl;
for( int i = 0; i < iCurrentPids; i++ )
cout << "(" << i << ") " << dwPids[i] << endl;
int iProcessID = 0;
cout << "Select process: ";
cin >> iProcessID;
while ( (iProcessID+1 > iCurrentPids) || (iProcessID < 0) )
{
cout << "Select process: ";
cin >> iProcessID;
}
dwObjMgr = dwGetObjManager( dwPids[iProcessID] );
hProcess = OpenProcess( PROCESS_ALL_ACCESS, false, dwPids[iProcessID] );
} else {
dwObjMgr = dwGetObjManager( dwPids[0] );
}
if ( dwObjMgr == NULL )
{
cout << "Could not find ObjMgr!" << endl;
}
INT64 LocalGuid;
DWORD dwFirstObject;
DWORD dwCurObject;
DWORD dwBytesRead;
AddDebugPrivileges();
hProcess = OpenProcess( PROCESS_ALL_ACCESS, false, dwPids[0] );
ReadProcessMemory( hProcess, (LPVOID)(dwObjMgr + 0xC0), (LPVOID)&LocalGuid, 8, &dwBytesRead );
ReadProcessMemory( hProcess, (LPVOID)(dwObjMgr + 0xAC), (LPVOID)&dwFirstObject, 4, &dwBytesRead );
printf( "Local GUID: %016I64X\r\n", LocalGuid );
dwCurObject = dwFirstObject;
while ( dwCurObject && (dwCurObject&1) == 0 )
{
INT64 ObjGuid;
ReadProcessMemory( hProcess, (LPVOID)(dwCurObject + 0x30), (LPVOID)&ObjGuid, 8, &dwBytesRead );
float X, Y, Z;
ReadProcessMemory( hProcess, (LPVOID)(dwCurObject + 0xBF0), (LPVOID)&X, 4, &dwBytesRead );
ReadProcessMemory( hProcess, (LPVOID)(dwCurObject + 0xBF4), (LPVOID)&Y, 4, &dwBytesRead );
ReadProcessMemory( hProcess, (LPVOID)(dwCurObject + 0xBFC), (LPVOID)&Z, 4, &dwBytesRead );
printf( "GUID: %016I64X Location: %f %f %f\r\n", ObjGuid, X, Y, Z );
dwFirstObject = dwCurObject;
ReadProcessMemory( hProcess, (LPVOID)(dwFirstObject + 0x3C),(LPVOID)&dwCurObject, 4, &dwBytesRead );
if ( dwCurObject == dwFirstObject )
break;
}
int i;
cin >> i;
return 0;
}
//-----------------------------------------------------------
// We need to do this to gain access to read the process
int AddDebugPrivileges()
{
HANDLE hToken;
TOKEN_PRIVILEGES tp;
OpenProcessToken(GetCurrentProcess(),TOKEN_ADJUST_PRIVILEGES, &hToken);
if( !LookupPrivilegeValueA( NULL, "SeDebugPrivilege", &tp.Privileges[0].Luid ) )
{
CloseHandle(hToken);
return 1;
}
tp.PrivilegeCount = 1;
tp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
if( !AdjustTokenPrivileges( hToken, FALSE, &tp, 0, (PTOKEN_PRIVILEGES)NULL, 0) )
{
CloseHandle(hToken);
return 1;
}
CloseHandle(hToken);
return 0;
}