Code:
DWORD WINAPI runFunction(LPVOID lParam) {
unsigned int ObjMngr = 0;
// Correct TLS with proper ObjectManager ptr
__asm {
mov EDX, 0x012705B0
mov EDX, [EDX]
mov EDX, [EDX+0x2D94]
mov ObjMngr, EDX
mov EAX, FS:[0x2C]
mov EAX, [EAX] ; EAX = TLS[0]
mov [EAX+8], EDX ; replacing TLS[2] pointer with pointer to ObjMngr
}
// Get our GUID
DWORD guidLOW, guidHIGH;
__asm {
mov edx, 0x00476580
call edx
mov guidLOW, eax
mov guidHIGH, edx
}
// Alternative way to get GUID without asm code
/*
typedef unsigned long long (*fptr_t)(void);
fptr_t GetPlayerGuid = (fptr_t)0x00476580;
unsigned long long playerGuid = GetPlayerGuid();
*/
// Get Player pointer
DWORD playerPtr = 0;
DWORD playerVFTable = 0;
__asm {
push 0xA1
push 0x00
push 0x10
push guidHIGH
push guidLOW
mov EDX, 0x00477B50
call EDX
mov playerPtr, EAX
mov EAX, [EAX]
mov playerVFTable, EAX
add esp, 0x14
}
FILE * file = fopen("C:\\Users\\Public\\test.txt", "w");
fprintf(file, "ObjMngr Addr: 0x%08x\n", ObjMngr);
fprintf(file, "GUID: 0x%08x%08x\n", guidHIGH, guidLOW);
//fprintf(file, "GUID: 0x%016llx\n", playerGuid);
fprintf(file, "Ptr : 0x%08x\n", playerPtr);
fprintf(file, "pVFT: 0x%08x\n", playerVFTable);
// List VFTable addresses
DWORD VFTable[53];
for( unsigned short i = 0; i < 53; i++ ) {
DWORD addr = 0;
DWORD index = playerVFTable + 4*i;
__asm {
mov EDX, index
mov EDX, [EDX]
mov addr, EDX
}
VFTable[i] = addr;
fprintf(file, "\t[%02d] - 0x%08x\n", i, addr);
}
fprintf(file, "\n");
// Get our Position
float pos[3] = {0.0};
DWORD pos_addr = (DWORD)&pos[0];
DWORD index = VFTable[11];
// test this by getting 10 points
for( unsigned int i = 0; i < 10; i++ ) {
__asm {
mov EDX, index
push pos_addr
mov ECX, playerPtr
call EDX
add esp, 4
}
fprintf(file, "Position: %04.2f, %04.2f, %03.2f\n", pos[0], pos[1], pos[2]);
char gStr[128];
_snprintf_s(gStr, 128, 128, "Position: %04.2f, %04.2f, %03.2f\n", pos[0], pos[1], pos[2]);
MessageBox(0, gStr, "Info", 0);
}
// Flush and Close our file
fflush(file);
fclose(file);
// Check Stuff
ExitThread(0);
}
To Remember: When using VFtables you need to set ECX to be the pointer to the class of the object you want to call the VFTable function for. That led me to a few crashes before I had a "duh" moment.