This commit is contained in:
Robert MacGregor 2015-06-29 18:48:03 -04:00
commit 758d4243bd
2 changed files with 118 additions and 19 deletions

View file

@ -4,9 +4,10 @@
#include <time.h> #include <time.h>
#include <stdio.h> #include <stdio.h>
#include <conio.h> #include <conio.h>
#include <LinkerAPI.h> #include <LinkerAPI.h>
// #define LONGHAMBURGERROUTINE
BOOL APIENTRY DllMain( HMODULE hModule, BOOL APIENTRY DllMain( HMODULE hModule,
DWORD ul_reason_for_call, DWORD ul_reason_for_call,
LPVOID lpReserved LPVOID lpReserved
@ -25,11 +26,49 @@ BOOL APIENTRY DllMain( HMODULE hModule,
static bool sDogPetted = false; static bool sDogPetted = false;
static DWORD mainthreadid=0; 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) DWORD WINAPI WatchDogThread(LPVOID lpParam)
{ {
time_t lastPet = time(0); time_t lastPet = time(0);
CONTEXT hamburger; CONTEXT hamburger;
HANDLE mainThread = OpenThread(THREAD_ALL_ACCESS,false,mainthreadid); HANDLE mainThread = OpenThread(THREAD_ALL_ACCESS,false,mainthreadid);
char inputchar=0;
char evalcode[5000]="";
while (true) while (true)
{ {
time_t now = time(0); time_t now = time(0);
@ -50,13 +89,57 @@ DWORD WINAPI WatchDogThread(LPVOID lpParam)
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); 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); 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 ("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\n or wait for 30 more seconds to kill T2 and write log\n"); 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");
Sleep(30000); #ifdef LONGHAMBURGERROUTINE
if (_kbhit()) { for (int secondcounter=0;secondcounter<120;secondcounter++) {
sDogPetted=true; #else
_getch(); // make sure to clean the keyboard buffer for (int secondcounter=0;secondcounter<8;secondcounter++) {
ResumeThread(mainThread); #endif
} else { 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); CloseHandle(mainThread);
exit(0); exit(0);
} }
@ -74,6 +157,10 @@ extern "C"
{ {
__declspec(dllexport) void ModInitialize(void) __declspec(dllexport) void ModInitialize(void)
{ {
DWORD *codeOffset=(DWORD *)(0xa3b714);
DWORD *codeBase=(DWORD *)(0xa3b710);
*codeOffset=0x0;
*codeBase=0x0;
mainthreadid = GetThreadId(GetCurrentThread()); mainthreadid = GetThreadId(GetCurrentThread());
SECURITY_DESCRIPTOR secDescVar; SECURITY_DESCRIPTOR secDescVar;
DWORD threadID; DWORD threadID;

View file

@ -20,22 +20,30 @@ BOOL APIENTRY DllMain( HMODULE hModule,
{ {
return true; return true;
} }
const unsigned char moduroutine[] = {0x8B, 0x3D, 0xEC, 0x82, 0x9E, 0x00, 0x89, 0xF8, 0x8B, 0x14, 0x85, 0xFC, 0xA5, 0x88, 0x00, 0x83, 0xFA, 0x00, 0x74, 0x30, 0x8B, 0x3D, 0xEC, 0x82, 0x9E, 0x00, 0x89, 0xF8, 0x31, 0xD2, 0x89, 0xF8, 0x8B, 0x04, 0x85, 0x00, 0xA6, 0x88, 0x00, 0xF7, 0x34, 0xBD, 0xFC, 0xA5, 0x88, 0x00, 0xFF, 0x0D, 0xEC, 0x82, 0x9E, 0x00, 0x89, 0xF8, 0x89, 0x14, 0x85, 0xFC, 0xA5, 0x88, 0x00, 0xB8, 0xC7, 0xCE, 0x42, 0x00, 0xFF, 0xE0, 0xFF, 0x0D, 0xEC, 0x82, 0x9E, 0x00, 0xC7, 0x04, 0x85, 0xFC, 0xA5, 0x88, 0x00, 0x00, 0x00, 0x00, 0x00, 0xB8, 0xC7, 0xCE, 0x42, 0x00, 0xFF, 0xE0};
const unsigned char interpreterRoutine[] = {0x8B ,0x56 ,0x18 ,0x89 ,0x15 ,0x10 ,0xB7 ,0xA3 ,0x00 ,0x89 ,0x1D ,0x14 ,0xB7 ,0xA3 ,0x00 ,0x8B ,0x55 ,0x80 ,0x89 ,0xD0 ,0xBF ,0xD9 ,0xCE ,0x42 ,0x00 ,0x3D ,0x55 ,0x00 ,0x00 ,0x00 ,0xFF ,0xE7};
const char* congetServPAddr(Linker::SimObject *obj, S32 argc, const char *argv[]) const char* congetServPAddr(Linker::SimObject *obj, S32 argc, const char *argv[])
{ {
char test[256] = ""; char test[256] = "";
char test2[256]=""; char test2[256]="";
int spr=(signed int)*serverProcessReplacement; int spr=(signed int)*serverProcessReplacement;
sprintf(test2,"B8%08XFFD089EC5DC3",endian(spr)); sprintf(test2,"B8%08XFFD089EC5DC3",endian(spr));
/*test2[0]=test[6]; return test2;
test2[1]=test[7]; }
test2[2]=test[4]; const char* congetModuAddr(Linker::SimObject *obj, S32 argc, const char *argv[])
test2[3]=test[5]; {
test2[4]=test[2]; char test[256] = "";
test2[5]=test[3]; char test2[256]="";
test2[6]=test[0]; int spr=(signed int)moduroutine;
test2[7]=test[1]; sprintf(test2,"B8%08XFFE0",endian(spr));
test2[8]=0;*/ return test2;
}
const char* congetInterpreterAddr(Linker::SimObject *obj, S32 argc, const char *argv[])
{
char test[256] = "";
char test2[256]="";
int spr=(signed int)interpreterRoutine;
sprintf(test2,"B8%08XFFE0",endian(spr));
return test2; return test2;
} }
@ -54,10 +62,14 @@ class CImmDevice
{ {
Con::addVariable("$cpuspeed",TypeS32,reinterpret_cast<void*>(0x8477F8)); //1 - S32, this is so i can set my cpu speed to 31337 or osmething =P Con::addVariable("$cpuspeed",TypeS32,reinterpret_cast<void*>(0x8477F8)); //1 - S32, this is so i can set my cpu speed to 31337 or osmething =P
Con::addVariable("$GameBase::showBoundingBox",TypeBool,reinterpret_cast<void*>(0x9ECF24)); Con::addVariable("$GameBase::showBoundingBox",TypeBool,reinterpret_cast<void*>(0x9ECF24));
DWORD oldprotect=0;
// Mod Loader Function // Mod Loader Function
Con::addMethodB(NULL, "loadMod", &conLoadMod, "Loads a C++ modification.",2,2); Con::addMethodB(NULL, "loadMod", &conLoadMod, "Loads a C++ modification.",2,2);
Con::addMethodS(NULL, "getServPAddr",&congetServPAddr,"Gets the memPatch data for ServerProcess",1,1); Con::addMethodS(NULL, "getServPAddr",&congetServPAddr,"Gets the memPatch data for ServerProcess",1,1);
VirtualProtect( (LPVOID)moduroutine,sizeof(moduroutine),PAGE_EXECUTE_READWRITE,&oldprotect);
VirtualProtect( (LPVOID)interpreterRoutine,sizeof(interpreterRoutine),PAGE_EXECUTE_READWRITE,&oldprotect);
Con::addMethodS(NULL, "getModuAddr",&congetModuAddr,"Gets the memPatch data for the MODULO operator routine",1,1); // memPatch("42D89D",getModuAddr());
Con::addMethodS(NULL, "getInterAddr", &congetInterpreterAddr, "Gets the memPatch data for the interpreter switchtable",1,1); // memPatch("42CED1",getInterAddr());
// Load the original TribesNext DLL if available // Load the original TribesNext DLL if available
typedef void (*LPINITT2DLL)(void); typedef void (*LPINITT2DLL)(void);