499 lines
16 KiB
C++
499 lines
16 KiB
C++
#include "shieldSecurityDll.h"
|
|
#include "system.h"
|
|
#include "utility.h"
|
|
#include "converter.h"
|
|
#include "frost.bmp.h"
|
|
#include <commctrl.h>
|
|
#include <fstream>
|
|
|
|
#pragma comment(lib, "Ws2_32.lib")
|
|
#pragma comment(lib, "Advapi32.lib")
|
|
|
|
std::ofstream frostLogFile;
|
|
bool frostLogging = false;
|
|
|
|
shieldSecurityDll* shieldSecurityDll::m_inst = 0;
|
|
const char* shieldSecurityDll::m_defaultDll = "gameShieldDll.dll";
|
|
|
|
shieldSecurityDll::shieldSecurityDll()
|
|
{
|
|
memset(this, 0, sizeof(shieldSecurityDll));
|
|
}
|
|
|
|
shieldSecurityDll::~shieldSecurityDll()
|
|
{
|
|
if(m_updateLib) {
|
|
typedef void (*freeFrostUpdate_t)();
|
|
freeFrostUpdate_t freeFrostUpdate =
|
|
(freeFrostUpdate_t)GetProcAddress(m_updateLib, "freeFrostUpdate");
|
|
if(freeFrostUpdate){
|
|
freeFrostUpdate();
|
|
}
|
|
}
|
|
//if(m_lib) {
|
|
// FreeLibrary(m_lib);
|
|
//}
|
|
}
|
|
|
|
void shieldSecurityDll::loadLibrary(const char* dllPath)
|
|
{
|
|
m_lib = LoadLibraryA(dllPath);
|
|
if(m_lib) {
|
|
m_pSetUserName = (void (*)(const char*))
|
|
GetProcAddress(m_lib, "frostSetUserName");
|
|
m_pSetCharName = (void (*)(const char*))
|
|
GetProcAddress(m_lib, "frostSetCharName");
|
|
m_pConnect = (int (*)(SOCKET, const struct sockaddr*, int))
|
|
GetProcAddress(m_lib, "frostConnect");
|
|
m_pSend = (int (*)(SOCKET, const char*, int, int))
|
|
GetProcAddress(m_lib, "frostSend");
|
|
m_pRecv = (int (*)(SOCKET, char*, int, int))
|
|
GetProcAddress(m_lib, "frostRecv");
|
|
m_pWSASend = (int (*)(SOCKET, LPWSABUF, DWORD, LPDWORD,
|
|
DWORD, LPWSAOVERLAPPED, LPWSAOVERLAPPED_COMPLETION_ROUTINE))
|
|
GetProcAddress(m_lib, "frostWSASend");
|
|
m_pWSARecv = (int (*)(SOCKET, LPWSABUF, DWORD,
|
|
LPDWORD, LPDWORD, LPWSAOVERLAPPED, LPWSAOVERLAPPED_COMPLETION_ROUTINE))
|
|
GetProcAddress(m_lib, "frostWSARecv");
|
|
m_pSendto = (int (*)(SOCKET, const char*, int, int,
|
|
const struct sockaddr*, int))
|
|
GetProcAddress(m_lib, "frostSendto");
|
|
m_pRecvfrom = (int (*)(SOCKET, char*, int, int,
|
|
struct sockaddr*, int*))
|
|
GetProcAddress(m_lib, "frostRecvfrom");
|
|
}
|
|
}
|
|
|
|
LRESULT CALLBACK shieldSecurityDll::
|
|
logoWndProc(HWND hWnd,
|
|
UINT message,
|
|
WPARAM wParam,
|
|
LPARAM lParam)
|
|
{
|
|
switch (message)
|
|
{
|
|
case WM_DESTROY:
|
|
PostQuitMessage(0);
|
|
return 0;
|
|
case WM_COMMAND:
|
|
if (HIWORD(wParam) == 0xabab && LOWORD(wParam) == 0xefef) {
|
|
DestroyWindow(hWnd);
|
|
PostQuitMessage(0);
|
|
return 0;
|
|
}
|
|
break;
|
|
case WM_LBUTTONDOWN:
|
|
PostMessage(hWnd, WM_NCLBUTTONDOWN, HTCAPTION, MAKELPARAM(lParam, wParam));
|
|
return 0;
|
|
case WM_PAINT:
|
|
if(m_inst){
|
|
PAINTSTRUCT ps;
|
|
HDC hDC = BeginPaint(hWnd, &ps);
|
|
HDC hMemDC = CreateCompatibleDC(hDC);
|
|
HGDIOBJ oldBitmap = SelectObject(hMemDC, m_inst->m_hBitmap);
|
|
int oldBkMode = SetBkMode(hMemDC, TRANSPARENT);
|
|
BitBlt(hDC, 0, 0, m_inst->m_logoWidth, m_inst->m_logoHeight, hMemDC, 0, 0, SRCCOPY);
|
|
SelectObject(hMemDC, oldBitmap);
|
|
SetBkMode(hMemDC, oldBkMode);
|
|
}
|
|
break;
|
|
default:
|
|
return DefWindowProc(hWnd, message, wParam, lParam);
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
void shieldSecurityDll::initLogoWnd(void*)
|
|
{
|
|
if(!m_inst) return;
|
|
strcpy(m_inst->m_szWindowClass, "frostsecurity_init_window");
|
|
WNDCLASSEXA wcex;
|
|
memset(&wcex, 0, sizeof(wcex));
|
|
wcex.cbSize = sizeof(wcex);
|
|
wcex.lpfnWndProc = logoWndProc;
|
|
wcex.hCursor = LoadCursor(NULL, IDC_ARROW);
|
|
wcex.hbrBackground = (HBRUSH)(COLOR_WINDOW+1);
|
|
wcex.lpszClassName = m_inst->m_szWindowClass;
|
|
RegisterClassExA(&wcex);
|
|
m_inst->m_logoWnd =
|
|
CreateWindowExA(WS_EX_PALETTEWINDOW,
|
|
m_inst->m_szWindowClass,
|
|
NULL,
|
|
WS_POPUP | WS_VISIBLE | WS_OVERLAPPED,
|
|
CW_USEDEFAULT,
|
|
CW_USEDEFAULT,
|
|
0,
|
|
0,
|
|
0,
|
|
0,
|
|
0,
|
|
NULL);
|
|
if(m_inst->m_logoWnd) {
|
|
m_inst->m_logoWidth = bmpWidth;
|
|
m_inst->m_logoHeight = bmpHeight;
|
|
DWORD* bmpBits = GetBmpBits();
|
|
BITMAPINFO bmpInfo;
|
|
bmpInfo.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
|
|
bmpInfo.bmiHeader.biWidth = m_inst->m_logoWidth;
|
|
bmpInfo.bmiHeader.biHeight = m_inst->m_logoHeight;
|
|
bmpInfo.bmiHeader.biPlanes = 1;
|
|
bmpInfo.bmiHeader.biBitCount = 32;
|
|
bmpInfo.bmiHeader.biCompression = BI_RGB;
|
|
bmpInfo.bmiHeader.biSizeImage = 0;
|
|
bmpInfo.bmiHeader.biXPelsPerMeter = 0;
|
|
bmpInfo.bmiHeader.biYPelsPerMeter = 0;
|
|
bmpInfo.bmiHeader.biClrUsed = 0;
|
|
bmpInfo.bmiHeader.biClrImportant = 0;
|
|
HDC hDC = GetDC(m_inst->m_logoWnd);
|
|
m_inst->m_hBitmap = CreateCompatibleBitmap(hDC, m_inst->m_logoWidth, m_inst->m_logoHeight);
|
|
SetDIBits(hDC, m_inst->m_hBitmap, 0, m_inst->m_logoHeight, bmpBits, &bmpInfo, DIB_RGB_COLORS);
|
|
delete[] bmpBits;
|
|
BITMAP mBitmap;
|
|
GetObject(m_inst->m_hBitmap, sizeof(mBitmap), &mBitmap);
|
|
m_inst->m_logoWidth = mBitmap.bmWidth;
|
|
m_inst->m_logoHeight = mBitmap.bmHeight;
|
|
HDC hMemDC = CreateCompatibleDC(hDC);
|
|
HGDIOBJ pOldBitmap = SelectObject(hMemDC, m_inst->m_hBitmap);
|
|
HRGN crRgnTmp;
|
|
HRGN crRgn = CreateRectRgn(0, 0, 0, 0);
|
|
COLORREF crTransparent = RGB(0, 255, 0);
|
|
int iX = 0;
|
|
for (int iY = 0; iY < m_inst->m_logoHeight; iY++) {
|
|
do {
|
|
while (iX <= m_inst->m_logoWidth && GetPixel(hMemDC, iX, iY) == crTransparent) ++iX;
|
|
int iLeftX = iX;
|
|
while (iX <= m_inst->m_logoWidth && GetPixel(hMemDC, iX, iY) != crTransparent) ++iX;
|
|
crRgnTmp = CreateRectRgn(iLeftX, iY, iX, iY+1);
|
|
CombineRgn(crRgn, crRgn, crRgnTmp, RGN_OR);
|
|
DeleteObject(crRgnTmp);
|
|
} while(iX < m_inst->m_logoWidth);
|
|
iX = 0;
|
|
}
|
|
SetWindowRgn(m_inst->m_logoWnd, crRgn, TRUE);
|
|
int iiX = (GetSystemMetrics(SM_CXSCREEN)) / 2 - (m_inst->m_logoWidth / 2);
|
|
int iiY = (GetSystemMetrics(SM_CYSCREEN)) / 2 - (m_inst->m_logoHeight / 2);
|
|
SetWindowPos(m_inst->m_logoWnd, NULL, iiX, iiY, m_inst->m_logoWidth, m_inst->m_logoHeight, NULL);
|
|
ReleaseDC(m_inst->m_logoWnd, hDC);
|
|
SelectObject(hMemDC, pOldBitmap);
|
|
DeleteDC(hMemDC);
|
|
DeleteObject(crRgn);
|
|
}
|
|
if(m_inst->m_logoEvent) {
|
|
SetEvent(m_inst->m_logoEvent);
|
|
}
|
|
if(m_inst->m_logoWnd) {
|
|
MSG msg;
|
|
while (GetMessage(&msg, 0, 0, 0) > 0) {
|
|
TranslateMessage(&msg);
|
|
DispatchMessage(&msg);
|
|
}
|
|
}
|
|
}
|
|
|
|
void shieldSecurityDll::loadUpdateDll(const char* dllPathCstr)
|
|
{
|
|
std::string dllPath(dllPathCstr);
|
|
std::wstring pd(utils::get_parent_directory(utils::ascii_to_utf16(dllPath.c_str())));
|
|
bool fnameChanged = std::string::npos == dllPath.find(m_defaultDll);
|
|
if(fnameChanged) {
|
|
CopyFileA(dllPath.c_str(),
|
|
(utils::utf16_to_ascii(pd.c_str()) + "\\" + m_defaultDll).c_str(),
|
|
false);
|
|
}
|
|
m_updateLib = LoadLibraryA((utils::utf16_to_ascii(pd.c_str()) + "\\frostUpdater.dll").c_str());
|
|
if(m_updateLib) {
|
|
typedef void (*frostUpdate_t)(HINSTANCE, const char*);
|
|
frostUpdate_t frostUpdate =
|
|
(frostUpdate_t)GetProcAddress(m_updateLib, "frostUpdate");
|
|
if(frostUpdate){
|
|
frostUpdate(GetModuleHandleA("frostUpdater"), utils::utf16_to_ascii(pd.c_str()).c_str());
|
|
}
|
|
}
|
|
if(fnameChanged) {
|
|
CopyFileA((utils::utf16_to_ascii(pd.c_str()) + "\\" + m_defaultDll).c_str(),
|
|
dllPath.c_str(),
|
|
false);
|
|
DeleteFileA((utils::utf16_to_ascii(pd.c_str()) + "\\" + m_defaultDll).c_str());
|
|
}
|
|
}
|
|
|
|
static bool isTestVersion()
|
|
{
|
|
HKEY hKey;
|
|
if (RegOpenKeyExA(HKEY_CURRENT_USER,
|
|
"software\\frost\\action",
|
|
0,
|
|
KEY_QUERY_VALUE,
|
|
&hKey) != ERROR_SUCCESS) {
|
|
return false;
|
|
}
|
|
DWORD dwType = REG_SZ;
|
|
char ptsPath[MAX_PATH] = {0};
|
|
DWORD ptsPathSize = MAX_PATH;
|
|
if (RegQueryValueExA(hKey,
|
|
"ignore_updater_update",
|
|
0,
|
|
&dwType,
|
|
(LPBYTE)ptsPath,
|
|
&ptsPathSize) != ERROR_SUCCESS) {
|
|
RegCloseKey(hKey);
|
|
return false;
|
|
}
|
|
RegCloseKey(hKey);
|
|
return true;
|
|
}
|
|
|
|
static bool is_logging_on()
|
|
{
|
|
HKEY hKey;
|
|
if (RegOpenKeyExA(HKEY_CURRENT_USER,
|
|
"software\\frost\\staticLib",
|
|
0,
|
|
KEY_QUERY_VALUE,
|
|
&hKey) != ERROR_SUCCESS) {
|
|
return false;
|
|
}
|
|
DWORD dwType = REG_DWORD;
|
|
DWORD isLogging = 0;
|
|
DWORD isLoggingSize = sizeof(isLogging);
|
|
if (RegQueryValueExA(hKey,
|
|
"logging",
|
|
0,
|
|
&dwType,
|
|
(LPBYTE)(&isLogging),
|
|
&isLoggingSize) != ERROR_SUCCESS) {
|
|
RegCloseKey(hKey);
|
|
return false;
|
|
}
|
|
RegCloseKey(hKey);
|
|
return (1 == isLogging);
|
|
}
|
|
|
|
void shieldSecurityDll::update(const char* dllPathcstr)
|
|
{
|
|
static const std::string srvName = "frostsecurity.net";
|
|
static const unsigned short srvPort = 80;
|
|
static const std::string path = "frost/updater/";
|
|
static bool sockInited = false;
|
|
if(!sockInited) {
|
|
WSADATA wsaData;
|
|
if(WSAStartup(MAKEWORD(2, 2), &wsaData) != NO_ERROR) {
|
|
WSACleanup();
|
|
return;
|
|
}
|
|
sockInited = true;
|
|
}
|
|
std::string rootURL =
|
|
"http://" + srvName + ":" + utils::int2str(srvPort) + "/" + path;
|
|
std::string dllPath(dllPathcstr);
|
|
if(std::string::npos == dllPath.find_first_of("\\/")) {
|
|
dllPath = std::string(".\\") + dllPath;
|
|
}
|
|
m_logoEvent = CreateEvent(0, false, false, 0);
|
|
CreateThread(0,
|
|
0,
|
|
(LPTHREAD_START_ROUTINE)initLogoWnd,
|
|
0,
|
|
0,
|
|
0);
|
|
update_by_crc_param up(rootURL.c_str(),
|
|
utils::utf16_to_ascii(utils::get_parent_directory(utils::ascii_to_utf16(dllPath.c_str())).c_str()).c_str());
|
|
if(!isTestVersion()) {
|
|
utility::update_by_crc(&up);
|
|
} else {
|
|
}
|
|
if(m_logoEvent) {
|
|
WaitForSingleObject(m_logoEvent, INFINITE);
|
|
CloseHandle(m_logoEvent);
|
|
m_logoEvent = 0;
|
|
}
|
|
if(m_logoWnd) {
|
|
PostMessage(m_logoWnd,
|
|
WM_COMMAND,
|
|
MAKEWPARAM(0xefef, 0xabab),
|
|
0);
|
|
m_logoWnd = 0;
|
|
}
|
|
loadUpdateDll(dllPath.c_str());
|
|
}
|
|
|
|
void shieldSecurityDll::init(const char* path)
|
|
{
|
|
if(is_logging_on()) {
|
|
frostLogFile.open("frostStatic.log");
|
|
if(frostLogFile.is_open()) {
|
|
frostLogging = true;
|
|
} else {
|
|
frostLogging = false;
|
|
}
|
|
} else {
|
|
frostLogging = false;
|
|
if(frostLogFile.is_open()) {
|
|
frostLogFile.close();
|
|
}
|
|
}
|
|
const char* dllPath = path ? path : m_defaultDll;
|
|
if(!m_inst) {
|
|
try {
|
|
m_inst = new shieldSecurityDll();
|
|
if(m_inst) {
|
|
m_inst->update(dllPath);
|
|
m_inst->loadLibrary(dllPath);
|
|
}
|
|
} catch (...) {
|
|
finish();
|
|
}
|
|
}
|
|
}
|
|
|
|
void shieldSecurityDll::finish()
|
|
{
|
|
delete m_inst;
|
|
m_inst = 0;
|
|
}
|
|
|
|
void shieldSecurityDll::setUserName(const char* uin)
|
|
{
|
|
if(m_inst && m_inst->m_pSetUserName) {
|
|
m_inst->m_pSetUserName(uin);
|
|
}
|
|
}
|
|
|
|
int shieldSecurityDll::connect(SOCKET s,
|
|
const struct sockaddr* name,
|
|
int namelen)
|
|
{
|
|
if(m_inst && m_inst->m_pConnect) {
|
|
return m_inst->m_pConnect(s, name, namelen);
|
|
}
|
|
return ::connect(s, name, namelen);
|
|
}
|
|
|
|
int shieldSecurityDll::send(SOCKET s,
|
|
const char* buf,
|
|
int len,
|
|
int flags)
|
|
{
|
|
if(m_inst && m_inst->m_pSend) {
|
|
return m_inst->m_pSend(s, buf, len, flags);
|
|
}
|
|
return ::send(s, buf, len, flags);
|
|
}
|
|
|
|
int shieldSecurityDll::recv(SOCKET s,
|
|
char* buf,
|
|
int len,
|
|
int flags)
|
|
{
|
|
if(m_inst && m_inst->m_pRecv) {
|
|
return m_inst->m_pRecv(s, buf, len, flags);
|
|
}
|
|
return ::recv(s, buf, len, flags);
|
|
}
|
|
|
|
int shieldSecurityDll::WSASend(SOCKET s,
|
|
LPWSABUF lpBuffers,
|
|
DWORD dwBufferCount,
|
|
LPDWORD lpNumberOfBytesSent,
|
|
DWORD dwFlags,
|
|
LPWSAOVERLAPPED lpOverlapped,
|
|
LPWSAOVERLAPPED_COMPLETION_ROUTINE lpCompletionRoutine)
|
|
{
|
|
if(m_inst && m_inst->m_pWSASend) {
|
|
return m_inst->m_pWSASend(s,
|
|
lpBuffers,
|
|
dwBufferCount,
|
|
lpNumberOfBytesSent,
|
|
dwFlags,
|
|
lpOverlapped,
|
|
lpCompletionRoutine);
|
|
}
|
|
return ::WSASend(s,
|
|
lpBuffers,
|
|
dwBufferCount,
|
|
lpNumberOfBytesSent,
|
|
dwFlags,
|
|
lpOverlapped,
|
|
lpCompletionRoutine);
|
|
}
|
|
|
|
int shieldSecurityDll::WSARecv(SOCKET s,
|
|
LPWSABUF lpBuffers,
|
|
DWORD dwBufferCount,
|
|
LPDWORD lpNumberOfBytesRecvd,
|
|
LPDWORD lpFlags,
|
|
LPWSAOVERLAPPED lpOverlapped,
|
|
LPWSAOVERLAPPED_COMPLETION_ROUTINE lpCompletionRoutine)
|
|
{
|
|
if(m_inst && m_inst->m_pWSARecv) {
|
|
return m_inst->m_pWSARecv(s,
|
|
lpBuffers,
|
|
dwBufferCount,
|
|
lpNumberOfBytesRecvd,
|
|
lpFlags,
|
|
lpOverlapped,
|
|
lpCompletionRoutine);
|
|
}
|
|
return ::WSARecv(s,
|
|
lpBuffers,
|
|
dwBufferCount,
|
|
lpNumberOfBytesRecvd,
|
|
lpFlags,
|
|
lpOverlapped,
|
|
lpCompletionRoutine);
|
|
}
|
|
|
|
int shieldSecurityDll::sendto(SOCKET s,
|
|
const char* buf,
|
|
int len,
|
|
int flags,
|
|
const struct sockaddr* to,
|
|
int tolen)
|
|
{
|
|
if(m_inst && m_inst->m_pSendto) {
|
|
return m_inst->m_pSendto(s,
|
|
buf,
|
|
len,
|
|
flags,
|
|
to,
|
|
tolen);
|
|
}
|
|
return ::sendto(s,
|
|
buf,
|
|
len,
|
|
flags,
|
|
to,
|
|
tolen);
|
|
}
|
|
|
|
int shieldSecurityDll::recvfrom(SOCKET s,
|
|
char* buf,
|
|
int len,
|
|
int flags,
|
|
struct sockaddr* from,
|
|
int* fromlen)
|
|
{
|
|
if(m_inst && m_inst->m_pRecvfrom) {
|
|
return m_inst->m_pRecvfrom(s,
|
|
buf,
|
|
len,
|
|
flags,
|
|
from,
|
|
fromlen);
|
|
}
|
|
return ::recvfrom(s,
|
|
buf,
|
|
len,
|
|
flags,
|
|
from,
|
|
fromlen);
|
|
}
|
|
|
|
void shieldSecurityDll::setCharName(const char* cName)
|
|
{
|
|
if(m_inst && m_inst->m_pSetCharName) {
|
|
m_inst->m_pSetCharName(cName);
|
|
}
|
|
}
|
|
|