T2-CPP/Mod Sources/Watchdog/Watchdog/source/dllmain.cpp
Calvin Balke 81a28fe3ba Added new Move Code
Added Move Code, TS callback, and commands to interface with Move code.
2015-07-06 10:01:22 -07:00

197 lines
6.1 KiB
C++

// dllmain.cpp : Defines the entry point for the DLL application.
#include <SDKDDKVer.h>
#include <Windows.h>
#include <time.h>
#include <stdio.h>
#include <conio.h>
#include <LinkerAPI.h>
// #define LONGHAMBURGERROUTINE
BOOL APIENTRY DllMain( HMODULE hModule,
DWORD ul_reason_for_call,
LPVOID lpReserved
)
{
switch (ul_reason_for_call)
{
case DLL_PROCESS_ATTACH:
case DLL_THREAD_ATTACH:
case DLL_THREAD_DETACH:
case DLL_PROCESS_DETACH:
break;
}
return TRUE;
}
static bool sDogPetted = false;
static DWORD mainthreadid=0;
static bool evaldone=1;
void overrideputhex(unsigned char hex) {
char hexstr[40]="";
char outchar=' ';
int counter=0;
sprintf (hexstr,"%02X",hex);
while (hexstr[counter] != 0x0) {
_putch(hexstr[counter]);
counter++;
}
}
void overridegets(char * string) {
int counter=0;
char outstr[3]="";
while (1) {
if (_kbhit()) {
string[counter]=_getch();
_putch(string[counter]);
if (string[counter]=='\n' || string[counter]=='\r') {
string[counter]=0x0;
break;
} else {
counter++;
}
} else {
Sleep(4);
}
}
}
DWORD WINAPI WatchDogEvalThread(LPVOID lpParam)
{
Con::evaluate((char *) lpParam,true,0,0);
Con::printf ("Finished executing\n");
evaldone=1;
return 0;
}
DWORD WINAPI WatchDogThread(LPVOID lpParam)
{
time_t lastPet = time(0);
CONTEXT hamburger;
HANDLE mainThread = OpenThread(THREAD_ALL_ACCESS,false,mainthreadid);
char inputchar=0;
char evalcode[5000]="";
while (true)
{
time_t now = time(0);
double seconds = difftime(now,lastPet);
#ifdef SLOWSERVER
if (!sDogPetted && seconds > 15) // Wait 15 seconds to be extra safe
#else
if (!sDogPetted && seconds > 8) // Wait 8 seconds to be safe
#endif
{
SuspendThread(mainThread);
hamburger.ContextFlags=CONTEXT_FULL; // Make sure to select which parts of the context to dump
GetThreadContext(mainThread, &hamburger); // dog grabs hamburger;
Con::printf ("Dog has grabbed the hamburger again\n");
Con::printf ("Either grab Hamburger back and put dog back on leash, or let dog eat hamburger\n");
Con::printf ("the following text is from the Processor State\n");
FILE * wlog = fopen ("watchdog.log","a");
fprintf (wlog,"EIP: %08X EAX: %08X EBX: %08X ECX: %08X \nEDX: %08X ESI: %08X EDI: %08X\nEBP:%08X ESP:%08X\n", hamburger.Eip, hamburger.Eax, hamburger.Ebx, hamburger.Ecx, hamburger.Edx, hamburger.Esi, hamburger.Edi, hamburger.Ebp, hamburger.Esp);
fclose (wlog);
Con::printf ("EIP: %08X EAX: %08X EBX: %08X ECX: %08X \nEDX: %08X ESI: %08X EDI: %08X\nEBP:%08X ESP:%08X\n", hamburger.Eip, hamburger.Eax, hamburger.Ebx, hamburger.Ecx, hamburger.Edx, hamburger.Esi, hamburger.Edi, hamburger.Ebp, hamburger.Esp);
Con::printf ("Please press enter to try to continue, press e to get a torquescript shell, press d to get a hexdump of the last bit of torquescript bytecode to search for in DSO files, or wait for 30 more seconds to kill T2 and write log\n");
#ifdef LONGHAMBURGERROUTINE
for (int secondcounter=0;secondcounter<120;secondcounter++) {
#else
for (int secondcounter=0;secondcounter<8;secondcounter++) {
#endif
Sleep(250);
if (_kbhit()) {
sDogPetted=true;
inputchar=_getch(); // make sure to clean the keyboard buffer
if (inputchar=='e') {
Con::printf ("Torque script shell activated enter the code to evaluate on the next line to exit, just type exitshell and press enter\n");
while (true) {
overridegets(evalcode);
if (strcmp(evalcode,"exitshell")==0) {
break;
}
DWORD threadID=0;
evaldone=0;
HANDLE thread = CreateThread(NULL, 0, WatchDogEvalThread, evalcode, 0, &threadID);
while (!evaldone) {
Sleep(256);
}
CloseHandle(thread);
}
} else if (inputchar=='d') {
DWORD codeOffset=*(DWORD *)(0xa3b714);
DWORD codeBase=*(DWORD *)(0xa3b710);
if (codeBase!=0) {
unsigned char *basecodeptr=(unsigned char *)((codeBase+(codeOffset*4)));
Con::printf ("CodeOffset: %08X CodeAddr: %08X (Codeoffset-128 to CodeOffset+512 is on the next line)\n",codeOffset, (codeBase+(codeOffset*4)));
for (int codeOffsetCounter=-128; codeOffsetCounter<512; codeOffsetCounter++) {
overrideputhex(*(basecodeptr+codeOffsetCounter));
_putch(' ');
}
_putch('\n');
_putch('\r');
Con::printf("Search for those hex bytes in a binary search utility to find the DSO file with the last executed opcodes\n");
} else {
Con::printf ("you forgot to run this command: memPatch(\"42CED1\",getInterAddr());\n");
}
}
ResumeThread(mainThread);
break;
}
}
if (!sDogPetted) {
CloseHandle(mainThread);
exit(0);
}
}
else if (sDogPetted)
{
sDogPetted = false;
lastPet = now;
}
Sleep(500);
}
}
extern "C"
{
__declspec(dllexport) void ModInitialize(void)
{
DWORD *codeOffset=(DWORD *)(0xa3b714);
DWORD *codeBase=(DWORD *)(0xa3b710);
*codeOffset=0x0;
*codeBase=0x0;
mainthreadid = GetThreadId(GetCurrentThread());
SECURITY_DESCRIPTOR secDescVar;
DWORD threadID;
HANDLE token;
LUID debugname;
TOKEN_PRIVILEGES tokenpriv;
HANDLE thread = CreateThread(NULL, 0, WatchDogThread, NULL, 0, &threadID);
if (thread==NULL) {
DWORD errorval = GetLastError();
Con::printf ("Error %08X, watchdog is not running properly\n",errorval);
}
OpenProcessToken(GetCurrentProcess(),TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY,&token);
LookupPrivilegeValue(NULL,SE_DEBUG_NAME, &debugname);
tokenpriv.PrivilegeCount = 1;
tokenpriv.Privileges[0].Luid = debugname;
tokenpriv.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
if(AdjustTokenPrivileges(token, FALSE, &tokenpriv, sizeof tokenpriv, NULL, NULL)) {
Con::printf ("watchdog should work now\n");
CloseHandle(token);
} else {
Con::printf ("Error, watchdog won't operate fully, WatchDog needs Admin Privileges for Debug\n");
}
}
__declspec(dllexport) void ServerProcess(unsigned int deltaTime)
{
sDogPetted = true;
}
}