12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085 |
- #include "precompile.h"
- #include "app.h"
- #include "osutil.h"
- #include "sp_dbg_export.h"
- #ifdef _WIN32
- #include <DbgHelp.h>
- #include <TlHelp32.h>
- #include <shellapi.h>
- #else
- #include <unistd.h>
- #endif //_WIN32
- #include "fileutil.h"
- #include "iniutil.h"
- #include "getopt.h"
- #include "toolkit.h"
- #include "SimpleString.h"
- #include "SpBase.h"
- #include "SpComm.hpp"
- #ifdef _WIN32
- #include <io.h>
- #endif //_WIN32
- #include <locale.h>
- #include <winpr/library.h>
- #include <winpr/environment.h>
- #include <winpr/registry.h>
- #include <winpr/sysinfo.h>
- using namespace std;
- #define DRIVER_NAME "HelloDDK"
- #define DRIVER_PATH "InterceptDll.sys"
- #define SET_EVENT \
- CTL_CODE(FILE_DEVICE_UNKNOWN, 0x800, METHOD_BUFFERED, FILE_ANY_ACCESS)
- #define GET_SHARE_ADD \
- CTL_CODE(FILE_DEVICE_UNKNOWN, 0x801, METHOD_BUFFERED, FILE_ANY_ACCESS)
- HANDLE g_hEvent = NULL;
- bool g_bMD5Exist = false;
- bool g_bWow64 = false;
- CSimpleStringA g_strMD5ListPath;
- static void SetEnvPath()
- {
- char path[MAX_PATH];
- char *buf;
- DWORD size;
- const char *var = "PATH";
- // set current path
- GetModuleFileNameA(NULL, path, MAX_PATH);
- *strrchr(path, SPLIT_SLASH) = 0;
- *strrchr(path, SPLIT_SLASH) = 0;
- SetCurrentDirectoryA(path);
- // append dep sub dir to %PATH%
- strcat(path, SPLIT_SLASH_STR "dep");
- size = GetEnvironmentVariableA(var, NULL, 0);
- buf = (char*)malloc(size+MAX_PATH*3);
- size = GetEnvironmentVariableA(var, buf, size);
- strcpy(buf+size, ENV_SEP_STR);
- strcat(buf+size, path);
- *strrchr(path, SPLIT_SLASH) = 0;
- strcat(path, SPLIT_SLASH_STR "bin");
- strcat(buf+size, ENV_SEP_STR);
- strcat(buf+size, path);
-
- *strrchr(path, SPLIT_SLASH) = 0;
- strcat(path, SPLIT_SLASH_STR "dev");
- strcat(buf+size, ENV_SEP_STR);
- strcat(buf+size, path);
- *strrchr(path, SPLIT_SLASH) = 0;
- strcat(path, SPLIT_SLASH_STR "imdep");
- strcat(buf + size, ENV_SEP_STR);
- strcat(buf + size, path);
- SetEnvironmentVariableA(var, buf);
- free(buf);
- SetEnvironmentVariableA("ModuleName", "SpShell");
- }
- #ifdef _WIN32
- // 获取设置内存使用率,4G
- static void SetWorkingSet()
- {
- SIZE_T dwMinSize, dwMaxSize;
- HANDLE hCurrProcess = GetCurrentProcess();
- GetProcessWorkingSetSize(hCurrProcess, &dwMinSize, &dwMaxSize);
- if (dwMaxSize < (2 << 20))
- dwMaxSize = 2 << 20;
- SetProcessWorkingSetSize(hCurrProcess, dwMinSize, dwMaxSize);
- }
- static LONG WINAPI SuppressError(struct _EXCEPTION_POINTERS* ExceptionInfo)
- {
- char tmp[MAX_PATH];
- HANDLE hDumpFile;
- wsprintfA(tmp, ".\\expt.spshell.%d.%d.dmp", GetCurrentThreadId(), GetCurrentProcessId());
- hDumpFile = CreateFileA( tmp, GENERIC_READ | GENERIC_WRITE,
- 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL );
- if( ( hDumpFile != NULL ) && ( hDumpFile != INVALID_HANDLE_VALUE ) )
- {
- MINIDUMP_EXCEPTION_INFORMATION mdei;
- MINIDUMP_TYPE mdt;
- mdei.ThreadId = GetCurrentThreadId();
- mdei.ExceptionPointers = ExceptionInfo;
- mdei.ClientPointers = FALSE;
- mdt = MiniDumpNormal;
- MiniDumpWriteDump(GetCurrentProcess(), GetCurrentProcessId(),
- hDumpFile, mdt, (ExceptionInfo != 0) ? &mdei : 0, 0, 0 );
- CloseHandle( hDumpFile );
- }
- char szCmd[256];
- sprintf_s(szCmd, 256, "TASKKILL /f /im sphost.exe");
- system(szCmd);
- ExitProcess(Error_Exception); // exit process to suppress reporting exception
- return EXCEPTION_EXECUTE_HANDLER;
- }
- static void DisableSetUnhandledExceptionFilter()
- {
- void* addr = (void*)GetProcAddress(LoadLibrary("kernel32.dll"), "SetUnhandledExceptionFilter");
- if (addr) {
- DWORD dwOldFlag, dwTempFlag;
- unsigned char code[] = {0x33, 0xC0, 0xC2, 0x04, 0x00}; // xor eax,eax; ret 4;
- //VirtualProtect(addr, sizeof(code), PAGE_READWRITE, &dwOldFlag);
- VirtualProtectEx(GetCurrentProcess(), addr, sizeof(code), PAGE_EXECUTE_READWRITE, &dwOldFlag);
- WriteProcessMemory(GetCurrentProcess(), addr, code, sizeof(code), NULL);
- VirtualProtect(addr, sizeof(code), dwOldFlag, &dwTempFlag);
- }
- }
- __declspec(dllimport) bool DisableCharmbar();
- __declspec(dllimport) bool EnableCharmbar();
- static HANDLE create_process(const char *app)
- {
- //BOOL bRet;
- STARTUPINFOA si = { sizeof(STARTUPINFOA) };
- si.wShowWindow = SW_SHOWMAXIMIZED;
- si.dwFlags = STARTF_USESHOWWINDOW;
- PROCESS_INFORMATION pi;
- DWORD dwSessionId;
- HANDLE hUserTokenDup, hThisToken;
- HANDLE hProcess = NULL;
- dwSessionId = WTSGetActiveConsoleSessionId();
- if (OpenProcessToken(GetCurrentProcess(), TOKEN_ALL_ACCESS, &hThisToken)) {
- LUID luid;
- TOKEN_PRIVILEGES tp;
- LPVOID pEnv = NULL;
- LookupPrivilegeValueA(NULL, SE_DEBUG_NAME, &luid);
- tp.PrivilegeCount = 1;
- tp.Privileges[0].Luid = luid;
- tp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
- DuplicateTokenEx(hThisToken, MAXIMUM_ALLOWED, NULL,
- SecurityIdentification, TokenPrimary, &hUserTokenDup);
- SetTokenInformation(hUserTokenDup,
- TokenSessionId, (void*)&dwSessionId, sizeof(DWORD));
- AdjustTokenPrivileges(hUserTokenDup, FALSE, &tp, sizeof(TOKEN_PRIVILEGES),
- (PTOKEN_PRIVILEGES)NULL, NULL);
- //CreateEnvironmentBlock(&pEnv,hUserTokenDup,TRUE);
- if (CreateProcessAsUserA(hUserTokenDup, NULL,
- (LPSTR)app,
- NULL, NULL, FALSE, 0, pEnv, NULL, &si, &pi))
- {
- CloseHandle(pi.hThread);
- hProcess = pi.hProcess;
- }
- else
- sp_dbg_warn("create process failed! Error : ", GetLastError());
- //if (pEnv)
- //DestroyEnvironmentBlock(pEnv);
- CloseHandle(hUserTokenDup);
- CloseHandle(hThisToken);
- }
- else {
- sp_dbg_warn("open process token failed! Error : ", GetLastError());
- }
- return hProcess;
- }
- static void AutoHideTaskBar(bool bHide)
- {
- APPBARDATA apBar;
- memset(&apBar, 0, sizeof(apBar));
- apBar.cbSize = sizeof(apBar);
- apBar.lParam = bHide ? ABS_AUTOHIDE : ABS_ALWAYSONTOP;
- apBar.hWnd = FindWindow("Shell_TrayWnd", NULL);
- if (apBar.hWnd != NULL)
- {
- SHAppBarMessage(ABM_SETSTATE, &apBar);
- }
- }
- static bool AddRegIntValue(HKEY hKey, const char *szSubKey, const char *szKeyName, DWORD dwValue, bool bWin64)
- {
- HKEY hSubKey;
- LONG nRet = ::RegCreateKeyEx(hKey,
- szSubKey,
- 0,
- NULL,
- 0,
- bWin64 ? (KEY_ALL_ACCESS | KEY_WOW64_64KEY) : (KEY_ALL_ACCESS | KEY_WOW64_32KEY),
- NULL,
- &hSubKey,
- NULL);
- if (nRet != ERROR_SUCCESS)
- return false;
- nRet = RegSetValueExA(hSubKey, szKeyName, 0, REG_DWORD, (BYTE*)&dwValue, sizeof(DWORD));
- RegCloseKey(hSubKey);
- return (nRet == ERROR_SUCCESS);
- }
- static bool AddFirewallRules()
- {
- char szBinDir[MAX_PATH] = {};
- GetModuleFileNameA(NULL, szBinDir, MAX_PATH);
- *strrchr(szBinDir, SPLIT_SLASH) = 0;
- int nRet = (int)ShellExecute(NULL, "open", "cmd.exe", "/s /c \"netsh advfirewall firewall delete rule name=\"\"SpShell\"\"", NULL, SW_HIDE);
- nRet = (int)ShellExecute(NULL, "open", "cmd.exe", "/s /c \"netsh advfirewall firewall delete rule name=\"\"SpShell\"\"", NULL, SW_HIDE);
- nRet = (int)ShellExecute(NULL, "open", "cmd.exe", "/s /c \"netsh advfirewall firewall delete rule name=\"\"SpHost\"\"", NULL, SW_HIDE);
- nRet = (int)ShellExecute(NULL, "open", "cmd.exe", "/s /c \"netsh advfirewall firewall delete rule name=\"\"SpGuardian\"\"", NULL, SW_HIDE);
- char szParam[1024] = {};
- sprintf_s(szParam, 1024, "/s /c \"netsh advfirewall firewall add rule name=\"\"SpShell\"\" dir=out program=\"\"%s\\spshell.exe\"\" action=allow\"", szBinDir);
- nRet = (int)ShellExecute(NULL, "open", "cmd.exe", szParam, NULL, SW_HIDE);
- sprintf_s(szParam, 1024, "/s /c \"netsh advfirewall firewall add rule name=\"\"SpHost\"\" dir=out program=\"\"%s\\sphost.exe\"\" action=allow\"", szBinDir);
- nRet = (int)ShellExecute(NULL, "open", "cmd.exe", szParam, NULL, SW_HIDE);
- sprintf_s(szParam, 1024, "/s /c \"netsh advfirewall firewall add rule name=\"\"SpGuardian\"\" dir=out program=\"\"%s\\guardian.exe\"\" action=allow\"", szBinDir);
- nRet = (int)ShellExecute(NULL, "open", "cmd.exe", szParam, NULL, SW_HIDE);
- return nRet > 32;
- }
- int AddFireAddFirewallRulesThread(void* param)
- {
- if (!AddFirewallRules())
- {
- sp_dbg_fatal("设置Windows防火墙策略失败!!!");
- Sleep(10000);
- return -1;
- }
- else
- sp_dbg_info("设置Windows防火墙策略成功!!!");
- return 0;
- }
- static void AddFirewallRulesEx()
- {
- CloseHandle(CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)& AddFireAddFirewallRulesThread, NULL, 0, NULL));
- }
- static bool DisableWindowsCharmBar(bool bX64)
- {
- if (!bX64)
- {
- if (DisableCharmbar())
- {
- sp_dbg_info("disable windows 8 charmbar succ");
- return true;
- }
- else
- {
- sp_dbg_error("disable windows 8 charmbar fail: %x", GetLastError());
- return false;
- }
- }
- else
- {
- // 由于64位Windows Hook需要64位进程和64位dll,需要独立启动MetroWatcher64注入
- char path[MAX_PATH] = {};
- GetModuleFileNameA(NULL, path, MAX_PATH);
- *strrchr(path, SPLIT_SLASH) = 0;
- char app[MAX_PATH] = {};
- sprintf(app, "%s\\MetroWatcher64.exe %d", path, GetCurrentProcessId());
- if (create_process(app) != NULL)
- {
- sp_dbg_info("disable windows 8 (64bit) charmbar succ");
- return true;
- }
- else
- {
- sp_dbg_error("disable windows 8 (64bit) charmbar fail: %x", GetLastError());
- return false;
- }
- }
- }
- #endif //_WIN32
- /*!
- * at Linux, judge whether current process runs as root privilege.
- * @return : True only if run as admin or root
- */
- static bool IsProcessRunAsAdmin()
- {
- BOOL bAdmin = FALSE;
- #ifdef _WIN32
- SID_IDENTIFIER_AUTHORITY NtAuthority = SECURITY_NT_AUTHORITY;
- PSID AdministratorsGroup = NULL;
- sp_dbg_info("start AllocateAndInitializeSid");
- if (AllocateAndInitializeSid(
- &NtAuthority,
- 2,
- SECURITY_BUILTIN_DOMAIN_RID,
- DOMAIN_ALIAS_RID_ADMINS,
- 0, 0, 0, 0, 0, 0,
- &AdministratorsGroup)) {
- sp_dbg_info("start CheckTokenMembership");
- CheckTokenMembership(NULL, AdministratorsGroup, &bAdmin);
- sp_dbg_info("start FreeSid");
- FreeSid(AdministratorsGroup);
- }
- #else
- if (geteuid() == 0) {
- bAdmin = TRUE;
- } else {
- sp_dbg_warn("current process is not run as root privilege, euid:%u, uid:%d", geteuid(), getuid());
- }
- #endif //_WIN32
- return bAdmin == TRUE;
- }
- const char *GetMachineType()
- {
- auto env = sp_get_env();
- if (env == NULL)
- {
- sp_dbg_error("sp_get_env return null");
- return NULL;
- }
- return env->cfg->root_ini->machine_type;
- }
- const char *GetCenterSettingNameBySite(const char *pszSite)
- {
- if ((stricmp(pszSite, "CMB.LIB") == 0) // 行内大堂
- || (stricmp(pszSite, "CMB.SSB") == 0))//
- {
- return "CenterSetting.LAN.ini";
- }
- else if ((stricmp(pszSite, "CMB.LSS") == 0) //
- || (stricmp(pszSite, "CMB.FLB") == 0) //
- || (stricmp(pszSite, "CMB.OSB") == 0) //
- || (stricmp(pszSite, "CMB.SMM") == 0)) //
- {
- return "CenterSetting.DMZ.ini";
- }
- else
- {
- return "CenterSetting.DMZ.ini";
- }
- }
- const char *GetWebSiteFromConfig()
- {
- auto env = sp_get_env();
- if (env == NULL)
- {
- sp_dbg_error("sp_get_env return null");
- return NULL;
- }
- auto pszCenterSettingName = GetCenterSettingNameBySite(env->cfg->root_ini->site);
- char szCfgFile[256] = {};
- sprintf_s(szCfgFile, sizeof(szCfgFile), "%s\\%s", env->dir->cfg_path, pszCenterSettingName);
-
- // 判断对应集中配置文件是否存在,不存在则重命名CenterSetting.ini
- if (!ExistsFileA(szCfgFile))
- {
- char szBackupCfgFile[256] = {};
- sprintf_s(szBackupCfgFile, sizeof(szCfgFile), "%s\\CenterSetting.ini", env->dir->cfg_path);
- // default CenterSetting config file has been removed ? I can see it in depository [3/19/2020 7:47 Gifur]
- if (ExistsFileA(szBackupCfgFile))
- {
- rename(szBackupCfgFile, szCfgFile);
- }
- }
- // get machine type
- auto pMachineType = env->cfg->root_ini->machine_type;
- char szKeyName[256] = {};
- sprintf(szKeyName, "IEBrowser.%s.URL", pMachineType);
- auto pWebSite = inifile_read_str(szCfgFile, "HealthManager", szKeyName, NULL);
- if (pWebSite == NULL || strlen(pWebSite)==0)
- {
- if (pWebSite) FREE(pWebSite);
- sp_dbg_error("read %s from %s return null", szKeyName, pszCenterSettingName);
- return NULL;
- }
- // http://99.1.100.217/RVC.Web/default.aspx http://99.1.100.217/RVC.Web/default2.aspx
- // get root url
- auto p = strchr(pWebSite + 7, '/');
- if (p != NULL)
- *p = 0;
- p = strchr(pWebSite + 7, ':');
- if (p == NULL)
- strcat(pWebSite, ":80");
- return pWebSite;
- }
- #ifdef _WIN32
- static bool WebcamMicrophoneAuthorize(bool bWin64)
- {
- const char *pWetSite = GetWebSiteFromConfig();
- if(pWetSite == NULL)
- {
- sp_dbg_error("GetWebSiteFromConfig failed!");
- return false;
- }
- TCHAR szSubKey[1024] = { 0 };
- sprintf(szSubKey, "Software\\AppDataLow\\Software\\Microsoft\\Silverlight\\Permissions\\%s", pWetSite);
- free((void*)(char*)pWetSite);
- if (!AddRegIntValue(HKEY_CURRENT_USER, szSubKey, "WebcamAndMicrophone", 0x00000011, bWin64))
- {
- sp_dbg_error("创建SL摄像机麦克风权限注册表项失败!");
- return false;
- }
- sp_dbg_info("add silverlight webcam and microphone permission succeed");
- return true;
- }
- #endif //_WIN32
- static bool SpTerminateProcess(HANDLE hProc, DWORD dwProcID)
- {
- if (!TerminateProcess(hProc, -1))
- {
- #ifdef _WIN32
- char szCmd[256];
- int nRet = 0;
- sp_dbg_debug("terminate process %d fail: 0x%X, retry with taskkill", dwProcID, GetLastError());
- sprintf_s(szCmd, 256, "TASKKILL /PID %d /F", dwProcID);
- WinExec(szCmd, SW_HIDE);
- return nRet != -1;
- #else
- return false;
- #endif //_WIN32
- }
- return true;
- }
- // replace it with osutil from libtoolkit [3/18/2020 19:01 Gifur]
- /*
- static bool DetectDuplicateInstance(char **pNames, int nNum)
- {
- sp_dbg_info("start GetCurrentProcessId");
- DWORD dwCurProcID = GetCurrentProcessId();
- sp_dbg_info("start CreateToolhelp32Snapshot");
- HANDLE hSnapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
- if (hSnapshot)
- {
- PROCESSENTRY32 pe = {};
- pe.dwSize = sizeof(pe);
- sp_dbg_info("start Process32First");
- if (Process32First(hSnapshot, &pe))
- {
- do
- {
- for (int i = 0; i < nNum; i++)
- {
- if (stricmp(&pe.szExeFile[0], pNames[i]) == 0 && pe.th32ProcessID != dwCurProcID)
- {
- sp_dbg_info("start OpenProcess");
- HANDLE hProc = OpenProcess(PROCESS_ALL_ACCESS, FALSE, pe.th32ProcessID);
- if (hProc == NULL)
- {
- sp_dbg_error("find duplicated process: %s, id: %d", pNames[i], pe.th32ProcessID);
- CloseHandle(hSnapshot);
- return false;
- }
- if (!SpTerminateProcess(hProc, pe.th32ProcessID))
- {
- sp_dbg_error("terminate duplicated process %s fail, id: %d, error: %d", pNames[i], pe.th32ProcessID, GetLastError());
- CloseHandle(hSnapshot);
- return false;
- }
- sp_dbg_info("terminate duplicated process: %s, id: %d", pNames[i], pe.th32ProcessID);
- }
- }
- } while (Process32Next(hSnapshot, &pe));
- }
- CloseHandle(hSnapshot);
- }
- return true;
- }
- */
- #ifdef _WIN32
- static bool LoadInterceptDllDriver(char* lpszDriverName,char* lpszDriverPath)
- {
- /************************ 加载DLL监控驱动的代码*******************************
- ① 调用OpenSCManager,打开SCM管理器.如果返回NULL,则返回失败,否则继续
- ② 调用CreateService,创建服务,创建成功则转步骤 ⑥
- ③ 用GetLastError的得到错误返回值
- ④ 返回值为ERROR_IO_PENDING,说明服务已经创建过,用OpenService打开此服务.
- ⑤ 返回值为其他值, 创建武服务失败,返回失败.
- ⑥ 调用StartService开启服务
- ⑦ 成功返回
- ************************************************************************/
- CSimpleStringA strDriverPath;
- TCHAR szPath[MAX_PATH] = {0};
- GetModuleFileNameA(NULL, szPath, MAX_PATH);
- *strrchr(szPath, SPLIT_SLASH) = 0;
- strDriverPath = szPath;
- if (g_bWow64)
- {
- strDriverPath += SPLIT_SLASH_STR "InterceptDll_64.sys";
- }
- else
- {
- strDriverPath += SPLIT_SLASH_STR "InterceptDll_32.sys";
- }
-
- sp_dbg_info("strDriverPath[%s]",strDriverPath);
- bool bRet = false;
- SC_HANDLE hServiceMgr=NULL;
- SC_HANDLE hServiceDDK=NULL;
- hServiceMgr = OpenSCManager(NULL, NULL, SC_MANAGER_ALL_ACCESS);
- if(hServiceMgr == NULL)
- {
- sp_dbg_fatal("OpenSCManager() Failed %d!", GetLastError());
- bRet = false;
- goto BeforeLeave;
- }
- else
- {
- sp_dbg_info("OpenSCManager() ok");
- }
- hServiceDDK = CreateService(hServiceMgr,
- lpszDriverName, // 驱动程序的在注册表中的名字
- lpszDriverName, // 注册表驱动程序的 DisplayName 值
- SERVICE_ALL_ACCESS, // 加载驱动程序的访问权限
- SERVICE_KERNEL_DRIVER, // 表示加载的服务是驱动程序
- SERVICE_DEMAND_START, // 注册表驱动程序的 Start 值
- SERVICE_ERROR_IGNORE, // 注册表驱动程序的 ErrorControl 值
- //szDriverImagePath, // 注册表驱动程序的 ImagePath 值
- strDriverPath.GetData(),
- //"C:\\Run\\version\\1.10.0.0\\bin\\InterceptDll.sys",
- NULL,
- NULL,
- NULL,
- NULL,
- NULL);
- DWORD dwRtn;
- if(hServiceDDK == NULL) // 判断服务是否失败
- {
- dwRtn = GetLastError();
- if(dwRtn != ERROR_IO_PENDING && dwRtn != ERROR_SERVICE_EXISTS)
- {
- sp_dbg_fatal("CreateService() Faild %d !", dwRtn);
- bRet = false;
- goto BeforeLeave;
- }
- else
- {
- sp_dbg_info("CreateService() Faild Service is ERROR_IO_PENDING or ERROR_SERVICE_EXISTS!");
- }
- // 驱动程序已经加载,只需要打开
- hServiceDDK = OpenService(hServiceMgr, lpszDriverName, SERVICE_ALL_ACCESS);
- if(hServiceDDK == NULL)
- {
- // 如果打开服务也失败,则意味错误
- dwRtn = GetLastError();
- sp_dbg_fatal("OpenService() Faild %d!", dwRtn);
- bRet = false;
- goto BeforeLeave;
- }
- else
- {
- sp_dbg_info("OpenService() ok!");
- }
- }
- else
- {
- sp_dbg_info("CrateService() ok !");
- }
- bRet= StartService(hServiceDDK, NULL, NULL);
- if(!bRet)
- {
- DWORD dwRtn = GetLastError();
- if(dwRtn != ERROR_IO_PENDING && dwRtn != ERROR_SERVICE_ALREADY_RUNNING)
- {
- sp_dbg_fatal("StartService() Faild %d !", dwRtn);
- bRet = false;
- goto BeforeLeave;
- }
- else
- {
- if(dwRtn == ERROR_IO_PENDING)
- {
- // 设备被挂住
- sp_dbg_fatal("StartService() Faild ERROR_IO_PENDING!");
- bRet = false;
- goto BeforeLeave;
- }
- else
- {
- // 服务已经开启
- sp_dbg_fatal("StartService() Faild ERROR_SERVICE_ALREADY_RUNNING!");
- bRet = true;
- goto BeforeLeave;
- }
- }
- }
- else
- {
- sp_dbg_info("StartService() ok!");
- }
- bRet = true;
-
- BeforeLeave:
- if(hServiceDDK)
- {
- CloseServiceHandle(hServiceDDK); // 服务句柄
- }
- if(hServiceMgr)
- {
- CloseServiceHandle(hServiceMgr); // SCM句柄
- }
- return bRet;
- }
- static bool UnloadInterceptDllDriver(char* szSvrName)
- {
- /************************* 卸载NT驱动的代码******************************
- ① 调用OpenSCManager,打开SCM管理器,如果返回NULL,则返回失败,否则继续.
- ② 调用OpenService.如果返回NULL,则返回失败,否则继续
- ③ 调用DeleteService卸载此项服务.
- ④ 成功返回.
- ************************************************************************/
- bool bRet = false;
- SC_HANDLE hServiceMgr=NULL;// SCM管理器的句柄
- SC_HANDLE hServiceDDK=NULL;// NT驱动程序的服务句柄
- SERVICE_STATUS SvrSta;
- sp_dbg_info("start OpenSCManager");
- hServiceMgr = OpenSCManager(NULL, NULL, SC_MANAGER_ALL_ACCESS);
- if( hServiceMgr == NULL )
- {
- sp_dbg_info("OpenSCManager() Failed %d!", GetLastError());
- bRet = false;
- goto BeforeLeave;
- }
- else
- {
- sp_dbg_info("OpenSCManager() ok !");
- }
- hServiceDDK = OpenService(hServiceMgr, szSvrName, SERVICE_ALL_ACCESS);
- if(hServiceDDK == NULL)
- {
- sp_dbg_info("OpenService() Failed %d!", GetLastError());
- bRet = false;
- goto BeforeLeave;
- }
- else
- {
- sp_dbg_info("OpenService() ok !");
- }
- // 停止驱动程序,如果停止失败,只有重新启动才能,再动态加载。
- if(!ControlService(hServiceDDK, SERVICE_CONTROL_STOP , &SvrSta ))
- {
- sp_dbg_info("ControlService() Failed %d!", GetLastError());
- }
- else
- {
- sp_dbg_info("ControlService() ok !");
- }
- if(!DeleteService(hServiceDDK))
- {
- sp_dbg_info("DeleteSrevice() Failed %d!", GetLastError());
- }
- else
- {
- sp_dbg_info("DelServer:DeleteSrevice() ok !");
- }
- bRet = true;
- BeforeLeave:
- if(hServiceDDK)
- {
- CloseServiceHandle(hServiceDDK); // 服务句柄
- }
- if(hServiceMgr)
- {
- CloseServiceHandle(hServiceMgr); // SCM 句柄
- }
- return bRet;
- }
- #endif //_WIN32
- void DisplayUsage()
- {
- char szHelp[1024] = { '\0' };
- sprintf_s(szHelp, 1024, "\n"
- "Usage spshell [--entity <entityName>] [--guardian] [--test] [--debug] [--ipc <pipe|tcp>]\n"
- " --entity {entityName} -- 启动指定的实体\n"
- " --guardian -- 以后台监控形式运行程序\n"
- " --test -- 以测试模式运行程序\n"
- " --debug -- 以Debug的模式运行程序\n"
- " --kill -- 直接杀死程序相关进程\n"
- " --ipc <pipe,tcp> -- pipe: 实体间以管道的方式通信;tcp: 实体间以socket的方式通信\n"
- " --version -- 查看相关模块的版本号和生成时间\n"
- #ifndef NDEBUG
- " --telnet {listern port} -- 在指定端口打开 Telnet,仅在调试版本支持 \n"
- #endif
- );
- //sp_dbg_info(szHelp);
- #ifdef _WIN32
- MessageBoxA(NULL, szHelp, "Spshell Usage Tip", MB_OK);
- #else
- printf(szHelp);
- #endif //_WIN32
- }
- const char* GetFullVersionString(bool logFlag = false)
- {
- static char szVersion[128] = {'\0'};
- if (strlen(szVersion) == 0) {
- CVersion spbase_version;
- GetLibVersion(spbase_version);
- sprintf_s(szVersion, 128, "spbase version: %s(build date: %s)%s"
- "libtoolkit version: %s",
- spbase_version.ToString().GetData(), GetLibBuildDate(), logFlag ? " " : "\n",
- toolkit_version_string());
- }
- return szVersion;
- }
- sp_cfg_start_args_t* DealWithArgs(int argc, char** argv)
- {
- int allocedEntitiyLen = 0;
- sp_cfg_start_args_t* args = MALLOC_T(sp_cfg_start_args_t);
- assert(args);
- memset(args, 0, sizeof(sp_cfg_start_args_t));
- static struct option spshell_options[] = {
- {"entity", required_argument, 0, 'E' },
- {"guardian", no_argument, 0, 'G'},
- {"test", no_argument, 0, 'T'},
- {"debug", no_argument, 0, 'D'},
- {"ipc", required_argument, 0, 'I'},
- {"shutdown", no_argument, 0, 'S'},
- {"kill", no_argument, 0, 'K'},
- #ifndef NDEBUG
- {"telnet", required_argument, 0, 'N' },
- #endif
- {"help", no_argument, 0, 'H'},
- {"version", no_argument, 0, 'V'},
- {0, 0, 0, 0}
- };
- int spshell_index = 0;
- int c;
- while ((c = getopt_long(argc, argv, "E:GTDI:?", spshell_options, &spshell_index)) != EOF) {
- switch (c) {
- case 'E':
- {
- //sp_dbg_info("start specified entity: %s", optarg);
- if (optarg != NULL) {
- const int len = strlen(optarg);
- if (args->start_entities == NULL || len + strlen(args->start_entities) + 2 /*;\0*/ >= allocedEntitiyLen) {
- if (args->start_entities == NULL) {
- assert(allocedEntitiyLen == 0);
- allocedEntitiyLen = 128;
- args->start_entities = CALLOC_T(allocedEntitiyLen, char);
- if (NULL == args->start_entities) {
- exit(-1);
- }
- }
- else {
- assert(allocedEntitiyLen != 0);
- const int newLen = allocedEntitiyLen + len + 32;
- char* newAlloc = CALLOC_T(newLen, char);
- if (NULL == newAlloc) {
- exit(-1);
- }
- memset(newAlloc, '\0', sizeof(char) * newLen);
- strcpy_s(newAlloc, newLen, args->start_entities);
- FREE(args->start_entities);
- args->start_entities = newAlloc;
- allocedEntitiyLen = newLen;
- }
- }
- strcat(args->start_entities, optarg);
- strcat(args->start_entities, ";");
- }
- }
- break;
- case 'G':
- //sp_dbg_info("run spshell as guardian mode!");
- args->guardian_mode = 1;
- break;
- case 'D':
- //sp_dbg_info("run spshell as debug mode!");
- args->debug_mode = 1;
- break;
- case 'T':
- //sp_dbg_info("run spshell as test mode!");
- args->test_mode = 1;
- break;
- case 'I':
- //sp_dbg_info("run spshell with specified ipc method: %s", optarg);
- if (optarg) {
- if (strnicmp(optarg, "tcp", strlen("tcp")) == 0)
- args->ipc_type = 1;
- }
- break;
- #ifndef NDEBUG
- case 'N':
- if (optarg) {
- int nPort = 0;
- if (0 < sscanf(optarg, "%d", &nPort))
- args->telnet_port = nPort;
- }
- break;
- #endif
- case 'K':
- {
- //sp_dbg_info("terminate spshell!");
- char* relate_processes[] = {
- #ifdef _WIN32
- "spshell.exe", "sphost.exe", "guardian.exe"
- #else
- "spshell", "sphost", "guardian"
- #endif //_WIN32
- };
- osutil_terminate_related_process(relate_processes, sizeof(relate_processes) / sizeof(relate_processes[0]));
- exit(0);
- }
- break;
- case 'V':
- {
- #ifdef _WIN32
- MessageBoxA(NULL, GetFullVersionString(), "Spshell", MB_OK);
- #else
- printf("%s\n", GetFullVersionString());
- #endif //_WIN32
- exit(0);
- break;
- }
- break;
- case 'H':
- case '?':
- default:
- DisplayUsage();
- exit(0);
- break;
- }
- }
- if (optind < argc) {
- //sp_dbg_warn("non-option ARGV-elements: ");
- while (optind < argc) {
- //sp_dbg_warn("\t%s", argv[optind++]);
- }
- }
- if (args && args->start_entities != 0) {
- args->start_entities[strlen(args->start_entities) - 1] = '\0';
- }
- return args;
- }
- int main(int argc, char** argv)
- {
- sp_cfg_start_args_t* args = DealWithArgs(argc, argv);
- #if (0 && defined(_WIN32))
- char szProcessID[12];
- sprintf(szProcessID, "%u", GetCurrentProcessId());
- MessageBoxA(NULL, szProcessID, "", MB_OK);
- #endif //_WIN32
- if (args->debug_mode)
- { //open wlog
- SP::Perf::LeakDetector leakInstance;
- WLog_initRVC("SpShell");
- }
- #ifdef _WIN32
- _CrtSetDebugFillThreshold(0);
- #endif //_WIN32
- sp_dbg_init("SpShell");
- sp_dbg_info("===================SpShell start=====================");
- if (argc > 1) {
- char cmdline[1024] = { '\0' };
- for (int i = 0; i < argc; ++i) {
- sprintf_s(cmdline, 1024, "%s %s", cmdline, argv[i]);
- }
- sp_dbg_info(cmdline);
- }
- sp_dbg_info(GetFullVersionString(true));
- char proc1[64] = { '\0' };
- char proc2[64] = { '\0' };
- #ifdef _WIN32
- strcpy(proc1, "SpShell.exe");
- strcpy(proc2, "SpHost.exe");
- #else
- strcpy(proc1, "spshell");
- strcpy(proc2, "sphost");
- #endif //_WIN32
- char* arrProcName[] = { proc1, proc2 };
- //DetectDuplicateInstance
- if(!osutil_detect_unique_app(&arrProcName[0], sizeof(arrProcName) / sizeof(arrProcName[0])))
- {
- sp_dbg_fatal("detect duplicate spshell/sphost process, abort cur boot !!!");
- Sleep(10000);
- sp_dbg_term();
- return -200;
- }
- if (!IsProcessRunAsAdmin())
- {
- #ifdef _WIN32
- MessageBox(NULL, "Need run with Administrator privilege!", "Error", MB_OK);
- #else
- sp_dbg_fatal("current process need run with administrator or root privilege !!!");
- #endif //_WIN32
-
- Sleep(10000);
- sp_dbg_term();
- return -201;
- } else {
- sp_dbg_info("current process has been run with administrator or root privilege.");
- }
- #ifdef _WIN32
- // 设置防火墙注册表配置
- AddFirewallRulesEx();
- // 自动隐藏状态栏
- //AutoHideTaskBar(true);
- #endif //_WIN32
-
- #ifdef _WIN32
- setlocale(LC_ALL, "chs");
- #else
- if (NULL == setlocale(LC_ALL, "zh_CN.UTF-8")) {
- //zh_CN.UTF-8 zh_CN.GBK
- sp_dbg_error("setlocale failed: %s", strerror(errno));
- }
- sp_dbg_info("测试中文字符:%s", "招商银行");
- #endif //_WIN32
- SetEnvPath();
- #ifdef _WIN32
- SetWorkingSet();
- SetUnhandledExceptionFilter(&SuppressError);
- DisableSetUnhandledExceptionFilter();
- #endif //_WIN32
- sp_dbg_info("basic config success");
- #ifdef _WIN32
- // 检测是否Win8及64位
- OSVERSIONINFO ver = {};
- ver.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
- GetVersionEx(&ver);
- bool bWin8 = (ver.dwMajorVersion >= 7 || (ver.dwMajorVersion == 6 && ver.dwMinorVersion >= 2));
- SYSTEM_INFO sysInfo = {};
- GetNativeSystemInfo(&sysInfo);
- bool bX64 = (sysInfo.wProcessorArchitecture == PROCESSOR_ARCHITECTURE_AMD64);
- sp_dbg_info("OS version: %s %d.%d.%d ", bX64 ? "windows 64" : "windows 32", ver.dwMajorVersion, ver.dwMinorVersion, ver.dwBuildNumber);
- // 关闭WebBrowser渲染模式
- //DisableWebBrowserRenderMode(bX64);
- // 屏蔽CharmBar
- if (bWin8 && !DisableWindowsCharmBar(bX64))
- {
- Sleep(10000);
- return -300;
- }
- //#ifndef _DEBUG
- SetErrorMode(SEM_FAILCRITICALERRORS);
- //#endif
- #endif //_WIN32
-
- auto rc = app_init(args);
- FREE(args);
- if (rc == 0)
- {
- #ifdef _WIN32
- WebcamMicrophoneAuthorize(bX64);
- #endif //_WIN32
- rc = app_run();
- app_term();
- }
- else
- {
- sp_dbg_error("======================================================");
- sp_dbg_error("!!!!!! Startup failed, get more detail information from dbg/spshell !!!!!!");
- sp_dbg_error("======================================================");
- Sleep(10000);
- }
- #ifdef _WIN32
- if (bWin8 && !bX64) {
- EnableCharmbar();
- }
- // 显示状态栏
- //AutoHideTaskBar(false);
- #endif //_WIN32
- sp_dbg_term();
- return rc;
- }
- #ifdef _WIN32
- int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nShowCmd)
- {
- return main(__argc, __argv);
- }
- #endif //_WIN32
|