* Moved snowcrash to the applications directory * Removed the Release folder from SLIRC git-svn-id: http://libopenmetaverse.googlecode.com/svn/trunk@133 52acb1d6-8a22-11de-b505-999d5b087335
2965 lines
75 KiB
C++
2965 lines
75 KiB
C++
// snowflake.cpp : Defines the entry point for the DLL application.
|
|
//
|
|
|
|
#include "stdafx.h"
|
|
#include ".\snowflake.h"
|
|
#include ".\MainFrame.h"
|
|
#include ".\Server.h"
|
|
#include ".\ServerList.h"
|
|
#include ".\Message.h"
|
|
#include ".\Block.h"
|
|
#include ".\Var.h"
|
|
#include ".\Config.h"
|
|
#include <tlhelp32.h>
|
|
#include <wininet.h>
|
|
#include <wincrypt.h>
|
|
#include <gl/gl.h>
|
|
#include <gl/glu.h>
|
|
#include <math.h>
|
|
#include <winuser.h>
|
|
#include <time.h>
|
|
#include ".\keywords.h"
|
|
|
|
#pragma pack(1)
|
|
|
|
struct COMMANDVAR
|
|
{
|
|
char *lpszVar;
|
|
int nKeywordPos;
|
|
int nType;
|
|
int nTypeLen;
|
|
struct COMMANDVAR *lpNext;
|
|
struct COMMANDVAR *lpPrev;
|
|
} typedef COMMANDVARS;
|
|
|
|
typedef COMMANDVAR * LPCOMMANDVAR;
|
|
typedef COMMANDVARS * LPCOMMANDVARS;
|
|
|
|
struct COMMANDSTRUCT
|
|
{
|
|
char *lpszStruct;
|
|
int nKeywordPos;
|
|
int nType;
|
|
BYTE cItems;
|
|
LPCOMMANDVARS vars;
|
|
struct COMMANDSTRUCT *lpNext;
|
|
struct COMMANDSTRUCT *lpPrev;
|
|
} typedef COMMANDSTRUCTS;
|
|
|
|
typedef COMMANDSTRUCT * LPCOMMANDSTRUCT;
|
|
typedef COMMANDSTRUCTS * LPCOMMANDSTRUCTS;
|
|
|
|
typedef struct
|
|
{
|
|
char *lpszCmd;
|
|
bool bZerocoded;
|
|
bool bTrusted;
|
|
LPCOMMANDSTRUCTS structs;
|
|
} COMMAND;
|
|
|
|
typedef COMMAND * LPCOMMAND;
|
|
|
|
#define MAX_COMMANDS_LOW 65536
|
|
#define MAX_COMMANDS_MEDIUM 256
|
|
#define MAX_COMMANDS_HIGH 256
|
|
|
|
COMMAND cmds_low[MAX_COMMANDS_LOW];
|
|
COMMAND cmds_med[MAX_COMMANDS_MEDIUM];
|
|
COMMAND cmds_high[MAX_COMMANDS_HIGH];
|
|
|
|
typedef struct
|
|
{
|
|
LPCTSTR szCommand;
|
|
PROC pProc;
|
|
} CMDHOOK, *LPCMDHOOK;
|
|
|
|
CMDHOOK pCMDHooks[];
|
|
|
|
#pragma data_seg(".shared")
|
|
HHOOK h_hCBTHook = NULL;
|
|
#pragma data_seg()
|
|
#pragma comment(linker, "/SECTION:.shared,RWS")
|
|
|
|
HINSTANCE g_hinstDLL = NULL;
|
|
HMODULE g_hOpenGL = NULL;
|
|
CMainFrame* g_pMainFrm = NULL;
|
|
CAppModule _Module;
|
|
CMessageLoop g_msgLoop;
|
|
CConfig* g_pConfig = NULL;
|
|
BOOL g_bAllowSub = TRUE;
|
|
|
|
CServerList servers;
|
|
|
|
typedef struct
|
|
{
|
|
LPCTSTR szPatch;
|
|
LPCTSTR szModule;
|
|
LPCSTR szImport;
|
|
BOOL bOrdinal;
|
|
PROC pOldProc;
|
|
PROC pNewProc;
|
|
} APIHOOK, *LPAPIHOOK;
|
|
|
|
APIHOOK pAPIHooks[];
|
|
|
|
#define MAKEPTR(cast, ptr, add) (cast)((DWORD)(ptr)+(DWORD)(add))
|
|
|
|
enum APIHOOKS
|
|
{
|
|
APIHOOK_GETPROCADDRESS,
|
|
APIHOOK_LOADLIBRARYA,
|
|
APIHOOK_LOADLIBRARYW,
|
|
APIHOOK_LOADLIBRARYEXA,
|
|
APIHOOK_LOADLIBRARYEXW,
|
|
APIHOOK_FREELIBRARYA,
|
|
APIHOOK_DELETEFILEA,
|
|
APIHOOK_WRITEFILEA,
|
|
APIHOOK_LSTRCMPIA,
|
|
APIHOOK_CONNECT,
|
|
APIHOOK_RECV,
|
|
APIHOOK_RECVFROM,
|
|
APIHOOK_SEND,
|
|
APIHOOK_SENDTO,
|
|
APIHOOK_GETHOSTBYNAME,
|
|
// APIHOOK_SETWINDOWLONGA,
|
|
// APIHOOK_SETWINDOWLONGW,
|
|
APIHOOK_INTERNETREADFILE,
|
|
APIHOOK_INTERNETOPENURLA,
|
|
APIHOOK_CPENCRYPT,
|
|
APIHOOK_PEEKMESSAGEA,
|
|
APIHOOK_GLGETERROR,
|
|
APIHOOK_GLBEGIN,
|
|
APIHOOK_GLENABLE,
|
|
APIHOOK_GLISENABLED,
|
|
APIHOOK_GLTRANSLATED,
|
|
APIHOOK_GLTRANSLATEF,
|
|
APIHOOK_GLTEXCOORD2F,
|
|
APIHOOK_GLTEXCOORD2FV,
|
|
APIHOOK_GLVERTEX2F,
|
|
APIHOOK_GLVERTEX3F,
|
|
APIHOOK_GLVERTEX3FV,
|
|
APIHOOK_GLVERTEX4F,
|
|
APIHOOK_GLVERTEX4FV,
|
|
APIHOOK_GLVERTEXPOINTER,
|
|
APIHOOK_GLTEXCOORDPOINTER,
|
|
APIHOOK_GLNORMALPOINTER,
|
|
APIHOOK_GLDRAWELEMENTS,
|
|
APIHOOK_GLDRAWARRAYS,
|
|
APIHOOK_GLDRAWPIXELS,
|
|
APIHOOK_GLTEXIMAGE2D,
|
|
APIHOOK_GLCOLOR3F,
|
|
APIHOOK_GLCOLOR3FV,
|
|
APIHOOK_GLCOLOR4F,
|
|
APIHOOK_GLCOLOR4FV,
|
|
APIHOOK_GLCOLOR4UBV,
|
|
APIHOOK_GLCOLORPOINTER,
|
|
APIHOOK_GLVIEWPORT,
|
|
APIHOOK_GLFLUSH,
|
|
APIHOOK_GLUPERSPECTIVE,
|
|
APIHOOK_GLUQUADRICDRAWSTYLE,
|
|
APIHOOK_GLUTESSVERTEX,
|
|
APIHOOK_NULL
|
|
};
|
|
|
|
bool InstallSLHooks(HWND hwnd);
|
|
bool RemoveSLHooks();
|
|
void InstallImportHooks();
|
|
void RemoveImportHooks();
|
|
void SaveImportHooks();
|
|
|
|
int ZeroDecode(char *src, int srclen, char *dest, int destlen)
|
|
{
|
|
int zerolen = 0;
|
|
|
|
if (src[0] & MSG_ZEROCODED)
|
|
{
|
|
memcpy(dest, src, 4);
|
|
zerolen += 4;
|
|
|
|
for (int i = zerolen; i < srclen; i++)
|
|
{
|
|
if ((unsigned char)src[i] == 0x00)
|
|
{
|
|
for (unsigned char j = 0; j < (unsigned char)src[i+1]; j++)
|
|
dest[zerolen++] = 0x00;
|
|
|
|
i++;
|
|
}
|
|
else
|
|
dest[zerolen++] = src[i];
|
|
}
|
|
}
|
|
else
|
|
{
|
|
memcpy(dest, src, srclen);
|
|
zerolen = srclen;
|
|
}
|
|
|
|
return zerolen;
|
|
}
|
|
|
|
int ZeroEncode(char *src, int srclen, char *dest, int destlen)
|
|
{
|
|
int zerolen = 0;
|
|
unsigned char zerocount = 0;
|
|
|
|
if (src[0] & MSG_ZEROCODED)
|
|
{
|
|
memcpy(dest, src, 4);
|
|
zerolen += 4;
|
|
|
|
for (int i = zerolen; i < srclen; i++)
|
|
{
|
|
if ((unsigned char)src[i] == 0x00)
|
|
{
|
|
zerocount++;
|
|
|
|
if (zerocount == 0)
|
|
{
|
|
dest[zerolen++] = 0x00;
|
|
dest[zerolen++] = 0xff;
|
|
zerocount++;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
if (zerocount)
|
|
{
|
|
dest[zerolen++] = 0x00;
|
|
dest[zerolen++] = zerocount;
|
|
zerocount = 0;
|
|
}
|
|
|
|
dest[zerolen++] = src[i];
|
|
}
|
|
}
|
|
|
|
if (zerocount)
|
|
{
|
|
dest[zerolen++] = 0x00;
|
|
dest[zerolen++] = zerocount;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
memcpy(dest, src, srclen);
|
|
zerolen = srclen;
|
|
}
|
|
|
|
return zerolen;
|
|
}
|
|
|
|
// Convert a "hex string" to an integer by Anders Molin
|
|
int httoi(const TCHAR *value)
|
|
{
|
|
struct HEXMAP
|
|
{
|
|
TCHAR c;
|
|
int value;
|
|
};
|
|
|
|
const int nHexMap = 16;
|
|
|
|
HEXMAP hmLookup[nHexMap] =
|
|
{
|
|
{'0', 0}, {'1', 1},
|
|
{'2', 2}, {'3', 3},
|
|
{'4', 4}, {'5', 5},
|
|
{'6', 6}, {'7', 7},
|
|
{'8', 8}, {'9', 9},
|
|
{'A', 10}, {'B', 11},
|
|
{'C', 12}, {'D', 13},
|
|
{'E', 14}, {'F', 15}
|
|
};
|
|
|
|
TCHAR *mstr = _tcsupr(_tcsdup(value));
|
|
TCHAR *s = mstr;
|
|
int result = 0;
|
|
|
|
if (*s == '0' && *(s + 1) == 'X')
|
|
s += 2;
|
|
|
|
bool firsttime = true;
|
|
|
|
while (*s != '\0')
|
|
{
|
|
bool found = false;
|
|
|
|
for (int i = 0; i < nHexMap; i++)
|
|
{
|
|
if (*s == hmLookup[i].c)
|
|
{
|
|
if (!firsttime)
|
|
result <<= 4;
|
|
|
|
result |= hmLookup[i].value;
|
|
found = true;
|
|
break;
|
|
}
|
|
}
|
|
|
|
if (!found)
|
|
break;
|
|
|
|
s++;
|
|
firsttime = false;
|
|
}
|
|
|
|
free(mstr);
|
|
|
|
return result;
|
|
}
|
|
|
|
// Trim beginning, ending, and excess embedded whitespace from a string
|
|
char *trim(char *szStr)
|
|
{
|
|
char *iBuf, *oBuf;
|
|
|
|
if (szStr)
|
|
{
|
|
for (iBuf = oBuf = szStr; *iBuf;)
|
|
{
|
|
while (*iBuf && (isspace(*iBuf)))
|
|
iBuf++;
|
|
|
|
if (*iBuf && (oBuf != szStr))
|
|
*(oBuf++) = ' ';
|
|
|
|
while (*iBuf && (!isspace(*iBuf)))
|
|
*(oBuf++) = *(iBuf++);
|
|
}
|
|
|
|
*oBuf = NULL;
|
|
}
|
|
|
|
return(szStr);
|
|
}
|
|
|
|
int get_var_type(TCHAR *lptszType)
|
|
{
|
|
int i = 0;
|
|
|
|
while (LLTYPES[i])
|
|
{
|
|
if (!_tcscmp(lptszType, LLTYPES[i]))
|
|
{
|
|
//printf("Type: %s\n", LLTYPES[i]);
|
|
return i;
|
|
}
|
|
|
|
i++;
|
|
}
|
|
|
|
return -1;
|
|
}
|
|
|
|
int get_keyword_pos(TCHAR *lptszKeyword)
|
|
{
|
|
int i = 0;
|
|
|
|
while (LLKEYWORDS[i])
|
|
{
|
|
if (!_tcscmp(lptszKeyword, LLKEYWORDS[i]))
|
|
{
|
|
//printf("Keyword: %s\n", LLKEYWORDS[i]);
|
|
return i;
|
|
}
|
|
|
|
i++;
|
|
}
|
|
|
|
dprintf("Unhandled keyword: %s\n", lptszKeyword);
|
|
return -1;
|
|
}
|
|
|
|
// Get message template block deliminator positions
|
|
bool get_block_markers(LPBYTE lpBuffer, DWORD &dwStart, DWORD &dwEnd, DWORD &dwChildren)
|
|
{
|
|
DWORD dwStartBlock = 0;
|
|
DWORD dwEndBlock = 0;
|
|
DWORD dwDepth = 0;
|
|
|
|
dwChildren = 0;
|
|
|
|
for (DWORD dwPos = dwStart; dwPos <= dwEnd; dwPos++)
|
|
{
|
|
if (lpBuffer[dwPos] == '{')
|
|
{
|
|
dwDepth++;
|
|
|
|
if (dwDepth == 1)
|
|
dwStartBlock = dwPos;
|
|
else if (dwDepth == 2 && !dwChildren)
|
|
dwChildren = dwPos;
|
|
}
|
|
|
|
else if (lpBuffer[dwPos] == '}')
|
|
{
|
|
dwDepth--;
|
|
|
|
if (dwDepth == 0 && dwStartBlock)
|
|
{
|
|
dwEndBlock = dwPos;
|
|
dwStart = dwStartBlock;
|
|
dwEnd = dwEndBlock;
|
|
return true;
|
|
}
|
|
}
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
// Parse the variables message template block of a struct
|
|
bool get_var_blocks(LPCOMMANDSTRUCT lpStruct, LPBYTE lpBuffer, DWORD dwStart, DWORD dwEnd)
|
|
{
|
|
DWORD dwVarStart = dwStart;
|
|
DWORD dwVarEnd = dwEnd;
|
|
DWORD dwVarChildren = 0;
|
|
|
|
while (get_block_markers(lpBuffer, dwVarStart, dwVarEnd, dwVarChildren))
|
|
{
|
|
char szVarLine[256];
|
|
DWORD dwVarLen = (dwVarChildren ? dwVarChildren - 1 : dwVarEnd - 1) - dwVarStart;
|
|
|
|
memcpy(&szVarLine, &lpBuffer[dwVarStart+1], dwVarLen);
|
|
szVarLine[dwVarLen] = '\0';
|
|
trim(szVarLine);
|
|
|
|
//printf("\t\t%s\n", szVarLine);
|
|
|
|
char *lpszVar = strtok(szVarLine, " ");
|
|
char *lpszType = strtok(NULL, " ");
|
|
char *lpszTypeLen = NULL;
|
|
int nKeywordPos = get_keyword_pos(lpszVar);
|
|
int nVarType = get_var_type(lpszType);
|
|
|
|
LPCOMMANDVAR lpVar = lpStruct->vars;
|
|
|
|
if (lpVar)
|
|
{
|
|
// Insert after an item
|
|
if (nKeywordPos > lpVar->nKeywordPos)
|
|
{
|
|
while (lpVar->lpNext && nKeywordPos > lpVar->lpNext->nKeywordPos)
|
|
lpVar = lpVar->lpNext;
|
|
|
|
LPCOMMANDVAR lpBelow = lpVar->lpNext;
|
|
|
|
lpVar->lpNext = (LPCOMMANDVAR)malloc(sizeof(COMMANDVAR));
|
|
|
|
if (!lpVar->lpNext)
|
|
return false;
|
|
|
|
ZeroMemory(lpVar->lpNext, sizeof(COMMANDVAR));
|
|
lpVar->lpNext->lpPrev = lpVar;
|
|
lpVar->lpNext->lpNext = lpBelow;
|
|
lpVar = lpVar->lpNext;
|
|
}
|
|
// Insert before all items
|
|
else
|
|
{
|
|
lpVar->lpPrev = (LPCOMMANDVAR)malloc(sizeof(COMMANDVAR));
|
|
|
|
if (!lpVar->lpPrev)
|
|
return false;
|
|
|
|
ZeroMemory(lpVar->lpPrev, sizeof(COMMANDVAR));
|
|
|
|
lpVar->lpPrev->lpNext = lpVar;
|
|
lpVar->lpPrev->lpPrev = NULL;
|
|
lpVar = lpVar->lpPrev;
|
|
lpStruct->vars = lpVar;
|
|
}
|
|
}
|
|
// No existing list, create a new list with our entry
|
|
else
|
|
{
|
|
lpVar = (LPCOMMANDVAR)malloc(sizeof(COMMANDVAR));
|
|
|
|
if (!lpVar)
|
|
return false;
|
|
|
|
ZeroMemory(lpVar, sizeof(COMMANDVAR));
|
|
lpStruct->vars = lpVar;
|
|
}
|
|
|
|
lpVar->lpszVar = strdup(lpszVar);
|
|
lpVar->nType = nVarType;
|
|
lpVar->nKeywordPos = nKeywordPos;
|
|
|
|
if (nVarType == LLTYPE_VARIABLE || nVarType == LLTYPE_FIXED)
|
|
{
|
|
lpszTypeLen = strtok(NULL, " ");
|
|
lpVar->nTypeLen = atoi(lpszTypeLen);
|
|
}
|
|
|
|
dwVarStart = dwVarEnd + 1;
|
|
dwVarEnd = dwEnd;
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
// Parse the struct message template block of a command
|
|
bool get_struct_blocks(LPCOMMAND lpCmd, LPBYTE lpBuffer, DWORD dwStart, DWORD dwEnd)
|
|
{
|
|
DWORD dwStructStart = dwStart;
|
|
DWORD dwStructEnd = dwEnd;
|
|
DWORD dwStructChildren = 0;
|
|
|
|
while (get_block_markers(lpBuffer, dwStructStart, dwStructEnd, dwStructChildren))
|
|
{
|
|
char szStructLine[256];
|
|
DWORD dwStructLen = (dwStructChildren ? dwStructChildren - 1 : dwStructEnd - 1) - dwStructStart;
|
|
|
|
memcpy(&szStructLine, &lpBuffer[dwStructStart+1], dwStructLen);
|
|
szStructLine[dwStructLen] = '\0';
|
|
trim(szStructLine);
|
|
|
|
//printf("\t%s\n", szStructLine);
|
|
|
|
char *lpszStruct = strtok(szStructLine, " ");
|
|
char *lpszType = strtok(NULL, " ");
|
|
int nKeywordPos = get_keyword_pos(lpszStruct);
|
|
int nVarType = get_var_type(lpszType);
|
|
|
|
LPCOMMANDSTRUCT lpStruct = lpCmd->structs;
|
|
|
|
if (lpStruct)
|
|
{
|
|
// Insert after an item
|
|
if (nKeywordPos > lpStruct->nKeywordPos)
|
|
{
|
|
while (lpStruct->lpNext && nKeywordPos > lpStruct->lpNext->nKeywordPos)
|
|
lpStruct = lpStruct->lpNext;
|
|
|
|
LPCOMMANDSTRUCT lpBelow = lpStruct->lpNext;
|
|
|
|
lpStruct->lpNext = (LPCOMMANDSTRUCT)malloc(sizeof(COMMANDSTRUCT));
|
|
|
|
if (!lpStruct->lpNext)
|
|
return false;
|
|
|
|
ZeroMemory(lpStruct->lpNext, sizeof(COMMANDSTRUCT));
|
|
lpStruct->lpNext->lpPrev = lpStruct;
|
|
lpStruct->lpNext->lpNext = lpBelow;
|
|
lpStruct = lpStruct->lpNext;
|
|
}
|
|
// Insert before all items
|
|
else
|
|
{
|
|
lpStruct->lpPrev = (LPCOMMANDSTRUCT)malloc(sizeof(COMMANDSTRUCT));
|
|
|
|
if (!lpStruct->lpPrev)
|
|
return false;
|
|
|
|
ZeroMemory(lpStruct->lpPrev, sizeof(COMMANDSTRUCT));
|
|
|
|
lpStruct->lpPrev->lpNext = lpStruct;
|
|
lpStruct->lpPrev->lpPrev = NULL;
|
|
lpStruct = lpStruct->lpPrev;
|
|
lpCmd->structs = lpStruct;
|
|
}
|
|
}
|
|
// No existing list, create a new list with our entry
|
|
else
|
|
{
|
|
lpCmd->structs = (LPCOMMANDSTRUCT)malloc(sizeof(COMMANDSTRUCT));
|
|
|
|
if (!lpCmd->structs)
|
|
return false;
|
|
|
|
ZeroMemory(lpCmd->structs, sizeof(COMMANDSTRUCT));
|
|
lpStruct = lpCmd->structs;
|
|
}
|
|
|
|
lpStruct->lpszStruct = strdup(lpszStruct);
|
|
lpStruct->nKeywordPos = nKeywordPos;
|
|
lpStruct->nType = nVarType;
|
|
|
|
if (nVarType == LLTYPE_VARIABLE)
|
|
{
|
|
lpStruct->cItems = 1;
|
|
}
|
|
else if (nVarType == LLTYPE_MULTIPLE)
|
|
{
|
|
char *lpszTypeLen = strtok(NULL, " ");
|
|
lpStruct->cItems = atoi(lpszTypeLen);
|
|
}
|
|
|
|
get_var_blocks(lpStruct, lpBuffer, dwStructStart + 1, dwStructEnd - 1);
|
|
|
|
dwStructStart = dwStructEnd + 1;
|
|
dwStructEnd = dwEnd;
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
// Parse the command message template blocks
|
|
bool get_command_blocks(LPBYTE lpBuffer, DWORD dwStart, DWORD dwEnd)
|
|
{
|
|
DWORD dwCmdStart = dwStart;
|
|
DWORD dwCmdEnd = dwEnd;
|
|
DWORD dwCmdChildren = 0;
|
|
|
|
while (get_block_markers(lpBuffer, dwCmdStart, dwCmdEnd, dwCmdChildren))
|
|
{
|
|
char szCmdLine[256];
|
|
DWORD dwCmdLen = (dwCmdChildren ? dwCmdChildren - 1 : dwCmdEnd - 1) - dwCmdStart;
|
|
|
|
memcpy(&szCmdLine, &lpBuffer[dwCmdStart+1], dwCmdLen);
|
|
szCmdLine[dwCmdLen] = '\0';
|
|
trim(szCmdLine);
|
|
|
|
//printf("%s\n", szCmdLine);
|
|
|
|
char *lpszCmd = strtok(szCmdLine, " ");
|
|
char *lpszFreq = strtok(NULL, " ");
|
|
char *lpszFixed = NULL;
|
|
char *lpszTrust = NULL;
|
|
char *lpszCoding = NULL;
|
|
static DWORD dwLow = 1;
|
|
static DWORD dwMed = 1;
|
|
static DWORD dwHigh = 1;
|
|
COMMAND *lpCmd = NULL;
|
|
|
|
// Get the commands frequency
|
|
if (!strnicmp(lpszFreq, "Fixed", 6))
|
|
{
|
|
lpszFixed = strtok(NULL, " ");
|
|
DWORD dwFixed = (DWORD)httoi(lpszFixed) ^ 0xffff0000;
|
|
lpCmd = &cmds_low[dwFixed];
|
|
}
|
|
else if (!strnicmp(lpszFreq, "Low", 4))
|
|
{
|
|
lpCmd = &cmds_low[dwLow++];
|
|
}
|
|
else if (!strnicmp(lpszFreq, "Medium", 7))
|
|
{
|
|
lpCmd = &cmds_med[dwMed++];
|
|
}
|
|
else if (!strnicmp(lpszFreq, "High", 5))
|
|
{
|
|
lpCmd = &cmds_high[dwHigh++];
|
|
}
|
|
|
|
lpszTrust = strtok(NULL, " ");
|
|
lpszCoding = strtok(NULL, " ");
|
|
|
|
lpCmd->lpszCmd = strdup(lpszCmd);
|
|
|
|
// Is the command zero encoded?
|
|
if (!strnicmp(lpszCoding, "Zerocoded", 10))
|
|
{
|
|
lpCmd->bZerocoded = true;
|
|
}
|
|
|
|
// Is the command trusted?
|
|
if (!strnicmp(lpszTrust, "Trusted", 8))
|
|
{
|
|
lpCmd->bTrusted = true;
|
|
}
|
|
|
|
get_struct_blocks(lpCmd, lpBuffer, dwCmdStart + 1, dwCmdEnd - 1);
|
|
|
|
//printf("----------------------\n");
|
|
|
|
dwCmdStart = dwCmdEnd + 1;
|
|
dwCmdEnd = dwEnd;
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
void dump_structs(LPCOMMANDSTRUCT lpStruct)
|
|
{
|
|
while (lpStruct)
|
|
{
|
|
//dprintf("\t%04d %s (%s / %hu)\n", lpStruct->nKeywordPos, lpStruct->lpszStruct, LLTYPES[lpStruct->nType], lpStruct->cItems);
|
|
|
|
LPCOMMANDVAR lpVar = lpStruct->vars;
|
|
|
|
while (lpVar)
|
|
{
|
|
//dprintf("\t\t%04d %s (%s / %d)\n", lpVar->nKeywordPos, lpVar->lpszVar, LLTYPES[lpVar->nType], lpVar->nTypeLen);
|
|
lpVar = lpVar->lpNext;
|
|
}
|
|
|
|
// if (lpStruct->lpNext)
|
|
// {
|
|
lpStruct = lpStruct->lpNext;
|
|
// SAFE_FREE(lpStruct->lpPrev->lpszStruct);
|
|
// SAFE_FREE(lpStruct->lpPrev);
|
|
// }
|
|
// else
|
|
// {
|
|
// SAFE_FREE(lpStruct->lpszStruct);
|
|
// SAFE_FREE(lpStruct);
|
|
// }
|
|
}
|
|
}
|
|
|
|
void WINAPI parse_command(LPCOMMAND lpCommand, CServer *server, char *zerobuf, int *len, int pos)
|
|
{
|
|
//dprintf("--- %s ---\n", lpCommand->lpszCmd);
|
|
|
|
LPCOMMANDSTRUCT lpStruct = lpCommand->structs;
|
|
|
|
while (lpStruct)
|
|
{
|
|
//dprintf("\t%04d %s (%s / %hu)\n", lpStruct->nKeywordPos, lpStruct->lpszStruct, LLTYPES[lpStruct->nType], lpStruct->cItems);
|
|
BYTE cItems = 1;
|
|
|
|
if (lpStruct->nType == LLTYPE_VARIABLE)
|
|
{
|
|
memcpy(&cItems, &zerobuf[pos], sizeof(cItems));
|
|
pos += sizeof(cItems);
|
|
}
|
|
else if (lpStruct->nType == LLTYPE_MULTIPLE)
|
|
{
|
|
cItems = lpStruct->cItems;
|
|
}
|
|
|
|
for (BYTE c = 0; c < cItems; c++)
|
|
{
|
|
//dprintf("--- %s ----\n", lpStruct->lpszStruct);
|
|
|
|
LPCOMMANDVAR lpVar = lpStruct->vars;
|
|
|
|
while (lpVar)
|
|
{
|
|
//dprintf("\t\t%04d %s (%s / %d)\n", lpVar->nKeywordPos, lpVar->lpszVar, LLTYPES[lpVar->nType], lpVar->nTypeLen);
|
|
|
|
switch (lpVar->nType)
|
|
{
|
|
case LLTYPE_U8:
|
|
{
|
|
unsigned char ubData;
|
|
memcpy(&ubData, &zerobuf[pos], sizeof(ubData));
|
|
pos += sizeof(ubData);
|
|
//dprintf("%s: %hu\n", lpVar->lpszVar, ubData);
|
|
}
|
|
break;
|
|
|
|
case LLTYPE_U16:
|
|
{
|
|
WORD wData;
|
|
memcpy(&wData, &zerobuf[pos], sizeof(wData));
|
|
pos += sizeof(wData);
|
|
//dprintf("%s: %u\n", lpVar->lpszVar, wData);
|
|
}
|
|
break;
|
|
|
|
case LLTYPE_U32:
|
|
{
|
|
DWORD dwData;
|
|
memcpy(&dwData, &zerobuf[pos], sizeof(dwData));
|
|
pos += sizeof(dwData);
|
|
//dprintf("%s: %lu\n", lpVar->lpszVar, dwData);
|
|
}
|
|
break;
|
|
|
|
case LLTYPE_U64:
|
|
{
|
|
ULONGLONG ullData;
|
|
memcpy(&ullData, &zerobuf[pos], sizeof(ullData));
|
|
pos += sizeof(ullData);
|
|
//dprintf("%s: %I64u\n", lpVar->lpszVar, ullData);
|
|
}
|
|
break;
|
|
|
|
case LLTYPE_S8:
|
|
{
|
|
BYTE bData;
|
|
memcpy(&bData, &zerobuf[pos], sizeof(bData));
|
|
pos += sizeof(bData);
|
|
//dprintf("%s: %hd\n", lpVar->lpszVar, bData);
|
|
}
|
|
break;
|
|
|
|
case LLTYPE_S16:
|
|
{
|
|
SHORT sData;
|
|
memcpy(&sData, &zerobuf[pos], sizeof(sData));
|
|
pos += sizeof(sData);
|
|
//dprintf("%s: %d\n", lpVar->lpszVar, sData);
|
|
}
|
|
break;
|
|
|
|
case LLTYPE_S32:
|
|
{
|
|
LONG nData;
|
|
memcpy(&nData, &zerobuf[pos], sizeof(nData));
|
|
pos += sizeof(nData);
|
|
//dprintf("%s: %ld\n", lpVar->lpszVar, nData);
|
|
}
|
|
break;
|
|
|
|
case LLTYPE_S64:
|
|
break;
|
|
|
|
case LLTYPE_F8:
|
|
break;
|
|
|
|
case LLTYPE_F16:
|
|
break;
|
|
|
|
case LLTYPE_F32:
|
|
{
|
|
FLOAT fData;
|
|
memcpy(&fData, &zerobuf[pos], sizeof(fData));
|
|
pos += sizeof(fData);
|
|
//dprintf("%s: %f\n", lpVar->lpszVar, fData);
|
|
}
|
|
break;
|
|
|
|
case LLTYPE_F64:
|
|
{
|
|
double dData;
|
|
memcpy(&dData, &zerobuf[pos], sizeof(dData));
|
|
pos += sizeof(dData);
|
|
//dprintf("%s: %f\n", lpVar->lpszVar, dData);
|
|
}
|
|
break;
|
|
|
|
case LLTYPE_LLUUID:
|
|
{
|
|
BYTE bData[16];
|
|
memcpy(&bData, &zerobuf[pos], sizeof(bData));
|
|
pos += sizeof(bData);
|
|
//dprintf("%s: ", lpVar->lpszVar);
|
|
//for (int u = 0; u < sizeof(bData); u++)
|
|
//dprintf("%02x", bData[u]);
|
|
//dprintf("\n");
|
|
}
|
|
break;
|
|
|
|
case LLTYPE_BOOL:
|
|
{
|
|
BYTE bData;
|
|
memcpy(&bData, &zerobuf[pos], sizeof(bData));
|
|
pos += sizeof(bData);
|
|
//dprintf("%s: %s\n", lpVar->lpszVar, (bData) ? "True" : "False");
|
|
}
|
|
break;
|
|
|
|
case LLTYPE_LLVECTOR3:
|
|
{
|
|
FLOAT fData[3];
|
|
memcpy(&fData, &zerobuf[pos], sizeof(fData));
|
|
pos += sizeof(fData);
|
|
//dprintf("%s: %f, %f, %f\n", lpVar->lpszVar, fData[0], fData[1], fData[2]);
|
|
}
|
|
break;
|
|
|
|
case LLTYPE_LLVECTOR3D:
|
|
{
|
|
double dData[3];
|
|
memcpy(&dData, &zerobuf[pos], sizeof(dData));
|
|
pos += sizeof(dData);
|
|
//dprintf("%s: %f, %f, %f\n", lpVar->lpszVar, dData[0], dData[1], dData[2]);
|
|
}
|
|
break;
|
|
|
|
/*case LLTYPE_VECTOR4:
|
|
{
|
|
FLOAT fData[4];
|
|
memcpy(&fData, &zerobuf[pos], sizeof(fData));
|
|
pos += sizeof(fData);
|
|
dprintf("%s: %f, %f, %f, %f\n", lpVar->lpszVar, fData[0], fData[1], fData[2], fData[3]);
|
|
}
|
|
break;*/
|
|
|
|
case LLTYPE_QUATERNION:
|
|
{
|
|
FLOAT fData[4];
|
|
memcpy(&fData, &zerobuf[pos], sizeof(fData));
|
|
pos += sizeof(fData);
|
|
//dprintf("%s: %f, %f, %f, %f\n", lpVar->lpszVar, fData[0], fData[1], fData[2], fData[3]);
|
|
}
|
|
break;
|
|
|
|
case LLTYPE_IPADDR:
|
|
{
|
|
BYTE ipData[4];
|
|
memcpy(&ipData, &zerobuf[pos], sizeof(ipData));
|
|
pos += sizeof(ipData);
|
|
//dprintf("%s: %hu.%hu.%hu.%hu\n", lpVar->lpszVar, ipData[0], ipData[1], ipData[2], ipData[3]);
|
|
}
|
|
break;
|
|
|
|
case LLTYPE_IPPORT:
|
|
{
|
|
WORD wData;
|
|
memcpy(&wData, &zerobuf[pos], sizeof(wData));
|
|
pos += sizeof(wData);
|
|
//dprintf("%s: %hu\n", lpVar->lpszVar, htons(wData));
|
|
}
|
|
break;
|
|
|
|
case LLTYPE_VARIABLE:
|
|
{
|
|
if (lpVar->nTypeLen == 1)
|
|
{
|
|
BYTE cDataLen;
|
|
LPBYTE lpData = NULL;
|
|
|
|
memcpy(&cDataLen, &zerobuf[pos], sizeof(cDataLen));
|
|
pos += sizeof(cDataLen);
|
|
|
|
if (cDataLen > 0)
|
|
lpData = (LPBYTE)malloc(cDataLen);
|
|
|
|
if (lpData)
|
|
memcpy(lpData, &zerobuf[pos], cDataLen);
|
|
|
|
pos += cDataLen;
|
|
|
|
if (lpData)
|
|
{
|
|
bool bPrintable = true;
|
|
|
|
for (int j = 0; j < cDataLen - 1; j++)
|
|
{
|
|
if (((unsigned char)lpData[j] < 0x20 || (unsigned char)lpData[j] > 0x7E) && (unsigned char)lpData[j] != 0x09 && (unsigned char)lpData[j] != 0x0D)
|
|
bPrintable = false;
|
|
}
|
|
|
|
if (bPrintable && lpData[cDataLen - 1] == '\0')
|
|
{
|
|
//dprintf("%s: %s\n", lpVar->lpszVar, lpData);
|
|
}
|
|
else
|
|
{
|
|
for (int j = 0; j < cDataLen; j += 16)
|
|
{
|
|
//dprintf("%s: ", lpVar->lpszVar);
|
|
|
|
for (int k = 0; k < 16; k++)
|
|
{
|
|
if ((j + k) < cDataLen)
|
|
{
|
|
//dprintf("%02x ", (unsigned char)lpData[j+k]);
|
|
}
|
|
else
|
|
{
|
|
//dprintf(" ");
|
|
}
|
|
}
|
|
|
|
for (int k = 0; k < 16 && (j + k) < cDataLen; k++)
|
|
{
|
|
//dprintf("%c", ((unsigned char)lpData[j+k] >= 0x20 && (unsigned char)lpData[j+k] <= 0x7E) ? (unsigned char)lpData[j+k] : '.');
|
|
}
|
|
|
|
//dprintf("\n");
|
|
}
|
|
}
|
|
}
|
|
|
|
SAFE_FREE(lpData);
|
|
}
|
|
else if (lpVar->nTypeLen == 2)
|
|
{
|
|
WORD cDataLen;
|
|
LPBYTE lpData = NULL;
|
|
|
|
memcpy(&cDataLen, &zerobuf[pos], sizeof(cDataLen));
|
|
pos += sizeof(cDataLen);
|
|
|
|
if (cDataLen > 0)
|
|
lpData = (LPBYTE)malloc(cDataLen);
|
|
|
|
if (lpData)
|
|
memcpy(lpData, &zerobuf[pos], cDataLen);
|
|
|
|
pos += cDataLen;
|
|
|
|
if (lpData)
|
|
{
|
|
bool bPrintable = true;
|
|
|
|
for (int j = 0; j < cDataLen - 1; j++)
|
|
{
|
|
if (((unsigned char)lpData[j] < 0x20 || (unsigned char)lpData[j] > 0x7E) && (unsigned char)lpData[j] != 0x09 && (unsigned char)lpData[j] != 0x0D)
|
|
bPrintable = false;
|
|
}
|
|
|
|
if (bPrintable && lpData[cDataLen - 1] == '\0')
|
|
{
|
|
//dprintf("%s: %s\n", lpVar->lpszVar, lpData);
|
|
}
|
|
else
|
|
{
|
|
for (int j = 0; j < cDataLen; j += 16)
|
|
{
|
|
//dprintf("%s: ", lpVar->lpszVar);
|
|
|
|
for (int k = 0; k < 16; k++)
|
|
{
|
|
if ((j + k) < cDataLen)
|
|
{
|
|
//dprintf("%02x ", (unsigned char)lpData[j+k]);
|
|
}
|
|
else
|
|
{
|
|
//dprintf(" ");
|
|
}
|
|
}
|
|
|
|
for (int k = 0; k < 16 && (j + k) < cDataLen; k++)
|
|
{
|
|
//dprintf("%c", ((unsigned char)lpData[j+k] >= 0x20 && (unsigned char)lpData[j+k] <= 0x7E) ? (unsigned char)lpData[j+k] : '.');
|
|
}
|
|
|
|
//dprintf("\n");
|
|
}
|
|
}
|
|
}
|
|
|
|
SAFE_FREE(lpData);
|
|
}
|
|
}
|
|
break;
|
|
|
|
case LLTYPE_FIXED:
|
|
{
|
|
LPBYTE lpData = NULL;
|
|
|
|
if (lpVar->nTypeLen > 0)
|
|
lpData = (LPBYTE)malloc(lpVar->nTypeLen);
|
|
|
|
if (lpData)
|
|
memcpy(lpData, &zerobuf[pos], lpVar->nTypeLen);
|
|
|
|
pos += lpVar->nTypeLen;
|
|
|
|
if (lpData)
|
|
{
|
|
bool bPrintable = true;
|
|
|
|
for (int j = 0; j < lpVar->nTypeLen - 1; j++)
|
|
{
|
|
if (((unsigned char)lpData[j] < 0x20 || (unsigned char)lpData[j] > 0x7E) && (unsigned char)lpData[j] != 0x09 && (unsigned char)lpData[j] != 0x0D)
|
|
bPrintable = false;
|
|
}
|
|
|
|
if (bPrintable && lpData[lpVar->nTypeLen - 1] == '\0')
|
|
{
|
|
//dprintf("%s: %s\n", lpVar->lpszVar, lpData);
|
|
}
|
|
else
|
|
{
|
|
for (int j = 0; j < lpVar->nTypeLen; j += 16)
|
|
{
|
|
//dprintf("%s: ", lpVar->lpszVar);
|
|
|
|
for (int k = 0; k < 16; k++)
|
|
{
|
|
if ((j + k) < lpVar->nTypeLen)
|
|
{
|
|
//dprintf("%02x ", (unsigned char)lpData[j+k]);
|
|
}
|
|
else
|
|
{
|
|
//dprintf(" ");
|
|
}
|
|
}
|
|
|
|
for (int k = 0; k < 16 && (j + k) < lpVar->nTypeLen; k++)
|
|
{
|
|
//dprintf("%c", ((unsigned char)lpData[j+k] >= 0x20 && (unsigned char)lpData[j+k] <= 0x7E) ? (unsigned char)lpData[j+k] : '.');
|
|
}
|
|
|
|
//dprintf("\n");
|
|
}
|
|
}
|
|
}
|
|
|
|
SAFE_FREE(lpData);
|
|
}
|
|
break;
|
|
|
|
case LLTYPE_SINGLE:
|
|
case LLTYPE_MULTIPLE:
|
|
case LLTYPE_NULL:
|
|
default:
|
|
break;
|
|
}
|
|
|
|
lpVar = lpVar->lpNext;
|
|
}
|
|
}
|
|
|
|
lpStruct = lpStruct->lpNext;
|
|
}
|
|
}
|
|
|
|
CMessage * WINAPI map_command(LPCOMMAND lpCommand, CServer *server, char *zerobuf, int *len, int pos)
|
|
{
|
|
// dprintf("--- %s ---\n", lpCommand->lpszCmd);
|
|
|
|
int oldPos = pos;
|
|
|
|
CMessage *msg = new CMessage;
|
|
|
|
if (!msg)
|
|
return NULL;
|
|
|
|
msg->SetCommand(lpCommand->lpszCmd);
|
|
|
|
LPCOMMANDSTRUCT lpStruct = lpCommand->structs;
|
|
|
|
while (lpStruct)
|
|
{
|
|
//dprintf("\t%04d %s (%s / %hu)\n", lpStruct->nKeywordPos, lpStruct->lpszStruct, LLTYPES[lpStruct->nType], lpStruct->cItems);
|
|
BYTE cItems = 1;
|
|
|
|
if (lpStruct->nType == LLTYPE_VARIABLE)
|
|
{
|
|
memcpy(&cItems, &zerobuf[pos], sizeof(cItems));
|
|
pos += sizeof(cItems);
|
|
}
|
|
else if (lpStruct->nType == LLTYPE_MULTIPLE)
|
|
{
|
|
cItems = lpStruct->cItems;
|
|
}
|
|
|
|
for (BYTE c = 0; c < cItems; c++)
|
|
{
|
|
//dprintf("--- %s ----\n", lpStruct->lpszStruct);
|
|
CBlock *block = new CBlock;
|
|
msg->AddBlock(lpStruct->lpszStruct, lpStruct->nType, block);
|
|
|
|
LPCOMMANDVAR lpVar = lpStruct->vars;
|
|
|
|
while (lpVar)
|
|
{
|
|
//dprintf("\t\t%04d %s (%s / %d)\n", lpVar->nKeywordPos, lpVar->lpszVar, LLTYPES[lpVar->nType], lpVar->nTypeLen);
|
|
CVar *var = new CVar;
|
|
var->SetVar(lpVar->lpszVar);
|
|
var->SetType(lpVar->nType, lpVar->nTypeLen);
|
|
pos += var->SetData((LPBYTE)&zerobuf[pos]);
|
|
block->AddVar(var);
|
|
lpVar = lpVar->lpNext;
|
|
}
|
|
}
|
|
|
|
lpStruct = lpStruct->lpNext;
|
|
}
|
|
|
|
BYTE bPack[4096];
|
|
int nPackedSize = msg->Pack(bPack);
|
|
int diff = memcmp(bPack, &zerobuf[oldPos], nPackedSize);
|
|
|
|
if (diff)
|
|
{
|
|
msg->Dump();
|
|
dprintf("PACKED: %d / %d (%d) ===> %d\n", nPackedSize, *len, oldPos, diff);
|
|
}
|
|
|
|
return msg;
|
|
}
|
|
|
|
void WINAPI cmd_Silent(LPCOMMAND lpCommand, CServer *server, char *zerobuf, int *len, int pos)
|
|
{
|
|
}
|
|
|
|
void WINAPI cmd_Default(LPCOMMAND lpCommand, CServer *server, char *zerobuf, int *len, int pos)
|
|
{
|
|
//dprintf("Flags: %u\n", zerobuf[0]);
|
|
CMessage *msg = map_command(lpCommand, server, zerobuf, len, pos);
|
|
msg->Dump();
|
|
SAFE_DELETE(msg);
|
|
}
|
|
|
|
void WINAPI cmd_LoginReply(LPCOMMAND lpCommand, CServer *server, char *zerobuf, int *len, int pos)
|
|
{
|
|
parse_command(lpCommand, server, zerobuf, len, pos);
|
|
}
|
|
|
|
CMDHOOK pCMDHooks[] = {
|
|
{ _T("Default"), (PROC)cmd_Default },
|
|
{ _T("DirLandReply"), (PROC)cmd_Silent }, // Silence the most common
|
|
{ _T("AvatarAnimation"), (PROC)cmd_Silent }, // packets
|
|
{ _T("CoarseLocationUpdate"), (PROC)cmd_Silent },
|
|
{ _T("CompletePingCheck"), (PROC)cmd_Silent },
|
|
{ _T("LayerData"), (PROC)cmd_Silent },
|
|
{ _T("PacketAck"), (PROC)cmd_Silent },
|
|
{ _T("StartPingCheck"), (PROC)cmd_Silent },
|
|
{ _T("SimulatorViewerTimeMessage"), (PROC)cmd_Silent },
|
|
{ _T("ImagePacket"), (PROC)cmd_Silent },
|
|
{ _T("TransferPacket"), (PROC)cmd_Silent },
|
|
{ _T("ObjectUpdate"), (PROC)cmd_Silent },
|
|
{ _T("ObjectUpdateCompressed"), (PROC)cmd_Silent },
|
|
{ _T("AgentThrottle"), (PROC)cmd_Silent },
|
|
{ _T("CoarseLocationUpdate"), (PROC)cmd_Silent },
|
|
{ _T("UUIDNameReply"), (PROC)cmd_Silent },
|
|
{ _T("RequestImage"), (PROC)cmd_Silent },
|
|
{ _T("ImageData"), (PROC)cmd_Silent },
|
|
{ _T("SimStats"), (PROC)cmd_Silent },
|
|
{ _T("ViewerEffect"), (PROC)cmd_Silent },
|
|
{ _T("TransferRequest"), (PROC)cmd_Silent },
|
|
{ _T("DirClassifiedReply"), (PROC)cmd_Silent },
|
|
{ _T("DirEventsReply"), (PROC)cmd_Silent },
|
|
{ _T("DirPopularReply"), (PROC)cmd_Silent },
|
|
{ _T("DirLandReply"), (PROC)cmd_Silent },
|
|
{ _T("AgentUpdate"), (PROC)cmd_Silent },
|
|
{ _T("ObjectUpdateCached"), (PROC)cmd_Silent },
|
|
{ _T("ImprovedTerseObjectUpdate"), (PROC)cmd_Silent },
|
|
{ _T("RequestMultipleObjects"), (PROC)cmd_Silent },
|
|
{ _T("AttachedSound"), (PROC)cmd_Silent },
|
|
{ _T("ViewerStats"), (PROC)cmd_Silent },
|
|
{ _T("TransferInfo"), (PROC)cmd_Silent },
|
|
{ _T("ParcelOverlay"), (PROC)cmd_Silent },
|
|
{ _T("SendXferPacket"), (PROC)cmd_Silent },
|
|
{ _T("DirPlacesReply"), (PROC)cmd_Silent },
|
|
{ NULL, NULL }
|
|
};
|
|
|
|
int decomm()
|
|
{
|
|
FILE *fpComm;
|
|
FILE *fpMsg;
|
|
|
|
fpComm = fopen(g_pConfig->m_pCommDatPath, "rb");
|
|
|
|
if (!fpComm)
|
|
{
|
|
printf("Couldn't open %s for reading, aborting...\n", g_pConfig->m_pCommDatPath);
|
|
return -1;
|
|
}
|
|
|
|
fpMsg = fopen(g_pConfig->m_pMessageTemplatePath, "wb");
|
|
|
|
if (!fpMsg)
|
|
{
|
|
printf("Couldn't open %s for writing, aborting...\n", g_pConfig->m_pMessageTemplatePath);
|
|
return -1;
|
|
}
|
|
|
|
printf("Decrypting %s to %s\n", g_pConfig->m_pCommDatPath, g_pConfig->m_pMessageTemplatePath);
|
|
static unsigned char ucMagicKey = 0;
|
|
long lTemplateSize = 0;
|
|
|
|
fseek(fpComm, 0, SEEK_END);
|
|
lTemplateSize = ftell(fpComm);
|
|
fseek(fpComm, 0, SEEK_SET);
|
|
|
|
BYTE buffer[2048];
|
|
BYTE stripped[2048];
|
|
LPBYTE lpTemplate = (LPBYTE)malloc(lTemplateSize);
|
|
DWORD dwTemplateWrote = 0;
|
|
|
|
if (!lpTemplate)
|
|
return -1;
|
|
|
|
bool bComment = false;
|
|
|
|
while (!feof(fpComm))
|
|
{
|
|
size_t stRead = fread(&buffer, 1, sizeof(buffer), fpComm);
|
|
size_t stStripped = 0;
|
|
|
|
for (size_t stCount = 0; stCount < stRead; stCount++)
|
|
{
|
|
buffer[stCount] ^= ucMagicKey;
|
|
|
|
if (!bComment && buffer[stCount] != '/')
|
|
stripped[stStripped++] = buffer[stCount];
|
|
|
|
if (bComment && buffer[stCount] == '\n')
|
|
bComment = false;
|
|
|
|
if (!bComment && buffer[stCount] == '/')
|
|
bComment = true;
|
|
|
|
ucMagicKey += 43;
|
|
}
|
|
|
|
memcpy(lpTemplate + dwTemplateWrote, &stripped, stStripped);
|
|
dwTemplateWrote += (DWORD)stStripped;
|
|
|
|
size_t stWrote = fwrite(&stripped, 1, stStripped, fpMsg);
|
|
|
|
printf(".");
|
|
fflush(stdout);
|
|
}
|
|
|
|
printf("\nDone.\n");
|
|
|
|
printf("template size: %ld\n", lTemplateSize);
|
|
|
|
ZeroMemory(&cmds_low, sizeof(cmds_low));
|
|
ZeroMemory(&cmds_med, sizeof(cmds_med));
|
|
ZeroMemory(&cmds_high, sizeof(cmds_high));
|
|
|
|
get_command_blocks(lpTemplate, 0, lTemplateSize);
|
|
|
|
fclose(fpComm);
|
|
fclose(fpMsg);
|
|
|
|
for (int i = 1; i < MAX_COMMANDS_LOW; i++)
|
|
{
|
|
if (cmds_low[i].lpszCmd)
|
|
{
|
|
//dprintf("LOW %05d - %s - %s - %s\n", i, cmds_low[i].lpszCmd, cmds_low[i].bTrusted ? "Trusted" : "Untrusted", cmds_low[i].bZerocoded ? "Zerocoded" : "Unencoded");
|
|
dump_structs(cmds_low[i].structs);
|
|
//SAFE_FREE(cmds_low[i].lpszCmd);
|
|
}
|
|
}
|
|
|
|
for (int i = 1; i < MAX_COMMANDS_MEDIUM; i++)
|
|
{
|
|
if (cmds_med[i].lpszCmd)
|
|
{
|
|
//dprintf("Medium %05d - %s\n", i, cmds_med[i].lpszCmd);
|
|
dump_structs(cmds_med[i].structs);
|
|
//SAFE_FREE(cmds_med[i].lpszCmd);
|
|
}
|
|
}
|
|
|
|
for (int i = 1; i < MAX_COMMANDS_HIGH; i++)
|
|
{
|
|
if (cmds_high[i].lpszCmd)
|
|
{
|
|
//dprintf("High %05d - %s\n", i, cmds_high[i].lpszCmd);
|
|
dump_structs(cmds_high[i].structs);
|
|
//SAFE_FREE(cmds_high[i].lpszCmd);
|
|
}
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
HMODULE WINAPI new_LoadLibraryA(
|
|
LPCSTR lpLibFileName
|
|
)
|
|
{
|
|
if (g_hOpenGL != NULL && !_tcsicmp(lpLibFileName, "OPENGL32"))
|
|
return g_hOpenGL;
|
|
|
|
// dprintf("[LoadLibraryA] Filename(%s)\n", lpLibFileName);
|
|
|
|
HMODULE hModule = NULL;
|
|
PROC pOldProc = pAPIHooks[APIHOOK_LOADLIBRARYA].pOldProc;
|
|
|
|
if (pOldProc != NULL && !IsBadCodePtr((PROC)pOldProc))
|
|
{
|
|
hModule = ((HMODULE (WINAPI *)(LPCSTR))pOldProc)(lpLibFileName);
|
|
if (hModule != NULL)
|
|
{
|
|
SaveImportHooks();
|
|
InstallImportHooks();
|
|
}
|
|
}
|
|
|
|
if (!_tcsicmp(lpLibFileName, "OPENGL32"))
|
|
g_hOpenGL = hModule;
|
|
|
|
return hModule;
|
|
}
|
|
|
|
BOOL WINAPI new_FreeLibraryA(
|
|
HMODULE hLibModule
|
|
)
|
|
{
|
|
if (hLibModule == g_hOpenGL)
|
|
{
|
|
return TRUE;
|
|
}
|
|
|
|
return ((BOOL (WINAPI *)(HMODULE))pAPIHooks[APIHOOK_FREELIBRARYA].pOldProc)(hLibModule);
|
|
}
|
|
|
|
HMODULE WINAPI new_LoadLibraryW(
|
|
LPCWSTR lpLibFileName
|
|
)
|
|
{
|
|
// dprintf("[LoadLibraryW] Filename(%S)\n", lpLibFileName);
|
|
|
|
HMODULE hModule = NULL;
|
|
PROC pOldProc = pAPIHooks[APIHOOK_LOADLIBRARYW].pOldProc;
|
|
|
|
if (pOldProc != NULL && !IsBadCodePtr((PROC)pOldProc))
|
|
{
|
|
hModule = ((HMODULE (WINAPI *)(LPCWSTR))pOldProc)(lpLibFileName);
|
|
if (hModule != NULL)
|
|
{
|
|
SaveImportHooks();
|
|
InstallImportHooks();
|
|
}
|
|
}
|
|
|
|
return hModule;
|
|
}
|
|
|
|
HMODULE WINAPI new_LoadLibraryExA(
|
|
LPCSTR lpLibFileName,
|
|
HANDLE hFile,
|
|
DWORD dwFlags
|
|
)
|
|
{
|
|
// dprintf("[LoadLibraryExA] Filename(%s)\n", lpLibFileName);
|
|
|
|
HMODULE hModule = NULL;
|
|
PROC pOldProc = pAPIHooks[APIHOOK_LOADLIBRARYEXA].pOldProc;
|
|
|
|
if (pOldProc != NULL && !IsBadCodePtr((PROC)pOldProc))
|
|
{
|
|
hModule = ((HMODULE (WINAPI *)(LPCSTR, HANDLE, DWORD))pOldProc)(lpLibFileName, hFile, dwFlags);
|
|
if (hModule != NULL)
|
|
{
|
|
SaveImportHooks();
|
|
InstallImportHooks();
|
|
}
|
|
}
|
|
|
|
return hModule;
|
|
}
|
|
|
|
HMODULE WINAPI new_LoadLibraryExW(
|
|
LPCWSTR lpLibFileName,
|
|
HANDLE hFile,
|
|
DWORD dwFlags)
|
|
{
|
|
// dprintf("[LoadLibraryExW] Filename(%S)\n", lpLibFileName);
|
|
|
|
HMODULE hModule = NULL;
|
|
PROC pOldProc = pAPIHooks[APIHOOK_LOADLIBRARYEXW].pOldProc;
|
|
|
|
if (pOldProc != NULL && !IsBadCodePtr((PROC)pOldProc))
|
|
{
|
|
hModule = ((HMODULE (WINAPI *)(LPCWSTR, HANDLE, DWORD))pOldProc)(lpLibFileName, hFile, dwFlags);
|
|
if (hModule != NULL)
|
|
{
|
|
SaveImportHooks();
|
|
InstallImportHooks();
|
|
}
|
|
}
|
|
|
|
return hModule;
|
|
}
|
|
|
|
FARPROC WINAPI new_GetProcAddress(HMODULE hModule, LPCSTR lpProcName)
|
|
{
|
|
TCHAR szMod[MAX_PATH];
|
|
|
|
GetModuleFileName(hModule, szMod, sizeof(szMod));
|
|
|
|
if (HIWORD((DWORD)lpProcName) == 0)
|
|
{
|
|
WORD wOrdinal = LOWORD((DWORD)lpProcName);
|
|
// dprintf(_T("[GetProcAddress] [%s][@%d]\n"), szMod, wOrdinal);
|
|
}
|
|
else
|
|
{
|
|
if (lpProcName != NULL && !IsBadCodePtr((PROC)lpProcName))
|
|
{
|
|
if (!stricmp(lpProcName, "wglSwapBuffers"))
|
|
{
|
|
|
|
}
|
|
else if (!stricmp(lpProcName, "InternetReadFile"))
|
|
{
|
|
dprintf(_T("[***GetProcAddress] [%s][%s]\n"), szMod, lpProcName);
|
|
return pAPIHooks[(int)APIHOOK_INTERNETREADFILE].pNewProc;
|
|
}
|
|
else if (!stricmp(lpProcName, "InternetOpenUrlA"))
|
|
{
|
|
dprintf(_T("[***GetProcAddress] [%s][%s]\n"), szMod, lpProcName);
|
|
return pAPIHooks[(int)APIHOOK_INTERNETOPENURLA].pNewProc;
|
|
}
|
|
else if (!stricmp(lpProcName, "CPEncrypt"))
|
|
{
|
|
dprintf(_T("[***CPEncrypt] [%s][%s]\n"), szMod, lpProcName);
|
|
return pAPIHooks[(int)APIHOOK_CPENCRYPT].pNewProc;
|
|
}
|
|
//else
|
|
//dprintf(_T("[GetProcAddress] [%s][%s]\n"), szMod, lpProcName);
|
|
}
|
|
//else
|
|
//dprintf(_T("[GetProcAddress] [%s][<Bad Ptr>]\n"), szMod);
|
|
}
|
|
|
|
return ((FARPROC (WINAPI *)(HMODULE, LPCSTR))pAPIHooks[(int)APIHOOK_GETPROCADDRESS].pOldProc)(hModule, lpProcName);
|
|
}
|
|
|
|
struct hostent FAR * WINAPI new_gethostbyname(
|
|
const char FAR *name
|
|
)
|
|
{
|
|
dprintf("[new_gethostbyname] name(%s)\n", name);
|
|
|
|
struct hostent FAR * hp = ((struct hostent FAR * (WINAPI *)(const char FAR *))pAPIHooks[(int)APIHOOK_GETHOSTBYNAME].pOldProc)(name);
|
|
|
|
return hp;
|
|
}
|
|
|
|
int WINAPI new_connect(
|
|
SOCKET s,
|
|
const struct sockaddr FAR *name,
|
|
int namelen
|
|
)
|
|
{
|
|
dprintf("[connect] socket(0x%08X) host(%s) port(%d)\n", s, inet_ntoa(((struct sockaddr_in *)name)->sin_addr), ntohs(((struct sockaddr_in *)name)->sin_port));
|
|
|
|
return ((int (WINAPI *)(SOCKET, const struct sockaddr FAR *, int))pAPIHooks[(int)APIHOOK_CONNECT].pOldProc)(s, name, namelen);
|
|
}
|
|
|
|
int WINAPI new_recv(
|
|
SOCKET s,
|
|
char *buf,
|
|
int len,
|
|
int flags
|
|
)
|
|
{
|
|
//dprintf("[recv] socket(0x%08X)\n", s);
|
|
|
|
int nRes = 0;
|
|
{
|
|
nRes = ((int (WINAPI *)(SOCKET, char *, int, int))pAPIHooks[APIHOOK_RECV].pOldProc)(s, buf, len, flags);
|
|
}
|
|
/*
|
|
for (int j = 0; j < nRes; j += 16)
|
|
{
|
|
for (int k = 0; k < 16; k++)
|
|
{
|
|
if ((j + k) < nRes)
|
|
{
|
|
dprintf("%02x ", (unsigned char)buf[j+k]);
|
|
}
|
|
else
|
|
{
|
|
dprintf(" ");
|
|
}
|
|
}
|
|
|
|
for (int k = 0; k < 16 && (j + k) < nRes; k++)
|
|
{
|
|
dprintf("%c", ((unsigned char)buf[j+k] >= 0x20 && (unsigned char)buf[j+k] <= 0x7E) ? (unsigned char)buf[j+k] : '.');
|
|
}
|
|
|
|
dprintf("\n");
|
|
}
|
|
*/
|
|
return nRes;
|
|
}
|
|
|
|
int WINAPI new_recvfrom(
|
|
SOCKET s,
|
|
char *buf,
|
|
int len,
|
|
int flags,
|
|
struct sockaddr *from,
|
|
int *fromlen
|
|
)
|
|
{
|
|
int nRes = 0;
|
|
WORD wSeq = 0;
|
|
int zerolen = 0;
|
|
static char zerobuf[8192];
|
|
bool bZerocoded = false;
|
|
CServer *server = NULL;
|
|
CSequence *sequence = NULL;
|
|
|
|
nRes = ((int (WINAPI *)(SOCKET, char *, int, int, struct sockaddr *, int *))pAPIHooks[APIHOOK_RECVFROM].pOldProc)(s, buf, len, flags, from, fromlen);
|
|
|
|
// !!!
|
|
//return nRes;
|
|
|
|
if (nRes > 0)
|
|
{
|
|
//dprintf("Receiving %u bytes\n", nRes);
|
|
|
|
// Get packet sequence number
|
|
memcpy(&wSeq, &buf[2], sizeof(wSeq));
|
|
wSeq = htons(wSeq);
|
|
|
|
// Get current server
|
|
server = servers.FindServer((struct sockaddr_in *)from);
|
|
|
|
// If server isn't in our list add it as new
|
|
if (!server)
|
|
{
|
|
server = new CServer((struct sockaddr_in *)from);
|
|
servers.AddServer(server);
|
|
}
|
|
|
|
// Handle packet acks
|
|
BYTE bAppended[4096];
|
|
int nAppendedLen = 0;
|
|
|
|
if (buf[0] & MSG_APPENDED_ACKS)
|
|
{
|
|
//dprintf("APPENDED ACKS\n");
|
|
|
|
BYTE cPacketsItems = buf[nRes - 1];
|
|
|
|
int nOldRes = nRes;
|
|
|
|
nRes = nOldRes - 1 - (cPacketsItems * sizeof(DWORD));
|
|
//dprintf("NEW AND OLD: %d / %d\n", nRes, nOldRes);
|
|
nAppendedLen = nOldRes - nRes;
|
|
memcpy(bAppended, &buf[nRes], nAppendedLen);
|
|
}
|
|
zerolen = ZeroDecode(buf, nRes, zerobuf, sizeof(zerobuf));
|
|
|
|
if ((unsigned char)buf[4] != 0xff)
|
|
{
|
|
// High
|
|
//dprintf("parse high: %hu\n", zerobuf[4]);
|
|
|
|
bool bCmdFound = false;
|
|
|
|
for (int j = 0; pCMDHooks[j].szCommand; j++)
|
|
{
|
|
if (_tcsicmp(cmds_high[zerobuf[4]].lpszCmd, pCMDHooks[j].szCommand) == 0 && pCMDHooks[j].pProc != NULL && !IsBadCodePtr(pCMDHooks[j].pProc))
|
|
{
|
|
bCmdFound = true;
|
|
((void (WINAPI *)(LPCOMMAND, CServer *, char *, int *, int))pCMDHooks[j].pProc)(&cmds_high[zerobuf[4]], server, zerobuf, &zerolen, 5);
|
|
break;
|
|
}
|
|
}
|
|
|
|
if (!bCmdFound)
|
|
{
|
|
((void (WINAPI *)(LPCOMMAND, CServer *, char *, int *, int))pCMDHooks[0].pProc)(&cmds_high[zerobuf[4]], server, zerobuf, &zerolen, 5);
|
|
}
|
|
}
|
|
|
|
else if ((unsigned char)buf[5] != 0xff)
|
|
{
|
|
// Medium
|
|
//dprintf("parse med: %hu\n", zerobuf[5]);
|
|
|
|
bool bCmdFound = false;
|
|
|
|
for (int j = 0; pCMDHooks[j].szCommand; j++)
|
|
{
|
|
if (!_tcsicmp(cmds_med[zerobuf[5]].lpszCmd, pCMDHooks[j].szCommand) && pCMDHooks[j].pProc != NULL && !IsBadCodePtr(pCMDHooks[j].pProc))
|
|
{
|
|
bCmdFound = true;
|
|
((void (WINAPI *)(LPCOMMAND, CServer *, char *, int *, int))pCMDHooks[j].pProc)(&cmds_med[zerobuf[5]], server, zerobuf, &zerolen, 6);
|
|
break;
|
|
}
|
|
}
|
|
|
|
if (!bCmdFound)
|
|
{
|
|
((void (WINAPI *)(LPCOMMAND, CServer *, char *, int *, int))pCMDHooks[0].pProc)(&cmds_med[zerobuf[5]], server, zerobuf, &zerolen, 6);
|
|
}
|
|
}
|
|
|
|
else if ((unsigned char)buf[4] == 0xff && (unsigned char)buf[5] == 0xff)
|
|
{
|
|
// Fixed
|
|
// Low
|
|
|
|
//dprintf("parse low: %hu\n", htons(wFreq));
|
|
|
|
bool bCmdFound = false;
|
|
WORD wFreq;
|
|
memcpy(&wFreq, &zerobuf[6], sizeof(wFreq));
|
|
|
|
for (int j = 0; pCMDHooks[j].szCommand; j++)
|
|
{
|
|
if (!_tcsicmp(cmds_low[htons(wFreq)].lpszCmd, pCMDHooks[j].szCommand) && pCMDHooks[j].pProc != NULL && !IsBadCodePtr(pCMDHooks[j].pProc))
|
|
{
|
|
bCmdFound = true;
|
|
((void (WINAPI *)(LPCOMMAND, CServer *, char *, int *, int))pCMDHooks[j].pProc)(&cmds_low[htons(wFreq)], server, zerobuf, &zerolen, 8);
|
|
break;
|
|
}
|
|
}
|
|
|
|
if (!bCmdFound)
|
|
{
|
|
((void (WINAPI *)(LPCOMMAND, CServer *, char *, int *, int))pCMDHooks[0].pProc)(&cmds_low[htons(wFreq)], server, zerobuf, &zerolen, 8);
|
|
}
|
|
}
|
|
|
|
nRes = ZeroEncode(zerobuf, zerolen, buf, len);
|
|
|
|
if (nAppendedLen > 0)
|
|
{
|
|
memcpy(&buf[nRes], bAppended, nAppendedLen);
|
|
nRes += nAppendedLen;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
// We can use this area to synthesize incoming packets
|
|
}
|
|
|
|
return nRes;
|
|
}
|
|
|
|
int WINAPI new_send(
|
|
SOCKET s,
|
|
const char *buf,
|
|
int len,
|
|
int flags
|
|
)
|
|
{
|
|
// dprintf("[send] socket(0x%08X)\n", s);
|
|
|
|
int nRes = 0;
|
|
{
|
|
nRes = ((int (WINAPI *)(SOCKET, const char *, int, int))pAPIHooks[APIHOOK_SEND].pOldProc)(s, buf, len, flags);
|
|
}
|
|
|
|
return nRes;
|
|
}
|
|
|
|
int WINAPI new_sendto(
|
|
SOCKET s,
|
|
char *buf,
|
|
int len,
|
|
int flags,
|
|
struct sockaddr *to,
|
|
int tolen
|
|
)
|
|
{
|
|
int nRes = 0;
|
|
WORD wSeq = 0;
|
|
int zerolen = 0;
|
|
char *zerobuf = NULL;
|
|
bool bZerocoded = false;
|
|
CServer *server = NULL;
|
|
CSequence *sequence = NULL;
|
|
|
|
// Get packet sequence number
|
|
memcpy(&wSeq, &buf[2], sizeof(wSeq));
|
|
wSeq = htons(wSeq);
|
|
|
|
// Get current server
|
|
server = servers.FindServer((struct sockaddr_in *)to);
|
|
|
|
// If server isn't in our list add it as new
|
|
if (!server)
|
|
{
|
|
server = new CServer((struct sockaddr_in *)to);
|
|
servers.AddServer(server);
|
|
}
|
|
|
|
static int nDropPacket = 0;
|
|
|
|
if (buf[0] & MSG_ZEROCODED)
|
|
{
|
|
bZerocoded = true;
|
|
zerolen = 4;
|
|
|
|
for (int i = 4; i < len; i++)
|
|
{
|
|
if ((unsigned char)buf[i] == 0x00)
|
|
zerolen += (unsigned char)buf[++i];
|
|
else
|
|
zerolen++;
|
|
}
|
|
|
|
zerobuf = (char *)malloc(zerolen);
|
|
|
|
if (!zerobuf)
|
|
{
|
|
dprintf("Couldn't allocate memory for zerocoded buffer\n");
|
|
return -1;
|
|
}
|
|
|
|
int j = 4;
|
|
memcpy(zerobuf, buf, 4);
|
|
|
|
for (int i = 4; i < len; i++)
|
|
{
|
|
if ((unsigned char)buf[i] == 0x00)
|
|
{
|
|
for (int z = 0; z < (unsigned char)buf[i+1]; z++)
|
|
zerobuf[j++] = 0x00;
|
|
|
|
i++;
|
|
}
|
|
else
|
|
zerobuf[j++] = buf[i];
|
|
}
|
|
}
|
|
else
|
|
{
|
|
zerolen = len;
|
|
zerobuf = buf;
|
|
}
|
|
|
|
nRes = ((int (WINAPI *)(SOCKET, char *, int, int, struct sockaddr *, int))pAPIHooks[APIHOOK_SENDTO].pOldProc)(s, buf, len, flags, to, tolen);
|
|
|
|
// !!!
|
|
//return nRes;
|
|
|
|
//dprintf("Sending %u bytes\n", nRes);
|
|
|
|
if ((unsigned char)buf[4] != 0xff)
|
|
{
|
|
// High
|
|
//dprintf("parse high: %hu\n", zerobuf[4]);
|
|
|
|
bool bCmdFound = false;
|
|
|
|
for (int j = 0; pCMDHooks[j].szCommand; j++)
|
|
{
|
|
if (_tcsicmp(cmds_high[zerobuf[4]].lpszCmd, pCMDHooks[j].szCommand) == 0 && pCMDHooks[j].pProc != NULL && !IsBadCodePtr(pCMDHooks[j].pProc))
|
|
{
|
|
bCmdFound = true;
|
|
((void (WINAPI *)(LPCOMMAND, CServer *, char *, int *, int))pCMDHooks[j].pProc)(&cmds_high[zerobuf[4]], server, zerobuf, &zerolen, 5);
|
|
break;
|
|
}
|
|
}
|
|
|
|
if (!bCmdFound)
|
|
{
|
|
((void (WINAPI *)(LPCOMMAND, CServer *, char *, int *, int))pCMDHooks[0].pProc)(&cmds_high[zerobuf[4]], server, zerobuf, &zerolen, 5);
|
|
}
|
|
}
|
|
|
|
else if ((unsigned char)buf[5] != 0xff)
|
|
{
|
|
// Medium
|
|
//dprintf("parse med: %hu\n", zerobuf[5]);
|
|
|
|
bool bCmdFound = false;
|
|
|
|
for (int j = 0; pCMDHooks[j].szCommand; j++)
|
|
{
|
|
if (!_tcsicmp(cmds_med[zerobuf[5]].lpszCmd, pCMDHooks[j].szCommand) && pCMDHooks[j].pProc != NULL && !IsBadCodePtr(pCMDHooks[j].pProc))
|
|
{
|
|
bCmdFound = true;
|
|
((void (WINAPI *)(LPCOMMAND, CServer *, char *, int *, int))pCMDHooks[j].pProc)(&cmds_med[zerobuf[5]], server, zerobuf, &zerolen, 6);
|
|
break;
|
|
}
|
|
}
|
|
|
|
if (!bCmdFound)
|
|
{
|
|
((void (WINAPI *)(LPCOMMAND, CServer *, char *, int *, int))pCMDHooks[0].pProc)(&cmds_med[zerobuf[5]], server, zerobuf, &zerolen, 6);
|
|
}
|
|
}
|
|
|
|
else if ((unsigned char)buf[4] == 0xff && (unsigned char)buf[5] == 0xff)
|
|
{
|
|
// Fixed
|
|
// Low
|
|
|
|
//dprintf("parse low: %hu\n", htons(wFreq));
|
|
|
|
bool bCmdFound = false;
|
|
WORD wFreq;
|
|
memcpy(&wFreq, &zerobuf[6], sizeof(wFreq));
|
|
|
|
for (int j = 0; pCMDHooks[j].szCommand; j++)
|
|
{
|
|
if (!_tcsicmp(cmds_low[htons(wFreq)].lpszCmd, pCMDHooks[j].szCommand) && pCMDHooks[j].pProc != NULL && !IsBadCodePtr(pCMDHooks[j].pProc))
|
|
{
|
|
bCmdFound = true;
|
|
((void (WINAPI *)(LPCOMMAND, CServer *, char *, int *, int))pCMDHooks[j].pProc)(&cmds_low[htons(wFreq)], server, zerobuf, &zerolen, 8);
|
|
break;
|
|
}
|
|
}
|
|
|
|
if (!bCmdFound)
|
|
{
|
|
((void (WINAPI *)(LPCOMMAND, CServer *, char *, int *, int))pCMDHooks[0].pProc)(&cmds_low[htons(wFreq)], server, zerobuf, &zerolen, 8);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
dprintf("[sendto] *** UNKNOWN FREQUENCY TYPE ***\n", s);
|
|
int i, j;
|
|
|
|
for (i = 0; i < len + 16; i += 16)
|
|
{
|
|
for (j = 0; j < 16; j++)
|
|
{
|
|
if ((i + j) < len)
|
|
{
|
|
dprintf("%02x ", (unsigned char)buf[i+j]);
|
|
}
|
|
else
|
|
{
|
|
dprintf(" ");
|
|
}
|
|
}
|
|
|
|
for (j = 0; j < 16 && (i + j) < len; j++)
|
|
{
|
|
dprintf("%c", isprint(buf[i+j]) ? (unsigned char)buf[i+j] : '.');
|
|
}
|
|
|
|
dprintf("\n");
|
|
}
|
|
|
|
dprintf("\n");
|
|
}
|
|
|
|
if (bZerocoded && zerobuf)
|
|
free(zerobuf);
|
|
|
|
return nRes;
|
|
}
|
|
|
|
/*
|
|
LONG WINAPI new_SetWindowLongA(
|
|
HWND hWnd,
|
|
int nIndex,
|
|
LONG dwNewLong
|
|
)
|
|
{
|
|
LONG nRes = 0;
|
|
|
|
if (nIndex == GWL_WNDPROC && g_pMainFrm && hWnd == g_pMainFrm->m_hWnd)
|
|
{
|
|
dprintf(_T("[SetWindowLongA] %08x [%x] = "), hWnd, dwNewLong);
|
|
|
|
nRes = ((LONG (WINAPI *)(HWND, int, LONG))pAPIHooks[APIHOOK_SETWINDOWLONGA].pOldProc)(hWnd, nIndex, dwNewLong);
|
|
|
|
dprintf(_T("[%x]\n"), nRes);
|
|
}
|
|
else
|
|
{
|
|
if (nIndex == GWL_WNDPROC)
|
|
dprintf(_T("[SetWindowLongA] %08x [%x]\n"), hWnd, dwNewLong);
|
|
|
|
nRes = ((LONG (WINAPI *)(HWND, int, LONG))pAPIHooks[APIHOOK_SETWINDOWLONGA].pOldProc)(hWnd, nIndex, dwNewLong);
|
|
}
|
|
|
|
return nRes;
|
|
}
|
|
|
|
LONG WINAPI new_SetWindowLongW(
|
|
HWND hWnd,
|
|
int nIndex,
|
|
LONG dwNewLong
|
|
)
|
|
{
|
|
LONG nRes = 0;
|
|
|
|
if (nIndex == GWL_WNDPROC)
|
|
{
|
|
dprintf(_T("[SetWindowLongW] %08x\n"), hWnd);
|
|
|
|
nRes = ((LONG (WINAPI *)(HWND, int, LONG))pAPIHooks[APIHOOK_SETWINDOWLONGW].pOldProc)(hWnd, nIndex, dwNewLong);
|
|
}
|
|
else
|
|
{
|
|
nRes = ((LONG (WINAPI *)(HWND, int, LONG))pAPIHooks[APIHOOK_SETWINDOWLONGW].pOldProc)(hWnd, nIndex, dwNewLong);
|
|
}
|
|
|
|
return nRes;
|
|
}
|
|
*/
|
|
BOOL WINAPI new_InternetReadFile(
|
|
IN HINTERNET hFile,
|
|
IN LPVOID lpBuffer,
|
|
IN DWORD dwNumberOfBytesToRead,
|
|
OUT LPDWORD lpNumberOfBytesRead
|
|
)
|
|
{
|
|
BOOL bRes = FALSE;
|
|
|
|
bRes = ((BOOL (WINAPI *)(HINTERNET, LPVOID, DWORD, LPDWORD))pAPIHooks[APIHOOK_INTERNETREADFILE].pOldProc)(hFile, lpBuffer, dwNumberOfBytesToRead, lpNumberOfBytesRead);
|
|
|
|
dprintf(_T("[InternetReadFile] [%s] %d\n"), lpBuffer, *lpNumberOfBytesRead);
|
|
|
|
return bRes;
|
|
}
|
|
|
|
HINTERNET WINAPI new_InternetOpenUrlA(
|
|
HINTERNET hInternet,
|
|
LPCTSTR lpszUrl,
|
|
LPCTSTR lpszHeaders,
|
|
DWORD dwHeadersLength,
|
|
DWORD dwFlags,
|
|
DWORD_PTR dwContext
|
|
)
|
|
{
|
|
HINTERNET hNet = 0;
|
|
|
|
dprintf(_T("[InternetOpenUrlA] [%s][%s]\n"), lpszUrl, lpszHeaders);
|
|
|
|
hNet = ((HINTERNET (WINAPI *)(HINTERNET, LPCTSTR, LPCTSTR, DWORD, DWORD, DWORD_PTR))pAPIHooks[APIHOOK_INTERNETOPENURLA].pOldProc)(hInternet, lpszUrl, lpszHeaders, dwHeadersLength, dwFlags, dwContext);
|
|
|
|
return hNet;
|
|
}
|
|
|
|
BOOL WINAPI new_CPEncrypt(
|
|
HCRYPTPROV hProv,
|
|
HCRYPTKEY hKey,
|
|
HCRYPTHASH hHash,
|
|
BOOL Final,
|
|
DWORD dwFlags,
|
|
BYTE* pbData,
|
|
DWORD* pdwDataLen,
|
|
DWORD dwBufLen
|
|
)
|
|
{
|
|
BOOL bRes = FALSE;
|
|
|
|
bRes = ((BOOL (WINAPI *)(HCRYPTPROV, HCRYPTKEY, HCRYPTHASH, BOOL, DWORD, BYTE *, DWORD *, DWORD))pAPIHooks[APIHOOK_CPENCRYPT].pOldProc)(hProv, hKey, hHash, Final, dwFlags, pbData, pdwDataLen, dwBufLen);
|
|
|
|
TCHAR szStr[2048];
|
|
ZeroMemory(szStr, sizeof(szStr));
|
|
memcpy(szStr, pbData, sizeof(szStr));
|
|
|
|
dprintf(_T("[CPEncrypt] [%s] %d\n"), szStr, 0);
|
|
|
|
return bRes;
|
|
}
|
|
|
|
BOOL WINAPI new_PeekMessageA(
|
|
LPMSG lpMsg, // pointer to structure for message
|
|
HWND hWnd, // handle to window
|
|
UINT wMsgFilterMin, // first message
|
|
UINT wMsgFilterMax, // last message
|
|
UINT wRemoveMsg // removal flags
|
|
)
|
|
{
|
|
//dprintf(_T("[PeekMessageA] [%x]\n"), hWnd);
|
|
|
|
BOOL bRes = FALSE;
|
|
static UINT uiAntiIdle = 0;
|
|
|
|
bRes = ((BOOL (WINAPI *)(LPMSG, HWND, UINT, UINT, UINT))pAPIHooks[APIHOOK_PEEKMESSAGEA].pOldProc)(lpMsg, hWnd, wMsgFilterMin, wMsgFilterMax, wRemoveMsg);
|
|
|
|
if (!bRes && GetFocus() == NULL)
|
|
{
|
|
// Wait for any message sent or posted to this queue
|
|
DWORD dwResult = MsgWaitForMultipleObjects(0, NULL, FALSE, 1000, QS_ALLINPUT);
|
|
|
|
uiAntiIdle++;
|
|
|
|
if (uiAntiIdle > 4)
|
|
{
|
|
//dprintf(_T("idle.. %d\n"), uiAntiIdle);
|
|
if (g_pMainFrm)
|
|
{
|
|
//dprintf(_T("sending anti.. idle...\n"));
|
|
PostMessage(g_pMainFrm->m_hWnd, WM_MOUSEMOVE, 0, MAKEWORD(10, 10));
|
|
}
|
|
|
|
uiAntiIdle = 0;
|
|
}
|
|
}
|
|
|
|
static UINT uiAutoPilot = 0;
|
|
|
|
if (g_pMainFrm)
|
|
{
|
|
//uiAutoPilot++;
|
|
|
|
if (uiAutoPilot > 200)
|
|
{
|
|
WORD wRepeatCount = 1;
|
|
LPARAM lParam = MAKELPARAM(wRepeatCount, 0);
|
|
|
|
lParam |= 1 << 24;
|
|
lParam |= 0 << 29;
|
|
lParam |= 1 << 30;
|
|
lParam |= 0 << 31;
|
|
|
|
//PostMessage(g_pMainFrm->m_hWnd, WM_KEYDOWN, VK_UP, lParam);
|
|
|
|
lParam |= 0 << 24;
|
|
//PostMessage(g_pMainFrm->m_hWnd, WM_KEYDOWN, 'E', 0);
|
|
|
|
char sc = 0;
|
|
sc = MapVirtualKey('E', 0);
|
|
|
|
for (int k = 0; k < 90; k++)
|
|
PostMessage(g_pMainFrm->m_hWnd, WM_KEYDOWN, 'E', 1 | (1 << 30) | (sc << 16));
|
|
|
|
//PostMessage(g_pMainFrm->m_hWnd, WM_KEYUP, 'E', 1 | (3 << 30) | (sc << 16));
|
|
|
|
uiAutoPilot = 0;
|
|
}
|
|
}
|
|
|
|
return bRes;
|
|
}
|
|
|
|
VOID WINAPI new_glEnable(
|
|
GLenum cap
|
|
)
|
|
{
|
|
dprintf(_T("[glEnable] [0x%08x]\n"), cap);
|
|
|
|
// if (cap != GL_TEXTURE_2D)
|
|
((VOID (WINAPI *)(GLenum))pAPIHooks[APIHOOK_GLENABLE].pOldProc)(cap);
|
|
// else
|
|
// glDisable(GL_TEXTURE_2D);
|
|
}
|
|
|
|
GLboolean WINAPI new_glIsEnabled(
|
|
GLenum cap
|
|
)
|
|
{
|
|
// if (cap == GL_TEXTURE_2D)
|
|
// return GL_TRUE;
|
|
|
|
return ((GLboolean (WINAPI *)(GLenum))pAPIHooks[APIHOOK_GLISENABLED].pOldProc)(cap);
|
|
}
|
|
|
|
VOID WINAPI new_glTranslatef(
|
|
GLfloat x,
|
|
GLfloat y,
|
|
GLfloat z
|
|
)
|
|
{
|
|
dprintf(_T("[glTranslatef]\n"));
|
|
((VOID (WINAPI *)(GLfloat, GLfloat, GLfloat))pAPIHooks[APIHOOK_GLTRANSLATEF].pOldProc)(x, y, z);
|
|
}
|
|
|
|
VOID WINAPI new_glTranslated(
|
|
GLdouble x,
|
|
GLdouble y,
|
|
GLdouble z
|
|
)
|
|
{
|
|
dprintf(_T("[glTranslated]\n"));
|
|
((VOID (WINAPI *)(GLdouble, GLdouble, GLdouble))pAPIHooks[APIHOOK_GLTRANSLATED].pOldProc)(x, y, z);
|
|
}
|
|
|
|
VOID WINAPI new_glTexCoord2f(
|
|
GLfloat s,
|
|
GLfloat t
|
|
)
|
|
{
|
|
((VOID (WINAPI *)(GLfloat, GLfloat))pAPIHooks[APIHOOK_GLTEXCOORD2F].pOldProc)(s, t);
|
|
}
|
|
|
|
VOID WINAPI new_glVertex2f(
|
|
GLfloat x,
|
|
GLfloat y
|
|
)
|
|
{
|
|
dprintf("[glVertex2f]\n");
|
|
((VOID (WINAPI *)(GLfloat, GLfloat))pAPIHooks[APIHOOK_GLVERTEX2F].pOldProc)(x, y);
|
|
}
|
|
|
|
VOID WINAPI new_glVertex3f(
|
|
GLfloat x,
|
|
GLfloat y,
|
|
GLfloat z
|
|
)
|
|
{
|
|
dprintf("[glVertex3f]\n");
|
|
((VOID (WINAPI *)(GLfloat, GLfloat, GLfloat))pAPIHooks[APIHOOK_GLVERTEX3F].pOldProc)(x, y, z);
|
|
}
|
|
|
|
// Moves floating name tags
|
|
VOID WINAPI new_glVertex3fv(
|
|
GLfloat *v
|
|
)
|
|
{
|
|
dprintf("[glVertex3fv]\n");
|
|
((VOID (WINAPI *)(const GLfloat *v))pAPIHooks[APIHOOK_GLVERTEX3FV].pOldProc)(v);
|
|
}
|
|
|
|
VOID WINAPI new_glVertex4f(
|
|
GLfloat x,
|
|
GLfloat y,
|
|
GLfloat z,
|
|
GLfloat w
|
|
)
|
|
{
|
|
dprintf("[glVertex4f]\n");
|
|
((VOID (WINAPI *)(GLfloat, GLfloat, GLfloat, GLfloat))pAPIHooks[APIHOOK_GLVERTEX4F].pOldProc)(x, y, z, w);
|
|
}
|
|
|
|
VOID WINAPI new_glVertex4fv(
|
|
GLfloat *v
|
|
)
|
|
{
|
|
dprintf("[glVertex4v]\n");
|
|
((VOID (WINAPI *)(const GLfloat *v))pAPIHooks[APIHOOK_GLVERTEX4FV].pOldProc)(v);
|
|
}
|
|
|
|
VOID WINAPI new_glTexCoord2fv(
|
|
GLfloat *v
|
|
)
|
|
{
|
|
((VOID (WINAPI *)(GLfloat *))pAPIHooks[APIHOOK_GLTEXCOORD2FV].pOldProc)(v);
|
|
}
|
|
|
|
VOID WINAPI new_glColor4f(
|
|
GLfloat red,
|
|
GLfloat green,
|
|
GLfloat blue,
|
|
GLfloat alpha
|
|
)
|
|
{
|
|
((VOID (WINAPI *)(GLfloat, GLfloat, GLfloat, GLfloat))pAPIHooks[APIHOOK_GLCOLOR4F].pOldProc)(red, green, blue, alpha);
|
|
}
|
|
|
|
VOID WINAPI new_glColor3f(
|
|
GLfloat red,
|
|
GLfloat green,
|
|
GLfloat blue
|
|
)
|
|
{
|
|
GLfloat alpha;
|
|
alpha = 1.0f;
|
|
|
|
((VOID (WINAPI *)(GLfloat, GLfloat, GLfloat, GLfloat))pAPIHooks[APIHOOK_GLCOLOR4F].pOldProc)(red, green, blue, alpha);
|
|
}
|
|
|
|
VOID WINAPI new_glColor4fv(
|
|
GLfloat *v
|
|
)
|
|
{
|
|
((VOID (WINAPI *)(const GLfloat *))pAPIHooks[APIHOOK_GLCOLOR4FV].pOldProc)(v);
|
|
}
|
|
|
|
VOID WINAPI new_glColor4ubv(
|
|
GLubyte *v
|
|
)
|
|
{
|
|
((VOID (WINAPI *)(const GLubyte *))pAPIHooks[APIHOOK_GLCOLOR4UBV].pOldProc)(v);
|
|
}
|
|
|
|
VOID WINAPI new_glColor3fv(
|
|
GLfloat *v
|
|
)
|
|
{
|
|
GLfloat n[4];
|
|
n[0] = v[0];
|
|
n[1] = v[1];
|
|
n[2] = v[2];
|
|
n[3] = 1.0;
|
|
|
|
((VOID (WINAPI *)(const GLfloat *))pAPIHooks[APIHOOK_GLCOLOR4FV].pOldProc)(n);
|
|
}
|
|
|
|
GLenum WINAPI new_glGetError(
|
|
void
|
|
)
|
|
{
|
|
dprintf("[glGetError] ");
|
|
GLenum error = ((GLenum (WINAPI *)(void))pAPIHooks[APIHOOK_GLGETERROR].pOldProc)();
|
|
|
|
dprintf("0x%x\n", error);
|
|
if (error == GL_INVALID_OPERATION)
|
|
return GL_NO_ERROR;
|
|
else return error;
|
|
}
|
|
|
|
VOID WINAPI new_glColorPointer(
|
|
GLint size,
|
|
GLenum type,
|
|
GLsizei stride,
|
|
const GLvoid *pointer
|
|
)
|
|
{
|
|
dprintf("[glColorPointer]\n");
|
|
((VOID (WINAPI *)(GLint, GLenum, GLsizei, const GLvoid *))pAPIHooks[APIHOOK_GLCOLORPOINTER].pOldProc)(size, type, stride, pointer);
|
|
}
|
|
|
|
// Used to render avatars and trees
|
|
VOID WINAPI new_glDrawElements(
|
|
GLenum mode,
|
|
GLsizei count,
|
|
GLenum type,
|
|
const GLvoid *indices
|
|
)
|
|
{
|
|
//glColor4f(1.0, 1.0, 1.0, 0.2);
|
|
/*glBegin(GL_QUADS);
|
|
for (int i = 0; i < 10; i++)
|
|
{
|
|
GLfloat fPosX;
|
|
GLfloat fPosY;
|
|
GLfloat fPosZ;
|
|
|
|
fPosX = (float)(rand() % 300) - 150.0f;
|
|
fPosY = -10;//(float)(rand() % 200) - 10.0f;
|
|
fPosZ = (float)(rand() % 300) - 150.0f;
|
|
|
|
glTexCoord2f(0.0, 1.0);
|
|
glVertex3f(fPosX - 4.0f, fPosY + 1.0f, fPosZ - 4.0f);
|
|
|
|
glTexCoord2f(0.0, 0.0);
|
|
glVertex3f(fPosX - 4.0f, fPosY + 1.0f, fPosZ + 4.0f);
|
|
|
|
glTexCoord2f(1.0, 0.0);
|
|
glVertex3f(fPosX + 4.0f, fPosY + 1.0f, fPosZ + 4.0f);
|
|
|
|
glTexCoord2f(1.0, 1.0);
|
|
glVertex3f(fPosX + 4.0f, fPosY + 1.0f, fPosZ - 4.0f);
|
|
|
|
}
|
|
glEnd();*/
|
|
|
|
dprintf("[glDrawElements] %d\n", count);
|
|
((VOID (WINAPI *)(GLenum, GLsizei, GLenum, const GLvoid *))pAPIHooks[APIHOOK_GLDRAWELEMENTS].pOldProc)(mode, count, type, indices);
|
|
}
|
|
|
|
VOID WINAPI new_glDrawArrays(
|
|
GLenum mode,
|
|
GLint first,
|
|
GLsizei count
|
|
)
|
|
{
|
|
dprintf("[glDrawArrays] %d\n", count);
|
|
((VOID (WINAPI *)(GLenum, GLint, GLsizei))pAPIHooks[APIHOOK_GLDRAWARRAYS].pOldProc)(mode, first, count);
|
|
}
|
|
|
|
VOID WINAPI new_glDrawPixels(
|
|
GLsizei width,
|
|
GLsizei height,
|
|
GLenum format,
|
|
GLenum type,
|
|
const GLvoid *pixels
|
|
)
|
|
{
|
|
dprintf("[glDrawPixels]\n");
|
|
((VOID (WINAPI *)(GLsizei, GLsizei, GLenum, GLenum, const GLvoid))pAPIHooks[APIHOOK_GLDRAWPIXELS].pOldProc)(width, height, format, type, pixels);
|
|
}
|
|
|
|
VOID WINAPI new_glVertexPointer(
|
|
GLint size,
|
|
GLenum type,
|
|
GLsizei stride,
|
|
const GLvoid *pointer
|
|
)
|
|
{
|
|
((VOID (WINAPI *)(GLint, GLenum, GLsizei, const GLvoid *))pAPIHooks[APIHOOK_GLVERTEXPOINTER].pOldProc)(size, type, stride, pointer);
|
|
}
|
|
|
|
VOID WINAPI new_glNormalPointer(
|
|
GLenum type,
|
|
GLsizei stride,
|
|
const GLvoid *pointer
|
|
)
|
|
{
|
|
dprintf("[glNormalPointer]\n");
|
|
((VOID (WINAPI *)(GLenum, GLsizei, const GLvoid *))pAPIHooks[APIHOOK_GLNORMALPOINTER].pOldProc)(type, stride, pointer);
|
|
}
|
|
|
|
VOID WINAPI new_glTexCoordPointer(
|
|
GLint size,
|
|
GLenum type,
|
|
GLsizei stride,
|
|
const GLvoid *pointer
|
|
)
|
|
{
|
|
((VOID (WINAPI *)(GLint, GLenum, GLsizei, const GLvoid *))pAPIHooks[APIHOOK_GLTEXCOORDPOINTER].pOldProc)(size, type, stride, pointer);
|
|
}
|
|
|
|
VOID WINAPI new_glViewport(
|
|
GLint x,
|
|
GLint y,
|
|
GLsizei width,
|
|
GLsizei height
|
|
)
|
|
{
|
|
((VOID (WINAPI *)(GLint, GLint, GLsizei, GLsizei))pAPIHooks[APIHOOK_GLVIEWPORT].pOldProc)(x, y, width, height);
|
|
}
|
|
|
|
VOID WINAPI new_glTexImage2D(
|
|
GLenum target,
|
|
GLint level,
|
|
GLint components,
|
|
GLsizei width,
|
|
GLsizei height,
|
|
GLint border,
|
|
GLenum format,
|
|
GLenum type,
|
|
const GLvoid *pixels
|
|
)
|
|
{
|
|
((VOID (WINAPI *)(GLenum, GLint, GLint, GLsizei, GLsizei, GLint, GLenum, GLenum, const GLvoid *))pAPIHooks[APIHOOK_GLTEXIMAGE2D].pOldProc)(target, level, components, width, height, border, format, type, pixels);
|
|
}
|
|
|
|
VOID WINAPI new_gluPerspective(
|
|
GLdouble fovy,
|
|
GLdouble aspect,
|
|
GLdouble zNear,
|
|
GLdouble zFar
|
|
)
|
|
{
|
|
((VOID (WINAPI *)(GLdouble, GLdouble, GLdouble, GLdouble))pAPIHooks[APIHOOK_GLUPERSPECTIVE].pOldProc)(fovy, aspect, zNear, zFar);
|
|
}
|
|
|
|
VOID WINAPI new_glBegin(
|
|
GLenum mode
|
|
)
|
|
{
|
|
((VOID (WINAPI *)(GLenum))pAPIHooks[APIHOOK_GLBEGIN].pOldProc)(mode);
|
|
}
|
|
|
|
VOID WINAPI new_glFlush(
|
|
void
|
|
)
|
|
{
|
|
((VOID (WINAPI *)(void))pAPIHooks[APIHOOK_GLFLUSH].pOldProc)();
|
|
}
|
|
|
|
VOID WINAPI new_gluQuadricDrawStyle(
|
|
GLUquadricObj * qobj,
|
|
GLenum drawStyle
|
|
)
|
|
{
|
|
((VOID (WINAPI *)(GLUquadricObj *, GLenum))pAPIHooks[APIHOOK_GLUQUADRICDRAWSTYLE].pOldProc)(qobj, drawStyle);
|
|
}
|
|
|
|
VOID WINAPI new_gluTessVertex(
|
|
GLUtesselator * tess,
|
|
GLdouble coords[3],
|
|
void * data
|
|
)
|
|
{
|
|
dprintf("[gluTessVertex]\n");
|
|
((VOID (WINAPI *)(GLUtesselator *, GLdouble[3], void *))pAPIHooks[APIHOOK_GLUTESSVERTEX].pOldProc)(tess, coords, data);
|
|
}
|
|
|
|
BOOL WINAPI new_WriteFileA(
|
|
HANDLE hFile, // handle to file to write to
|
|
LPCVOID lpBuffer, // pointer to data to write to file
|
|
DWORD nNumberOfBytesToWrite, // number of bytes to write
|
|
LPDWORD lpNumberOfBytesWritten, // pointer to number of bytes written
|
|
LPOVERLAPPED lpOverlapped // pointer to structure for overlapped I/O
|
|
)
|
|
{
|
|
return ((BOOL (WINAPI *)(HANDLE, LPCVOID, DWORD, LPDWORD, LPOVERLAPPED))pAPIHooks[APIHOOK_WRITEFILEA].pOldProc)(hFile, lpBuffer, nNumberOfBytesToWrite, lpNumberOfBytesWritten, lpOverlapped);
|
|
}
|
|
|
|
BOOL WINAPI new_DeleteFileA(
|
|
LPCTSTR lpFileName // pointer to name of file to delete
|
|
)
|
|
{
|
|
dprintf("[DeleteFileA] %s\n", lpFileName);
|
|
|
|
//return TRUE;
|
|
return ((BOOL (WINAPI *)(LPCTSTR))pAPIHooks[APIHOOK_DELETEFILEA].pOldProc)(lpFileName);
|
|
}
|
|
|
|
int WINAPI new_lstrcmpiA(
|
|
LPCTSTR lpString1, // pointer to first string
|
|
LPCTSTR lpString2 // pointer to second string
|
|
)
|
|
{
|
|
//dprintf("[lstrcmpiA] %s <> %s\n", lpString1, lpString2);
|
|
return ((int (WINAPI *)(LPCTSTR, LPCTSTR))pAPIHooks[APIHOOK_LSTRCMPIA].pOldProc)(lpString1, lpString2);
|
|
}
|
|
|
|
APIHOOK pAPIHooks[] = {
|
|
{ NULL, _T("KERNEL32.DLL"), "GetProcAddress", FALSE, NULL, (PROC)new_GetProcAddress },
|
|
{ NULL, _T("KERNEL32.DLL"), "LoadLibraryA", FALSE, NULL, (PROC)new_LoadLibraryA },
|
|
{ NULL, _T("KERNEL32.DLL"), "LoadLibraryW", FALSE, NULL, (PROC)new_LoadLibraryW },
|
|
{ NULL, _T("KERNEL32.DLL"), "LoadLibraryExA", FALSE, NULL, (PROC)new_LoadLibraryExA },
|
|
{ NULL, _T("KERNEL32.DLL"), "LoadLibraryExW", FALSE, NULL, (PROC)new_LoadLibraryExW },
|
|
{ NULL, _T("KERNEL32.DLL"), "FreeLibraryA", FALSE, NULL, (PROC)new_FreeLibraryA },
|
|
{ NULL, _T("KERNEL32.DLL"), "DeleteFileA", FALSE, NULL, (PROC)new_DeleteFileA },
|
|
{ NULL, _T("XKERNEL32.DLL"), "WriteFileA", FALSE, NULL, (PROC)new_WriteFileA },
|
|
{ NULL, _T("XKERNEL32.DLL"), "lstrcmpiA", FALSE, NULL, (PROC)new_lstrcmpiA },
|
|
{ NULL, _T("WS2_32.DLL"), (LPCSTR)4, TRUE, NULL, (PROC)new_connect },
|
|
{ NULL, _T("WS2_32.DLL"), (LPCSTR)16, TRUE, NULL, (PROC)new_recv },
|
|
{ NULL, _T("WS2_32.DLL"), (LPCSTR)17, TRUE, NULL, (PROC)new_recvfrom },
|
|
{ NULL, _T("WS2_32.DLL"), (LPCSTR)19, TRUE, NULL, (PROC)new_send },
|
|
{ NULL, _T("WS2_32.DLL"), (LPCSTR)20, TRUE, NULL, (PROC)new_sendto },
|
|
{ NULL, _T("WS2_32.DLL"), (LPCSTR)52, TRUE, NULL, (PROC)new_gethostbyname },
|
|
// { NULL, _T("USER32.DLL"), "SetWindowLongA", FALSE, NULL, (PROC)new_SetWindowLongA },
|
|
// { NULL, _T("USER32.DLL"), "SetWindowLongW", FALSE, NULL, (PROC)new_SetWindowLongW },
|
|
{ NULL, _T("WININET.DLL"), "InternetReadFile", FALSE, NULL, (PROC)new_InternetReadFile },
|
|
{ NULL, _T("WININET.DLL"), "InternetOpenUrlA", FALSE, NULL, (PROC)new_InternetOpenUrlA },
|
|
{ NULL, _T("RSAENH.DLL"), "CPEncrypt", FALSE, NULL, (PROC)new_CPEncrypt },
|
|
{ NULL, _T("USER32.DLL"), "PeekMessageA", FALSE, NULL, (PROC)new_PeekMessageA },
|
|
// { NULL, _T("UNCOMMENT"/*"OPENGL32.DLL"*/), "glGetError", FALSE, NULL, (PROC)new_glGetError },
|
|
// { NULL, _T("UNCOMMENT"/*"OPENGL32.DLL"*/), "glBegin", FALSE, NULL, (PROC)new_glBegin },
|
|
// { NULL, _T("UNCOMMENT"/*"OPENGL32.DLL"*/), "glEnable", FALSE, NULL, (PROC)new_glEnable },
|
|
// { NULL, _T("UNCOMMENT"/*"OPENGL32.DLL"*/), "glIsEnabled", FALSE, NULL, (PROC)new_glIsEnabled },
|
|
// { NULL, _T("UNCOMMENT"/*"OPENGL32.DLL"*/), "glTranslated", FALSE, NULL, (PROC)new_glTranslated },
|
|
// { NULL, _T("UNCOMMENT"/*"OPENGL32.DLL"*/), "glTranslatef", FALSE, NULL, (PROC)new_glTranslatef },
|
|
// { NULL, _T("UNCOMMENT"/*"OPENGL32.DLL"*/), "glTexCoord2f", FALSE, NULL, (PROC)new_glTexCoord2f },
|
|
// { NULL, _T("UNCOMMENT"/*"OPENGL32.DLL"*/), "glTexCoord2fv", FALSE, NULL, (PROC)new_glTexCoord2fv },
|
|
// { NULL, _T("UNCOMMENT"/*"OPENGL32.DLL"*/), "glVertex2f", FALSE, NULL, (PROC)new_glVertex2f },
|
|
// { NULL, _T("UNCOMMENT"/*"OPENGL32.DLL"*/), "glVertex3f", FALSE, NULL, (PROC)new_glVertex3f },
|
|
// { NULL, _T("UNCOMMENT"/*"OPENGL32.DLL"*/), "glVertex3fv", FALSE, NULL, (PROC)new_glVertex3fv },
|
|
// { NULL, _T("UNCOMMENT"/*"OPENGL32.DLL"*/), "glVertex4f", FALSE, NULL, (PROC)new_glVertex4f },
|
|
// { NULL, _T("UNCOMMENT"/*"OPENGL32.DLL"*/), "glVertex4fv", FALSE, NULL, (PROC)new_glVertex4fv },
|
|
// { NULL, _T("UNCOMMENT"/*"OPENGL32.DLL"*/), "glVertexPointer", FALSE, NULL, (PROC)new_glVertexPointer },
|
|
// { NULL, _T("UNCOMMENT"/*"OPENGL32.DLL"*/), "glTexCoordPointer", FALSE, NULL, (PROC)new_glTexCoordPointer },
|
|
// { NULL, _T("UNCOMMENT"/*"OPENGL32.DLL"*/), "glNormalPointer", FALSE, NULL, (PROC)new_glNormalPointer },
|
|
// { NULL, _T("UNCOMMENT"/*"OPENGL32.DLL"*/), "glDrawElements", FALSE, NULL, (PROC)new_glDrawElements },
|
|
// { NULL, _T("UNCOMMENT"/*"OPENGL32.DLL"*/), "glDrawArrays", FALSE, NULL, (PROC)new_glDrawArrays },
|
|
// { NULL, _T("UNCOMMENT"/*"OPENGL32.DLL"*/), "glDrawPixels", FALSE, NULL, (PROC)new_glDrawPixels },
|
|
// { NULL, _T("UNCOMMENT"/*"OPENGL32.DLL"*/), "glTexImage2D", FALSE, NULL, (PROC)new_glTexImage2D },
|
|
// { NULL, _T("UNCOMMENT"/*"OPENGL32.DLL"*/), "glColor3f", FALSE, NULL, (PROC)new_glColor3f },
|
|
// { NULL, _T("UNCOMMENT"/*"OPENGL32.DLL"*/), "glColor3fv", FALSE, NULL, (PROC)new_glColor3fv },
|
|
// { NULL, _T("UNCOMMENT"/*"OPENGL32.DLL"*/), "glColor4f", FALSE, NULL, (PROC)new_glColor4f },
|
|
// { NULL, _T("UNCOMMENT"/*"OPENGL32.DLL"*/), "glColor4fv", FALSE, NULL, (PROC)new_glColor4fv },
|
|
// { NULL, _T("UNCOMMENT"/*"OPENGL32.DLL"*/), "glColor4ubv", FALSE, NULL, (PROC)new_glColor4ubv },
|
|
// { NULL, _T("UNCOMMENT"/*"OPENGL32.DLL"*/), "glColorPointer", FALSE, NULL, (PROC)new_glColorPointer },
|
|
// { NULL, _T("UNCOMMENT"/*"OPENGL32.DLL"*/), "glViewport", FALSE, NULL, (PROC)new_glViewport },
|
|
// { NULL, _T("UNCOMMENT"/*"OPENGL32.DLL"*/), "glFlush", FALSE, NULL, (PROC)new_glFlush },
|
|
// { NULL, _T("UNCOMMENT"/*"GLU32.DLL"*/), "gluPerspective", FALSE, NULL, (PROC)new_gluPerspective },
|
|
// { NULL, _T("UNCOMMENT"/*"GLU32.DLL"*/), "gluQuadricDrawStyle", FALSE, NULL, (PROC)new_gluQuadricDrawStyle },
|
|
// { NULL, _T("UNCOMMENT"/*"GLU32.DLL"*/), "gluTessVertex", FALSE, NULL, (PROC)new_gluTessVertex },
|
|
{ NULL, NULL, NULL, FALSE, NULL, NULL }
|
|
};
|
|
|
|
PROC HookModuleImport(HMODULE hModule, LPCTSTR szModule, LPCSTR szImport, PROC pNewProc, BOOL bOrdinal)
|
|
{
|
|
PIMAGE_DOS_HEADER pDOSHeader = (PIMAGE_DOS_HEADER)hModule;
|
|
|
|
if (IsBadReadPtr(pDOSHeader, sizeof(IMAGE_DOS_HEADER)) || pDOSHeader->e_magic != IMAGE_DOS_SIGNATURE)
|
|
{
|
|
SetLastErrorEx(ERROR_INVALID_PARAMETER, SLE_ERROR);
|
|
return NULL;
|
|
}
|
|
|
|
PIMAGE_NT_HEADERS pNTHeader = MAKEPTR (PIMAGE_NT_HEADERS, pDOSHeader, pDOSHeader->e_lfanew);
|
|
if (IsBadReadPtr(pNTHeader, sizeof(IMAGE_NT_HEADERS)) || pNTHeader->Signature != IMAGE_NT_SIGNATURE)
|
|
{
|
|
SetLastErrorEx(ERROR_INVALID_PARAMETER, SLE_ERROR);
|
|
return NULL;
|
|
}
|
|
|
|
if (pNTHeader->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].Size != 0)
|
|
{
|
|
PIMAGE_IMPORT_DESCRIPTOR pImportDesc = MAKEPTR(PIMAGE_IMPORT_DESCRIPTOR, pDOSHeader, pNTHeader->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].VirtualAddress);
|
|
while (pImportDesc && pImportDesc->Name != NULL)
|
|
{
|
|
PTSTR szImportModule = MAKEPTR(PTSTR, pDOSHeader, pImportDesc->Name);
|
|
if (szImportModule != NULL && _tcsicmp(szImportModule, szModule) == 0)
|
|
{
|
|
PIMAGE_THUNK_DATA pOrigThunk = MAKEPTR(PIMAGE_THUNK_DATA, hModule, pImportDesc->OriginalFirstThunk);
|
|
PIMAGE_THUNK_DATA pRealThunk = MAKEPTR(PIMAGE_THUNK_DATA, hModule, pImportDesc->FirstThunk);
|
|
while (pOrigThunk != NULL && pRealThunk != NULL && pOrigThunk->u1.Function != NULL && pRealThunk->u1.Function)
|
|
{
|
|
PIMAGE_IMPORT_BY_NAME pByName = MAKEPTR(PIMAGE_IMPORT_BY_NAME, hModule, pOrigThunk->u1.AddressOfData);
|
|
|
|
if ((!bOrdinal && IMAGE_ORDINAL_FLAG != (pOrigThunk->u1.Ordinal & IMAGE_ORDINAL_FLAG) && pByName->Name[0] != 0 && stricmp((char*)pByName->Name, szImport) == 0) || (bOrdinal && IMAGE_ORDINAL(pOrigThunk->u1.Ordinal) == (DWORD)szImport))
|
|
{
|
|
PROC pOldProc;
|
|
|
|
/*
|
|
Retrieve memory information
|
|
*/
|
|
MEMORY_BASIC_INFORMATION mbi;
|
|
if (VirtualQuery(pRealThunk, &mbi, sizeof(MEMORY_BASIC_INFORMATION)))
|
|
{
|
|
/*
|
|
Give ourselves write access
|
|
*/
|
|
if (VirtualProtect(mbi.BaseAddress, mbi.RegionSize, PAGE_READWRITE, &mbi.Protect))
|
|
{
|
|
/*
|
|
Store old function pointer for return value
|
|
*/
|
|
pOldProc = (PROC)pRealThunk->u1.Function;
|
|
/*
|
|
Only patch import table if the new function is different than the old one
|
|
*/
|
|
if (pNewProc != NULL && pOldProc != pNewProc) pRealThunk->u1.Function = (DWORD)pNewProc;
|
|
|
|
/*
|
|
Restore old protection value
|
|
*/
|
|
DWORD dwOldProtect;
|
|
VirtualProtect(mbi.BaseAddress, mbi.RegionSize, mbi.Protect, &dwOldProtect);
|
|
}
|
|
|
|
// TCHAR szModuleFileName[MAX_PATH];
|
|
// GetModuleFileName(hModule, szModuleFileName, sizeof(szModuleFileName));
|
|
// dprintf(_T("HOOKED [%s => %s]\n"), szImport, szModuleFileName);
|
|
// return pOldProc;
|
|
}
|
|
}
|
|
pOrigThunk++;
|
|
pRealThunk++;
|
|
}
|
|
}
|
|
pImportDesc++;
|
|
}
|
|
}
|
|
|
|
return NULL;
|
|
}
|
|
|
|
///////////////////////////////////////////////////////////////////////////////////////////
|
|
//
|
|
// Retrieve the loaded modules for the specified process
|
|
//
|
|
// dwProccessID Process ID of the process whose loaded module list you wish to retrive.
|
|
// Specify 0 for the current process.
|
|
//
|
|
// pModules Pointer to an array of MODULEINFO structures to store the module list.
|
|
// Can be NULL.
|
|
//
|
|
// puiCount Specify 0 to retrieve the module count otherwise the maximum number of
|
|
// entries in the pModule array to return.
|
|
//
|
|
// Return Value
|
|
//
|
|
// Returns FALSE if failed
|
|
//
|
|
///////////////////////////////////////////////////////////////////////////////////////////
|
|
BOOL GetModuleList(DWORD dwProcessID, PMODULEENTRY32 pModules, LPUINT puiCount)
|
|
{
|
|
// dprintf(_T("[GetModuleList]\n"));
|
|
|
|
HANDLE hSnapshot;
|
|
MODULEENTRY32 cME32;
|
|
UINT uiCount = 0;
|
|
|
|
if (puiCount == NULL)
|
|
{
|
|
SetLastErrorEx(ERROR_INVALID_PARAMETER, SLE_ERROR);
|
|
return FALSE;
|
|
}
|
|
|
|
hSnapshot = CreateToolhelp32Snapshot(TH32CS_SNAPMODULE, dwProcessID);
|
|
if (hSnapshot == INVALID_HANDLE_VALUE)
|
|
{
|
|
return FALSE;
|
|
}
|
|
|
|
ZeroMemory(&cME32, sizeof(cME32));
|
|
cME32.dwSize = sizeof(MODULEENTRY32);
|
|
if (Module32First(hSnapshot, &cME32) == TRUE)
|
|
{
|
|
do
|
|
{
|
|
if (pModules != NULL && *puiCount)
|
|
{
|
|
_tcsncpy(pModules[uiCount].szModule, cME32.szModule, MAX_PATH);
|
|
pModules[uiCount].hModule = cME32.hModule;
|
|
}
|
|
uiCount++;
|
|
} while (Module32Next(hSnapshot, &cME32) == TRUE && (*puiCount == 0 || uiCount < *puiCount));
|
|
}
|
|
|
|
CloseHandle(hSnapshot);
|
|
|
|
*puiCount = uiCount;
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
///////////////////////////////////////////////////////////////////////////////////////////
|
|
//
|
|
// Save pointers to old functions
|
|
//
|
|
///////////////////////////////////////////////////////////////////////////////////////////
|
|
void SaveImportHooks()
|
|
{
|
|
// dprintf(_T("[SaveImportHooks]\n"));
|
|
|
|
INT i;
|
|
|
|
for (i = 0; pAPIHooks[i].szModule; i++)
|
|
{
|
|
/*
|
|
Only store pointers for any functions we haven't taken care of yet so this may be called multiple times
|
|
*/
|
|
if (pAPIHooks[i].pOldProc == NULL)
|
|
{
|
|
pAPIHooks[i].pOldProc = GetProcAddress(GetModuleHandle(pAPIHooks[i].szModule), (LPCSTR)pAPIHooks[i].szImport);
|
|
// dprintf(_T("Saved import for %s(%s) at 0x%08X\n"), pAPIHooks[i].szModule, pAPIHooks[i].szImport, pAPIHooks[i].pOldProc);
|
|
}
|
|
}
|
|
}
|
|
|
|
///////////////////////////////////////////////////////////////////////////////////////////
|
|
//
|
|
// Patch import table of all loaded modules
|
|
//
|
|
///////////////////////////////////////////////////////////////////////////////////////////
|
|
void InstallImportHooks()
|
|
{
|
|
// dprintf(_T("[InstallImportHooks]\n"));
|
|
|
|
/*
|
|
Retrieve number of loaded modules
|
|
*/
|
|
UINT uiCount = 0;
|
|
INT i, j;
|
|
if (GetModuleList(0, NULL, &uiCount))
|
|
{
|
|
/*
|
|
Allocate temporary table of loaded modules
|
|
*/
|
|
PMODULEENTRY32 pModules = (PMODULEENTRY32)GlobalAlloc(GMEM_FIXED | GMEM_ZEROINIT, uiCount*sizeof(MODULEENTRY32));
|
|
if (pModules != NULL)
|
|
{
|
|
/*
|
|
Retrieve table of loaded modules
|
|
*/
|
|
if (GetModuleList(0, pModules, &uiCount))
|
|
{
|
|
/*
|
|
Loop through each module and patch its import table
|
|
*/
|
|
for (i = 0; i < (INT)uiCount; i++)
|
|
{
|
|
/*
|
|
Loop through each API hook and patch import table for this module
|
|
HookModuleImport() takes care of dupe checking
|
|
*/
|
|
for (j = 0; pAPIHooks[j].szModule; j++)
|
|
{
|
|
if (_tcsicmp(pModules[i].szModule, _T("SNOWFLAKE.DLL")) && _tcsicmp(pModules[i].szModule, _T("FMOD.DLL")) && /*_tcsicmp(pModules[i].szModule, _T("NEWVIEW.EXE")) &&*/ _tcsicmp(pModules[i].szModule, pAPIHooks[j].szModule) && pAPIHooks[j].pNewProc != NULL && !IsBadCodePtr(pAPIHooks[j].pNewProc))
|
|
{
|
|
HookModuleImport(pModules[i].hModule, pAPIHooks[j].szModule, pAPIHooks[j].szImport, pAPIHooks[j].pNewProc, pAPIHooks[j].bOrdinal);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
GlobalFree(pModules);
|
|
}
|
|
}
|
|
}
|
|
|
|
///////////////////////////////////////////////////////////////////////////////////////////
|
|
//
|
|
// Removes the import table for all loaded modules back to the original saved functions
|
|
//
|
|
///////////////////////////////////////////////////////////////////////////////////////////
|
|
void RemoveImportHooks()
|
|
{
|
|
dprintf(_T("[RemoveImportHooks]\n"));
|
|
|
|
/*
|
|
Retrieve number of loaded modules
|
|
*/
|
|
UINT uiCount = 0;
|
|
INT i, j;
|
|
if (GetModuleList(0, NULL, &uiCount))
|
|
{
|
|
/*
|
|
Allocate temporary table of loaded modules
|
|
*/
|
|
PMODULEENTRY32 pModules = (PMODULEENTRY32)GlobalAlloc(GMEM_FIXED | GMEM_ZEROINIT, uiCount*sizeof(MODULEENTRY32));
|
|
if (pModules != NULL)
|
|
{
|
|
/*
|
|
Retrieve table of loaded modules
|
|
*/
|
|
if (GetModuleList(0, pModules, &uiCount))
|
|
{
|
|
/*
|
|
Loop through each module and patch its import table
|
|
*/
|
|
for (i = 0; i < (INT)uiCount; i++)
|
|
{
|
|
/*
|
|
Loop through each API hook and restore import table for this module
|
|
*/
|
|
// dprintf("RESTORE [%s]\n", pModules[i].szModule);
|
|
for (j = 0; pAPIHooks[j].szModule; j++)
|
|
{
|
|
if (_tcsicmp(pModules[i].szModule, _T("SNOWFLAKE.DLL")) && /*_tcsicmp(pModules[i].szModule, _T("NEWVIEW.EXE")) &&*/ _tcsicmp(pModules[i].szModule, pAPIHooks[j].szModule) && pAPIHooks[j].pOldProc != NULL && !IsBadCodePtr(pAPIHooks[j].pOldProc))
|
|
{
|
|
// dprintf(_T("REMOVE [%s => %s]\n"), pAPIHooks[j].szImport, pModules[i].szModule);
|
|
HookModuleImport(pModules[i].hModule, pAPIHooks[j].szModule, pAPIHooks[j].szImport, pAPIHooks[j].pOldProc, pAPIHooks[j].bOrdinal);
|
|
}
|
|
}
|
|
}
|
|
|
|
for (j = 0; pAPIHooks[j].szModule; j++)
|
|
{
|
|
pAPIHooks[j].pOldProc = NULL;
|
|
}
|
|
}
|
|
GlobalFree(pModules);
|
|
}
|
|
}
|
|
}
|
|
|
|
BOOL APIENTRY DllMain( HANDLE hModule,
|
|
DWORD ul_reason_for_call,
|
|
LPVOID lpReserved
|
|
)
|
|
{
|
|
if (ul_reason_for_call == DLL_PROCESS_ATTACH)
|
|
{
|
|
TCHAR szPath[MAX_PATH];
|
|
|
|
g_hinstDLL = (HINSTANCE)hModule;
|
|
_Module.Init(NULL, g_hinstDLL);
|
|
DisableThreadLibraryCalls(g_hinstDLL);
|
|
|
|
if (GetModuleFileName(GetModuleHandle(0), szPath, MAX_PATH))
|
|
{
|
|
_tcsupr(szPath);
|
|
|
|
if (_tcsstr(szPath, _T("\\SECONDLIFE.EXE")))
|
|
{
|
|
if (!g_pConfig)
|
|
g_pConfig = new CConfig();
|
|
|
|
#ifdef ECHO
|
|
AllocConsole();
|
|
|
|
if (!fpLog)
|
|
fpLog = fopen(g_pConfig->m_pSnowcrashTxtPath, "w");
|
|
#endif
|
|
dprintf(_T("[snowflake] %s\n"), szPath);
|
|
|
|
decomm();
|
|
|
|
SaveImportHooks();
|
|
InstallImportHooks();
|
|
}
|
|
}
|
|
} else if (ul_reason_for_call == DLL_PROCESS_DETACH)
|
|
{
|
|
RemoveSLHooks();
|
|
RemoveImportHooks();
|
|
#ifdef ECHO
|
|
FreeConsole();
|
|
|
|
if (fpLog)
|
|
{
|
|
fclose(fpLog);
|
|
fpLog = NULL;
|
|
}
|
|
#endif
|
|
_Module.Term();
|
|
}
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
LRESULT CALLBACK CBTHookProc(int nCode, WPARAM wParam, LPARAM lParam)
|
|
{
|
|
switch(nCode)
|
|
{
|
|
case HCBT_ACTIVATE:
|
|
{
|
|
if (!g_pMainFrm)
|
|
{
|
|
TCHAR szClass[128];
|
|
HWND hwnd = (HWND)wParam;
|
|
|
|
if (GetClassName(hwnd, szClass, sizeof(szClass)))
|
|
{
|
|
if (_tcsicmp(szClass, _T("Second Life")) == 0)
|
|
{
|
|
TCHAR szTitle[256];
|
|
GetWindowText(hwnd, szTitle, sizeof(szTitle));
|
|
|
|
if (_tcsstr(szTitle, "Second Life"))
|
|
{
|
|
dprintf(_T(">>> [%s][%s]\n"), szClass, szTitle);
|
|
InstallSLHooks(hwnd);
|
|
}
|
|
}
|
|
else
|
|
dprintf(_T(">>> [%s]\n"), szClass);
|
|
}
|
|
}
|
|
}
|
|
break;
|
|
|
|
case HCBT_CREATEWND:
|
|
{
|
|
TCHAR szClass[128];
|
|
HWND hwnd = (HWND)wParam;
|
|
LPCBT_CREATEWND lpcbt = (LPCBT_CREATEWND)lParam;
|
|
|
|
if (GetClassName(hwnd, szClass, sizeof(szClass)))
|
|
{
|
|
//dprintf(_T(">>> [%s]\n"), szClass);
|
|
//if (_tcsicmp(szClass, _T("OpenGL")) == 0)
|
|
//{
|
|
//dprintf(_T("[snowflake] SL window created\n"));
|
|
//InstallSLHooks(hwnd);
|
|
//}
|
|
}
|
|
}
|
|
break;
|
|
|
|
case HCBT_DESTROYWND:
|
|
{
|
|
TCHAR szClass[128];
|
|
HWND hwnd = (HWND)wParam;
|
|
|
|
if (GetClassName(hwnd, szClass, sizeof(szClass)))
|
|
{
|
|
if (g_pMainFrm && g_pMainFrm->m_hWnd == hwnd)
|
|
{
|
|
dprintf(_T("[snowflake] SL window destroyed\n"));
|
|
RemoveSLHooks();
|
|
}
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
return ::CallNextHookEx(h_hCBTHook, nCode, wParam, lParam);
|
|
}
|
|
|
|
SNOWFLAKE_API bool InstallSystemHook(void)
|
|
{
|
|
// dprintf(_T("[InstallSystemHook]\n"));
|
|
|
|
if (h_hCBTHook == NULL)
|
|
{
|
|
h_hCBTHook = ::SetWindowsHookEx(WH_CBT, CBTHookProc, g_hinstDLL, 0);
|
|
}
|
|
|
|
return (h_hCBTHook != NULL);
|
|
}
|
|
|
|
SNOWFLAKE_API BOOL RemoveSystemHook()
|
|
{
|
|
dprintf(_T("[RemoveSystemHook]\n"));
|
|
|
|
if (h_hCBTHook != NULL)
|
|
{
|
|
if (UnhookWindowsHookEx(h_hCBTHook))
|
|
{
|
|
h_hCBTHook = NULL;
|
|
|
|
return TRUE;
|
|
}
|
|
}
|
|
|
|
return FALSE;
|
|
}
|
|
|
|
bool InstallSLHooks(HWND hwnd)
|
|
{
|
|
_Module.AddMessageLoop(&g_msgLoop);
|
|
|
|
if (g_pMainFrm == NULL)
|
|
{
|
|
g_pMainFrm = new CMainFrame();
|
|
|
|
if (g_pMainFrm->SubclassWindow(hwnd))
|
|
{
|
|
return true;
|
|
}
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
bool RemoveSLHooks()
|
|
{
|
|
if (g_pMainFrm != NULL)
|
|
{
|
|
dprintf(_T("RemoveSLHooks MainFrm\n"));
|
|
if (g_pMainFrm->m_hWnd != NULL && ::IsWindow(*g_pMainFrm))
|
|
{
|
|
dprintf(_T("RemoveSLHooks MainFrm Unsub\n"));
|
|
g_pMainFrm->UnsubclassWindow(TRUE);
|
|
g_pMainFrm->m_hWnd = NULL;
|
|
} else
|
|
g_pMainFrm->m_hWnd = NULL;
|
|
delete(g_pMainFrm);
|
|
g_pMainFrm = NULL;
|
|
|
|
return true;
|
|
}
|
|
|
|
return false;
|
|
}
|