Files
2022-10-26 12:25:11 +08:00

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);
}
}