Rev 31 | Rev 34 | Go to most recent revision | Blame | Compare with Previous | Last modification | View Log | RSS feed
#include "pch.h"
#pragma hdrstop
#include "ConsoleClient.h"
#include <Os/W32/OsFile.h>
/****************************************************************************
*
* Client memory addresses
*
***/
#define CONSOLECOMMANDDESTROY 0x007685C0
/****************************************************************************
*
* Client symbol pointers
*
***/
void (*ConsoleCommandDestroyPtr)() = *(void(*)())CONSOLECOMMANDDESTROY;
/****************************************************************************
*
* Private
*
***/
static char s_fileName[260] = {};
//===========================================================================
void ConsoleCommandDestroy () {
// Remove the function trampoline
DETOUR_INIT;
DETOUR_DETACH(ConsoleCommandDestroyPtr,ConsoleCommandDestroy);
DETOUR_COMMIT;
// Unregister our own commands
ConsoleCommandUnregister("new");
ConsoleCommandUnregister("run");
ConsoleCommandUnregister("end");
ConsoleCommandUnregister("ver");
// Call the original function to handle clean-up
ConsoleCommandDestroyPtr();
}
//===========================================================================
BOOL ValidateFileName (char const* fileName) {
if (fileName && *fileName) {
if (strstr(fileName,"..") || strstr(fileName,"\\")) {
ConsoleWrite("File Name cannot contain '\\' or '..'",ERROR_COLOR);
return FALSE;
}
char const* fileExtension = strrchr(fileName,'.');
if (fileExtension&& *fileExtension) {
if (_strcmpi(fileExtension,".wtf")) {
ConsoleWrite("Only '.wtf' extensions are allowed",ERROR_COLOR);
return FALSE;
}
}
return TRUE;
}
return FALSE;
}
//===========================================================================
BOOL CreateWTFFilePath (char* filePath, unsigned int size) {
char buffer[FILENAME_MAX] = {};
if (filePath && *filePath && size != 0) {
SStrCopy(buffer,"WTF\\",FILENAME_MAX);
strncat_s(buffer,filePath,FILENAME_MAX);
char* extension = strrchr(filePath,'.');
if (extension && *extension) {
if (_strcmpi(extension,".wtf")) {
ConsoleWrite("File must have '.wtf' extension",ERROR_COLOR);
return FALSE;
}
}
else {
strncat_s(buffer,".wtf",FILENAME_MAX);
}
SStrCopy(filePath,buffer,FILENAME_MAX);
return TRUE;
}
return FALSE;
}
/****************************************************************************
*
* Command definitions
*
***/
//===========================================================================
BOOL ConsoleCommand_CreateExec (char const* cmd, char const* arguments) {
if (ValidateFileName(arguments)) {
char folder[FILENAME_MAX] = {};
char filePath[FILENAME_MAX] = {};
SStrCopy(s_fileName,arguments,FILENAME_MAX);
SStrCopy(filePath,s_fileName,FILENAME_MAX);
if (CreateWTFFilePath(filePath,FILENAME_MAX)) {
if (OsFileExists(filePath)) {
ConsoleWrite("File exists are you sure you want to Overwrite Y / N ? ",WARNING_COLOR);
g_ExecCreateMode = EM_PROMPTOVERWRITE;
}
else {
SStrCopy(folder,filePath,FILENAME_MAX);
char* dirName = strrchr(folder,'\\');
if (dirName)
*dirName = 0;
if (OsDirectoryExists(folder)) {
g_ExecCreateMode = EM_RECORDING;
ConsoleWrite("Begin Typing the commands",ECHO_COLOR);
}
else {
g_ExecCreateMode = EM_NOTACTIVE;
ConsoleWrite("Error! WTF folder does not exist.",ERROR_COLOR);
}
}
}
}
return FALSE;
}
//===========================================================================
BOOL ConsoleCommand_CloseExec (char const* cmd, char const* arguments) {
BOOL result = FALSE;
if (g_ExecCreateMode < EM_APPEND || g_ExecCreateMode > EM_WRITEFILE)
{
ConsoleWrite("You must type 'new' 'filename' to begin creating an Exec file",WARNING_COLOR);
result = TRUE;
}
else
{
char filePath[FILENAME_MAX] = {};
SStrCopy(filePath, s_fileName, FILENAME_MAX);
if (CreateWTFFilePath(filePath, FILENAME_MAX)) {
HANDLE hFile = OsCreateFile(filePath,FILE_ALL_ACCESS,0,CREATE_ALWAYS,FILE_ATTRIBUTE_NORMAL,(HANDLE)0x3F3F3F3F);
if (hFile == INVALID_HANDLE_VALUE)
ConsoleWrite("Error trying to create the file.",ERROR_COLOR);
else {
if (g_ExecCreateMode == EM_APPEND)
OsSetFilePointer(hFile,CREATE_ALWAYS,0i64);
DWORD count = 0;
DWORD bufLen = SStrLen(g_ExecBuffer);
COLOR_T color;
const char *str;
OsWriteFile(hFile,g_ExecBuffer,bufLen,&count);
if (count) {
color = ECHO_COLOR;
str = "File written successfully";
}
else {
color = ERROR_COLOR;
str = "Error Writing ExecFile";
}
ConsoleWrite(str,color);
OsCloseFile(hFile);
}
}
g_ExecCreateMode = EM_NOTACTIVE;
memset(g_ExecBuffer,'\0',sizeof(g_ExecBuffer));
result = TRUE;
}
return result;
}
//===========================================================================
BOOL ConsoleCommand_RunExec (char const* command, char const* arguments) {
BOOL result = FALSE;
char filename[FILENAME_MAX] = { '\0' };
char tmp[FILENAME_MAX] = { '\0' };
char lineBuffer[128] = { '\0' };
char param1[32] = { '\0' };
DWORD bytes;
int verbose = 0;
if (sscanf_s(arguments, "%260s %32s", filename, sizeof(filename), param1, sizeof(param1)) != 0) {
if (!_strcmpi(param1, "verbose"))
verbose = 1;
result = CreateWTFFilePath(filename, 260u);
if (result) {
HANDLE hFile = OsCreateFile(filename, GENERIC_READ, 0, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
DWORD fileSize = GetFileSize(hFile, NULL);
char* readData = (char *)calloc(1, fileSize+1);
if (!readData) {
ConsoleWriteA("ConsoleCommand_RunExec, Line %d: call to calloc() failed", ERROR_COLOR, __LINE__);
return FALSE;
}
if (OsReadFile(hFile, readData, fileSize, &bytes)) {
char* bufferPtr = (char *)calloc(1, bytes+1);
if (!bufferPtr) {
ConsoleWriteA("ConsoleCommand_RunExec, Line %d: call to calloc() failed", ERROR_COLOR, __LINE__);
return FALSE;
}
memcpy((void*)bufferPtr, readData, bytes);
if (bufferPtr) {
char* token = 0;
char* nextToken = 0;
token = strtok_s(bufferPtr, "\r\n", &nextToken);
if (token) {
do {
SStrCopy(lineBuffer, token, 128u);
if (lineBuffer[0]) {
if (verbose) {
_snprintf(tmp, FILENAME_MAX, "Executing ->%s", lineBuffer);
ConsoleWrite(tmp, ECHO_COLOR);
}
ConsoleCommandExecute(lineBuffer, 0);
}
token = strtok_s(NULL, "\r\n", &nextToken);
} while (token && *token);
}
else
result = FALSE;
free((void*)bufferPtr);
}
else
result = FALSE;
}
else {
if (*command)
_snprintf(tmp, FILENAME_MAX, "Unable to load file %s", filename);
else
_snprintf(tmp, FILENAME_MAX, "Unknown command: %s", arguments);
ConsoleWrite(tmp, ERROR_COLOR);
result = FALSE;
}
OsCloseFile(hFile);
free(readData);
}
}
else {
ConsoleWrite("Invalid number of parameters", ERROR_COLOR);
ConsoleCommandWriteHelp(command);
}
return result;
}
//===========================================================================
BOOL ConsoleCommand_Ver (LPCSTR command, LPCSTR args) {
#ifdef NDEBUG
ConsoleWriteA("WoW [Release] Build 12340 (%s)", DEFAULT_COLOR, __DATE__);
#else
ConsoleWriteA("WoW [Debug] Build 12340 (%s)", DEFAULT_COLOR, __DATE__);
#endif
return TRUE;
}
/****************************************************************************
*
* External
*
***/
//===========================================================================
void ConsoleCommandInitialize () {
DETOUR_INIT;
DETOUR_ATTACH(ConsoleCommandDestroyPtr,ConsoleCommandDestroy);
DETOUR_COMMIT;
ConsoleCommandUnregister("ver");
ConsoleCommandRegister("ver",ConsoleCommand_Ver,DEFAULT,NOHELP);
ConsoleCommandRegister("new",ConsoleCommand_CreateExec,CONSOLE,"[File Name] starts recording a new script");
ConsoleCommandRegister("run",ConsoleCommand_RunExec,CONSOLE,"[File Name] Runs a wtf file from the WTF folder");
ConsoleCommandRegister("end",ConsoleCommand_CloseExec,CONSOLE,"Stops recording script");
}