RDPWInst.cpp 51 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821
  1. // RDPWInst.cpp : 定义控制台应用程序的入口点。
  2. //
  3. #include "stdafx.h"
  4. #include <Windows.h>
  5. #include <process.h>
  6. #include <tchar.h>
  7. #include <Winsvc.h>
  8. #include <stdio.h>
  9. #include <strsafe.h>
  10. #include "FreeRDPErrorCode.h"
  11. #include "RDPWInst.h"
  12. #include "phnt\winsta.h"
  13. #pragma comment(lib, "Userenv.lib")
  14. #pragma comment(lib, "WtsApi32.lib")
  15. #pragma comment(lib, "version.lib")
  16. #define TERM_SERVICE TEXT("TermService")
  17. #define SVC_CERT_PROP TEXT("CertPropSvc")
  18. #define SVC_SEESSION_ENV TEXT("SessionEnv")
  19. #define RDP_WRAP_BINARY TEXT("\\bin\\RDPWrap.dll")
  20. #define RDP_WRAP_BINARY64 TEXT("\\bin\\RDPWrap64.dll")
  21. #define RDP_WRAP_CONFIG_FILE TEXT("\\cfg\\rdpwrap.ini")
  22. #define RDP_WRAP_CONFIG_FILE64 TEXT("\\cfg\\rdpwrap.ini")
  23. #define DEFAULT_TERMSRV_PATH TEXT("%SystemRoot%\\System32\\termsrv.dll")
  24. typedef BOOL(WINAPI *PFuncWow64DisableWow64FsRedirection)(PVOID);
  25. typedef BOOL(WINAPI *PFuncWow64RevertWow64FsRedirection)(PVOID);
  26. typedef BOOL(WINAPI *PFuncWow64EnableWow64FsRedirection)(BOOLEAN);
  27. typedef BOOLEAN(WINAPI *PFuncWinStationEnumerateW)(
  28. _In_opt_ HANDLE hServer,
  29. _Out_ PSESSIONIDW *SessionIds,
  30. _Out_ PULONG Count
  31. );
  32. typedef BOOL(WINAPI *PFuncWinStationFreeMemory)(
  33. _In_ PVOID Buffer);
  34. TCHAR gszTermServicePath[MAX_PATH] = { 0 };
  35. TCHAR gszExistedTSPath[MAX_PATH] = { 0 };
  36. int gArch = 0;
  37. int Will = (int)Invalid;
  38. FILE_VERSION FV = { 0 };
  39. BOOL bEnterWowRedirect = FALSE;
  40. BOOLEAN RevertWowRedirection();
  41. BOOL DisableWowRedirection();
  42. void EnterWowRedirection()
  43. {
  44. if(gArch == 64) {
  45. if(!bEnterWowRedirect) {
  46. DisableWowRedirection();
  47. bEnterWowRedirect = TRUE;
  48. }
  49. }
  50. }
  51. void LeaveWowRedirection()
  52. {
  53. if(gArch == 64) {
  54. if(bEnterWowRedirect) {
  55. RevertWowRedirection();
  56. bEnterWowRedirect = FALSE;
  57. }
  58. }
  59. }
  60. DWORD ToLowerCase(TCHAR *szChars)
  61. {
  62. if (szChars == NULL) {
  63. return 0;
  64. }
  65. DWORD charsLen = lstrlen(szChars);
  66. DWORD dwCount = 0;
  67. for (DWORD i = 0; i < charsLen; ++i) {
  68. if (szChars[i] >= 'A' && szChars[i] <= 'Z') {
  69. szChars[i] = szChars[i] + ('a' - 'A');
  70. dwCount++;
  71. }
  72. }
  73. return dwCount;
  74. }
  75. //#define IFCALLEXIT(_cb) do { if ( TRUE != (_cb) ) { AppQuit(-1); } } while (0)
  76. #define IFCALLEXIT_WITH_RESULT(_cb, exit_code) \
  77. do { if ( TRUE != (_cb) ) { \
  78. AppQuit(exit_code); goto Error; } \
  79. } while (0)
  80. VOID AppQuit(int nExitCode);
  81. VOID RestartTsvProcess();
  82. BOOL CheckTsvRestarted(DWORD dwLastPID);
  83. BOOL IsFileExisted(LPCTSTR lpszSpecifiedPath)
  84. {
  85. auto dwRet = GetFileAttributes(lpszSpecifiedPath);
  86. return (dwRet != INVALID_FILE_ATTRIBUTES) && !(dwRet & FILE_ATTRIBUTE_DIRECTORY);
  87. }
  88. /*the lpszSpecifiedValue must be all lower char*/
  89. BOOL IsTermsrvHasBeenReplaced(LPCTSTR lpszSpecifiedValue, BOOL& bThirdParty)
  90. {
  91. if(lpszSpecifiedValue == NULL || _tcslen(gszTermServicePath) == 0)
  92. {
  93. bThirdParty = FALSE;
  94. return FALSE;
  95. }
  96. if (_tcsstr(lpszSpecifiedValue, TEXT("termsrv.dll")) != NULL)
  97. {
  98. return FALSE;
  99. }
  100. if (_tcsstr(lpszSpecifiedValue, TEXT("rdpwrap.dll")) != NULL
  101. || _tcsstr(lpszSpecifiedValue, TEXT("rdpwrap64.dll")) != NULL)
  102. {
  103. bThirdParty = FALSE;
  104. return TRUE;
  105. }
  106. bThirdParty = TRUE;
  107. return TRUE;
  108. }
  109. DWORD ExpandPath(LPCTSTR lpcszOriginal, LPTSTR lpDest, const DWORD dwDestSize)
  110. {
  111. //StringReplace(Path, '%ProgramFiles%', '%ProgramW6432%', [rfReplaceAll, rfIgnoreCase]);
  112. DWORD dwBufSize = ExpandEnvironmentStrings(lpcszOriginal, lpDest, dwDestSize);
  113. if (dwBufSize > dwDestSize) {
  114. Dbg(TEXT("[!] Buffer is too small to convert envstring \"%s\"."), lpcszOriginal);
  115. }
  116. return dwBufSize;
  117. }
  118. BOOL GetWrapperDllPath(TCHAR szWrapPath[], const DWORD dwPathSize)
  119. {
  120. DWORD nLocLen = 0;
  121. nLocLen = GetCurrentDirectory(dwPathSize, szWrapPath);
  122. if (nLocLen == 0)
  123. {
  124. Dbg(TEXT("[-] GetCurrentDirectory failed with status %d"), GetLastError());
  125. return FALSE;
  126. }
  127. if (FAILED(StringCbCat(szWrapPath, dwPathSize, gArch == 64 ? RDP_WRAP_BINARY64 : RDP_WRAP_BINARY)))
  128. {
  129. Dbg(TEXT("[-] StringCbCatW failed with error %d"), GetLastError());
  130. return FALSE;
  131. }
  132. Dbg(TEXT("[*] RDP wrap executable file path : <%s>"), szWrapPath);
  133. if (!IsFileExisted(szWrapPath))
  134. {
  135. Dbg(TEXT("[-] detect the above file is not exist !!!"));
  136. return FALSE;
  137. }
  138. return TRUE;
  139. }
  140. BOOL GetWrapperINIPath(TCHAR szWrapPath[], const DWORD dwPathSize)
  141. {
  142. DWORD nLocLen = 0;
  143. nLocLen = GetCurrentDirectory(dwPathSize, szWrapPath);
  144. if (nLocLen == 0)
  145. {
  146. Dbg(TEXT("[-] GetCurrentDirectory failed with status %d"), GetLastError());
  147. return FALSE;
  148. }
  149. if (FAILED(StringCbCat(szWrapPath, dwPathSize, gArch == 64 ? RDP_WRAP_CONFIG_FILE64 : RDP_WRAP_CONFIG_FILE)))
  150. {
  151. Dbg(TEXT("[-] StringCbCatW failed with error %d"), GetLastError());
  152. return FALSE;
  153. }
  154. Dbg(TEXT("[*] RDP wrap config file path : <%s>"), szWrapPath);
  155. if (!IsFileExisted(szWrapPath))
  156. {
  157. Dbg(TEXT("[-] detect the above file is not exist !!!"));
  158. return FALSE;
  159. }
  160. return TRUE;
  161. }
  162. BOOL CheckIfSectionExist(TCHAR* szFilePath, char* szSection)
  163. {
  164. BOOL fExist = FALSE;
  165. DWORD NumberOfBytesRead = 0;
  166. DWORD FileSize;
  167. char *FileRaw = NULL;
  168. HANDLE hFile = CreateFile(szFilePath, GENERIC_READ, FILE_SHARE_WRITE | FILE_SHARE_READ,
  169. NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
  170. if (hFile == INVALID_HANDLE_VALUE)
  171. {
  172. return FALSE;
  173. }
  174. FileSize = GetFileSize(hFile, NULL);
  175. if (FileSize == INVALID_FILE_SIZE)
  176. {
  177. return FALSE;
  178. }
  179. FileRaw = new char[FileSize];
  180. fExist = ReadFile(hFile, FileRaw, FileSize, &NumberOfBytesRead, NULL);
  181. if (fExist)
  182. {
  183. fExist = !!strstr(FileRaw, szSection);
  184. }
  185. delete FileRaw;
  186. CloseHandle(hFile);
  187. return fExist;
  188. }
  189. BOOL ExtractFiles()
  190. {
  191. BOOL fResult = FALSE;
  192. /*
  193. WrapPath =: C:\\Program files\\RDP Wrapper
  194. if not exist
  195. create it
  196. if create failed
  197. halt false
  198. if update-online from center setting.
  199. download lastest ini-file
  200. suc: s := wrapPath + 'rdpwrap.ini'
  201. if not update-online or update-failed
  202. s := localPath + 'rdpwrap.ini'
  203. extract 'rdpclip.exe'
  204. %SystemRoot%\System32\rdpclip.exe
  205. '%SystemRoot%\System32\rfxvmt.dll
  206. */
  207. return fResult;
  208. }
  209. BOOL SetWrapperDll(LPTSTR lpWrapPath)
  210. {
  211. if (lpWrapPath == NULL) {
  212. return FALSE;
  213. }
  214. DWORD dwLen = (_tcsclen(lpWrapPath) + 1)*sizeof(TCHAR);
  215. DWORD dwFlag = KEY_WRITE;
  216. if (gArch == 64) {
  217. dwFlag |= KEY_WOW64_64KEY;
  218. }
  219. BOOL fResult = FALSE;
  220. HKEY hKey;
  221. LONG lResult = RegOpenKeyEx(HKEY_LOCAL_MACHINE,
  222. TEXT("SYSTEM\\CurrentControlSet\\Services\\TermService\\Parameters"),
  223. 0, dwFlag, &hKey);
  224. if (lResult == ERROR_SUCCESS) {
  225. lResult = RegSetValueEx(hKey, TEXT("ServiceDll"), 0, REG_EXPAND_SZ, (const BYTE*)lpWrapPath, dwLen);
  226. if (lResult == ERROR_SUCCESS) {
  227. Dbg(TEXT("[+] RegSetValueEx succ: %s"), lpWrapPath);
  228. if ((gArch == 64) && (FV.w.Major == 6) && (FV.w.Minor == 0)) {
  229. TCHAR szRegExe[MAX_PATH] = { 0 };
  230. ExpandPath(TEXT("%SystemRoot%"), szRegExe, MAX_PATH);
  231. _tcscat_s(szRegExe, TEXT("\\system32\\reg.exe"));
  232. TCHAR szParameters[MAX_PATH] = { 0 };
  233. sprintf_s(szParameters, TEXT("ADD HKLM\\SYSTEM\\CurrentControlSet\\Services\\TermService\\Parameters /v ServiceDll /t REG_EXPAND_SZ /d %s /f"), lpWrapPath);
  234. //添加一个值<名称:ServiceDll,类型:REG_EXPAND_SZ,数据:>,不用提示并强行覆盖现有注册表项
  235. Dbg(TEXT("[+] Parameters: %s"), szParameters);
  236. if (!_spawnl(_P_WAIT, szRegExe, TEXT("reg.exe"), szParameters, NULL)) {
  237. Dbg(TEXT("[+] _wspawnl succ."));
  238. fResult = TRUE;
  239. }
  240. else {
  241. Dbg(TEXT("[-] _wspawnl error."));
  242. }
  243. }
  244. else {
  245. fResult = TRUE;
  246. }
  247. }
  248. }
  249. else {
  250. Dbg(TEXT("[-] RegOpenKeyEx error returned %u, GLE=%u."), lResult, GetLastError());
  251. }
  252. RegCloseKey(hKey);
  253. return fResult;
  254. }
  255. BOOL ResetServiceDll()
  256. {
  257. DWORD dwFlag = KEY_WRITE;
  258. if (gArch == 64) {
  259. dwFlag |= KEY_WOW64_64KEY;
  260. }
  261. BOOL fResult = FALSE;
  262. HKEY hKey;
  263. LONG lResult = RegOpenKeyEx(HKEY_LOCAL_MACHINE, TEXT("SYSTEM\\CurrentControlSet\\Services\\TermService\\Parameters"),
  264. 0, dwFlag, &hKey);
  265. if (lResult == ERROR_SUCCESS) {
  266. TCHAR szTermsrv[MAX_PATH] = DEFAULT_TERMSRV_PATH;
  267. DWORD dwLen = (_tcslen(DEFAULT_TERMSRV_PATH) + 1)*sizeof(TCHAR);
  268. lResult = RegSetValueEx(hKey, TEXT("ServiceDll"), 0, REG_EXPAND_SZ, (const BYTE*)szTermsrv, dwLen);
  269. if (lResult == ERROR_SUCCESS) {
  270. Dbg(TEXT("[+] RegSetValueEx succ: %s"), szTermsrv);
  271. fResult = TRUE;
  272. }
  273. else {
  274. Dbg(TEXT("[-] RegSetValueEx \"%s\" error returned %u, GLE=%u."), szTermsrv, lResult, GetLastError());
  275. }
  276. }
  277. else {
  278. Dbg(TEXT("[-] RegOpenKeyEx \"SYSTEM\\CurrentControlSet\\Services\\TermService\\Parameters\" error returned %u, GLE=%u."), lResult, GetLastError());
  279. }
  280. RegCloseKey(hKey);
  281. return fResult;
  282. }
  283. BOOL ExtractResource(LPTSTR lpDestPath)
  284. {
  285. HMODULE hModule = NULL;
  286. HRSRC hrSRC = FindResource(hModule, TEXT(""), RT_RCDATA);
  287. return TRUE;
  288. }
  289. INT SvcGetStarType(LPCTSTR lpcSvcName)
  290. {
  291. INT nResult = -1;
  292. SC_HANDLE hSC = NULL;
  293. SC_HANDLE hSvc = NULL;
  294. LPQUERY_SERVICE_CONFIG lpServiceConfig;
  295. Dbg(TEXT("[*] Checking %s ..."), lpcSvcName);
  296. hSC = OpenSCManager(NULL, SERVICES_ACTIVE_DATABASE, SC_MANAGER_CONNECT);
  297. if (hSC == NULL) {
  298. Dbg(TEXT("[-] OpenSCManager error GLE=%u."), GetLastError());
  299. }
  300. else {
  301. hSvc = OpenService(hSC, lpcSvcName, SERVICE_QUERY_CONFIG);
  302. if (hSvc == NULL) {
  303. Dbg(TEXT("[-] OpenService for \"%s\" error GLE=%u."), lpcSvcName, GetLastError());
  304. }
  305. else {
  306. DWORD dwByteNeeded;
  307. DWORD dwBufSize;
  308. BOOL fResult = QueryServiceConfig(hSvc, NULL, 0, &dwByteNeeded);
  309. if (!fResult && ERROR_INSUFFICIENT_BUFFER == GetLastError()) {
  310. dwBufSize = dwByteNeeded;
  311. lpServiceConfig = (LPQUERY_SERVICE_CONFIG)LocalAlloc(LMEM_FIXED, dwBufSize);
  312. if (!QueryServiceConfig(hSvc, lpServiceConfig, dwBufSize, &dwByteNeeded)) {
  313. Dbg(TEXT("[-] QueryServiceConfig twice error GLE=%u."), GetLastError());
  314. }
  315. else {
  316. nResult = lpServiceConfig->dwStartType;
  317. }
  318. LocalFree(lpServiceConfig);
  319. }
  320. else {
  321. Dbg(TEXT("[-] QueryServiceConfig error GLE=%u."), GetLastError());
  322. }
  323. }
  324. }
  325. CloseServiceHandle(hSC);
  326. CloseServiceHandle(hSvc);
  327. return nResult;
  328. }
  329. BOOL SvcConfigStarType(LPCTSTR lpcSvcName, DWORD dwStartType)
  330. {
  331. SC_HANDLE hSC = NULL;
  332. SC_HANDLE hSvc = NULL;
  333. BOOL fResult = FALSE;
  334. Dbg(TEXT("[*] Configuring %s ..."), lpcSvcName);
  335. hSC = OpenSCManager(NULL, SERVICES_ACTIVE_DATABASE, SC_MANAGER_CONNECT);
  336. if (hSC == NULL) {
  337. Dbg(TEXT("[-] OpenSCManager error GLE=%u."), GetLastError());
  338. }
  339. else {
  340. hSvc = OpenService(hSC, lpcSvcName, SERVICE_CHANGE_CONFIG);
  341. if (hSvc == NULL) {
  342. Dbg(TEXT("[-] OpenService with \"%s\" for change-config error GLE=%u."), lpcSvcName, GetLastError());
  343. }
  344. else {
  345. if (ChangeServiceConfig(hSvc, SERVICE_NO_CHANGE, dwStartType, SERVICE_NO_CHANGE, NULL, NULL, NULL, NULL,
  346. NULL, NULL, NULL)) {
  347. fResult = TRUE;
  348. }
  349. else {
  350. Dbg(TEXT("[-] ChangeServiceConfig error GLE=%u."), GetLastError());
  351. }
  352. }
  353. }
  354. CloseServiceHandle(hSvc);
  355. CloseServiceHandle(hSC);
  356. return fResult;
  357. }
  358. BOOL SvcStartService(LPCTSTR lpcSvcName, DWORD dwLastProID = 0)
  359. {
  360. BOOL fResult = FALSE;
  361. SC_HANDLE hSC = NULL;
  362. SC_HANDLE hSvc = NULL;
  363. Dbg(TEXT("[*] Starting service %s ..."), lpcSvcName);
  364. hSC = OpenSCManager(NULL, SERVICES_ACTIVE_DATABASE, SC_MANAGER_CONNECT);
  365. if (hSC == NULL) {
  366. Dbg(TEXT("[-] OpenSCManager error GLE=%u."), GetLastError());
  367. goto FAILED;
  368. }
  369. else {
  370. hSvc = OpenService(hSC, lpcSvcName, SERVICE_START);
  371. if (hSvc == NULL) {
  372. Dbg(TEXT("[-] OpenService with \"%s\" for start error GLE=%u."), lpcSvcName, GetLastError());
  373. goto FAILED;
  374. }
  375. else {
  376. fResult = StartService(hSvc, 0, NULL);
  377. if (!fResult) {
  378. DWORD dwError = GetLastError();
  379. if (dwError == ERROR_SERVICE_ALREADY_RUNNING) {
  380. Dbg(TEXT("[!] Service already started or SCM hasn't registered killed process."));
  381. Sleep(2000);
  382. fResult = StartService(hSvc, 0, NULL);
  383. if (!fResult) {
  384. Dbg(TEXT("[-] StartService twice error GLE=%u."), GetLastError());
  385. if (!_tcsicmp(lpcSvcName, TERM_SERVICE) && CheckTsvRestarted(dwLastProID)) {
  386. } else {
  387. goto FAILED;
  388. }
  389. }
  390. }
  391. else {
  392. Dbg(TEXT("[-] StartService error GLE=%u."), dwError);
  393. goto FAILED;
  394. }
  395. }
  396. }
  397. }
  398. fResult = TRUE;
  399. FAILED:
  400. if (hSvc != NULL) {
  401. CloseServiceHandle(hSvc);
  402. }
  403. if (hSC != NULL) {
  404. CloseServiceHandle(hSC);
  405. }
  406. return fResult;
  407. }
  408. BOOL SetPrivilege(HANDLE hToken, LPCTSTR lpszPrivilege, BOOL bEnablePrivilege)
  409. {
  410. TOKEN_PRIVILEGES tp;
  411. LUID luid;
  412. if (!LookupPrivilegeValue(
  413. NULL, // lookup privilege on local system
  414. lpszPrivilege, // privilege to lookup
  415. &luid)) // receives LUID of privilege
  416. {
  417. Dbg(TEXT("[-] LookupPrivilegeValue error: %u"), GetLastError());
  418. return FALSE;
  419. }
  420. tp.PrivilegeCount = 1;
  421. tp.Privileges[0].Luid = luid;
  422. if (bEnablePrivilege)
  423. tp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
  424. else
  425. tp.Privileges[0].Attributes = 0;
  426. // Enable the privilege or disable all privileges.
  427. if (!AdjustTokenPrivileges(
  428. hToken,
  429. FALSE,
  430. &tp,
  431. sizeof(TOKEN_PRIVILEGES),
  432. (PTOKEN_PRIVILEGES)NULL,
  433. (PDWORD)NULL))
  434. {
  435. Dbg(TEXT("[-] AdjustTokenPrivileges error: %u"), GetLastError());
  436. return FALSE;
  437. }
  438. if (GetLastError() == ERROR_NOT_ALL_ASSIGNED)
  439. {
  440. Dbg(TEXT("[-] The token does not have the specified privilege. "));
  441. return FALSE;
  442. }
  443. return TRUE;
  444. }
  445. BOOL AddPrivilege(LPCTSTR lpszPrivilege)
  446. {
  447. HANDLE hToken = NULL;
  448. if (!OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, &hToken)) {
  449. Dbg(TEXT("[-] OpenProcessToken error, GLE=%u."), GetLastError());
  450. return FALSE;
  451. }
  452. return SetPrivilege(hToken, lpszPrivilege, TRUE);
  453. }
  454. BOOL KillProcess(DWORD dwProcessID)
  455. {
  456. BOOL fResult = FALSE;
  457. HANDLE hProc = OpenProcess(PROCESS_TERMINATE, FALSE, dwProcessID);
  458. if (hProc == NULL) {
  459. Dbg(TEXT("[-] OpenProcess error: %u"), GetLastError());
  460. }
  461. else if (!TerminateProcess(hProc, 0)) {
  462. Dbg(TEXT("[-] TerminateProcess error: %u"), GetLastError());
  463. }
  464. else {
  465. Dbg(TEXT("[+] TerminateProcess <pid %d> succ."), dwProcessID);
  466. fResult = TRUE;
  467. }
  468. CloseHandle(hProc);
  469. return fResult;
  470. }
  471. VOID CheckTermsrvDependencies()
  472. {
  473. if (SvcGetStarType(SVC_CERT_PROP) == SERVICE_DISABLED) {
  474. SvcConfigStarType(SVC_CERT_PROP, SERVICE_DEMAND_START);
  475. }
  476. if (SvcGetStarType(SVC_SEESSION_ENV) == SERVICE_DISABLED) {
  477. SvcConfigStarType(SVC_SEESSION_ENV, SERVICE_DEMAND_START);
  478. }
  479. }
  480. /*
  481. * dwDepCount[in and out]
  482. */
  483. VOID CheckTermsrvProcess(DWORD& dwProcessID, TCHAR pszDependencySvc[][MAX_PATH], DWORD& dwDepCount)
  484. {
  485. SC_HANDLE hSC;
  486. DWORD dwNeedBytes, dwReturnBytes, dwResumeHandle;
  487. BOOL fFound = FALSE, fStarted = FALSE, fResult = FALSE;
  488. TCHAR szTermServiceName[MAX_PATH];
  489. DWORD dwTermServicePID = 0;
  490. DWORD dwErrorCode = 0;
  491. hSC = OpenSCManager(NULL, SERVICES_ACTIVE_DATABASE, SC_MANAGER_CONNECT | SC_MANAGER_ENUMERATE_SERVICE);
  492. if (hSC == NULL) {
  493. Dbg(TEXT("[-] OpenSCManager error GLE=%u."), GetLastError());
  494. }
  495. else {
  496. Refresh:
  497. dwResumeHandle = 0;
  498. //TODO: 1489 !!!
  499. ENUM_SERVICE_STATUS_PROCESS svcs[1489];
  500. ZeroMemory(svcs, sizeof(ENUM_SERVICE_STATUS_PROCESS) * 1489);
  501. fResult = EnumServicesStatusEx(hSC, SC_ENUM_PROCESS_INFO, SERVICE_WIN32, SERVICE_STATE_ALL,
  502. (LPBYTE)&svcs[0], sizeof(svcs[0]) * 1489, &dwNeedBytes, &dwReturnBytes, &dwResumeHandle, NULL);
  503. if (fResult) {
  504. for (int i = 0; i < 1489; ++i) {
  505. if (svcs[i].lpServiceName != NULL) {
  506. if (!_tcsicmp(svcs[i].lpServiceName, TERM_SERVICE)) {
  507. fFound = TRUE;
  508. _tcscpy_s(szTermServiceName, svcs[i].lpServiceName);
  509. dwTermServicePID = svcs[i].ServiceStatusProcess.dwProcessId;
  510. dwProcessID = dwTermServicePID;
  511. break;
  512. }
  513. }
  514. }
  515. if (!fFound) {
  516. Dbg(TEXT("[-] TermService not found."));
  517. }
  518. else if (dwProcessID == 0) {
  519. if (fStarted) {
  520. Dbg(TEXT("[-] Failed to set up TermService. Unknown error."));
  521. }
  522. else {
  523. SvcConfigStarType(TERM_SERVICE, SERVICE_AUTO_START);
  524. SvcStartService(TERM_SERVICE);
  525. fStarted = TRUE;
  526. goto Refresh;
  527. }
  528. }
  529. else {
  530. Dbg(TEXT("[+] TermService found (pid %u)."), dwProcessID);
  531. //Found Shared service (maybe).
  532. const DWORD dwMaxSize = dwDepCount;
  533. if (dwMaxSize > 0) {
  534. DWORD nCount = 0;
  535. for (int i = 0; i < 1489; ++i) {
  536. if (svcs[i].lpServiceName != NULL && svcs[i].ServiceStatusProcess.dwProcessId == dwTermServicePID) {
  537. if (_tcsicmp(svcs[i].lpServiceName, TERM_SERVICE)) {
  538. _tcscpy_s(pszDependencySvc[nCount++], svcs[i].lpServiceName);
  539. if (nCount > dwMaxSize) {
  540. Dbg(TEXT("[!] Shared TermService out of range."));
  541. break;
  542. }
  543. }
  544. }
  545. }
  546. dwDepCount = nCount;
  547. if (nCount > 0) {
  548. for (DWORD i = 0; i < nCount; ++i) {
  549. if (i == 0) {
  550. Dbg(TEXT("[*] Shared services found:"));
  551. }
  552. Dbg(TEXT("[*] >>> %s"), pszDependencySvc[i]);
  553. }
  554. }
  555. else {
  556. Dbg(TEXT("[*] No shared services found."));
  557. }
  558. }
  559. else {
  560. dwDepCount = 0;
  561. for (int i = 0; i < 1489; ++i) {
  562. if (svcs[i].lpServiceName != NULL && svcs[i].ServiceStatusProcess.dwProcessId == dwTermServicePID) {
  563. if (_tcsnicmp(svcs[i].lpServiceName, TERM_SERVICE, _tclen(TERM_SERVICE))) {
  564. dwDepCount++;
  565. }
  566. }
  567. }
  568. }
  569. }
  570. }
  571. else {
  572. dwErrorCode = GetLastError();
  573. /*if (dwErrorCode == ERROR_MORE_DATA) {
  574. }
  575. else*/ {
  576. CloseServiceHandle(hSC);
  577. Dbg(TEXT("[-] EnumServicesStatusEx error GLE=%u."), dwErrorCode);
  578. return;
  579. }
  580. }
  581. }
  582. }
  583. BOOL GetFileVersion(LPCTSTR lptstrFilename, FILE_VERSION *FileVersion)
  584. {
  585. typedef struct
  586. {
  587. WORD wLength;
  588. WORD wValueLength;
  589. WORD wType;
  590. WCHAR szKey[16];
  591. WORD Padding1;
  592. VS_FIXEDFILEINFO Value;
  593. WORD Padding2;
  594. WORD Children;
  595. } VS_VERSIONINFO;
  596. if (lptstrFilename == NULL) {
  597. Dbg(TEXT("[-] Invalid file path for GetFileVersion."));
  598. return FALSE;
  599. }
  600. Dbg(TEXT("[*] Fetch file version : %s"), lptstrFilename);
  601. HMODULE hFile = LoadLibraryEx(lptstrFilename, NULL, LOAD_LIBRARY_AS_DATAFILE);
  602. if (!hFile)
  603. {
  604. return FALSE;
  605. }
  606. HRSRC hResourceInfo = FindResourceW(hFile, (LPCWSTR)1, (LPCWSTR)0x10);
  607. if (!hResourceInfo)
  608. {
  609. return FALSE;
  610. }
  611. VS_VERSIONINFO *VersionInfo = (VS_VERSIONINFO*)LoadResource(hFile, hResourceInfo);
  612. if (!VersionInfo)
  613. {
  614. return FALSE;
  615. }
  616. memcpy_s(&(FileVersion->w), sizeof(DWORD), &(VersionInfo->Value.dwFileVersionMS), sizeof(DWORD));
  617. //FileVersion->Version.dw = VersionInfo->Value.dwFileVersionMS;
  618. FileVersion->Release = (WORD)(VersionInfo->Value.dwFileVersionLS >> 16);
  619. FileVersion->Build = (WORD)VersionInfo->Value.dwFileVersionLS;
  620. FileVersion->fDebug = !!((VersionInfo->Value.dwFileFlags & VFF_DEBUG) == VFF_DEBUG);
  621. FileVersion->fPrerelease = !!((VersionInfo->Value.dwFileFlags & VFF_PRERELEASE) == VFF_PRERELEASE);
  622. FileVersion->fPrivate = !!((VersionInfo->Value.dwFileFlags & VFF_PRIVATE) == VFF_PRIVATE);
  623. FileVersion->fSpecial = !!((VersionInfo->Value.dwFileFlags & VFF_SPECIAL) == VFF_SPECIAL);
  624. return TRUE;
  625. }
  626. BOOL SupportedArchitecture(int& arch)
  627. {
  628. if(gArch != 0) {
  629. arch = gArch;
  630. return TRUE;
  631. }
  632. SYSTEM_INFO si = { 0 };
  633. GetNativeSystemInfo(&si);
  634. BOOL Result = FALSE;
  635. switch (si.wProcessorArchitecture)
  636. {
  637. case 0:
  638. gArch = 32;
  639. Result = TRUE; // Intel x86
  640. break;
  641. case 6:
  642. Result = FALSE; // Itanium-based x64
  643. break;
  644. case 9:
  645. gArch = 64;
  646. Result = TRUE; // Intel/AMD x64
  647. break;
  648. default:
  649. Result = FALSE;
  650. break;
  651. }
  652. arch = gArch;
  653. return Result;
  654. }
  655. BOOL CheckTermsrvVersion()
  656. {
  657. TCHAR szTermServicePath[MAX_PATH] = { 0 };
  658. TCHAR szTermServiceSlimPath[MAX_PATH] = { 0 };
  659. _tcscpy_s(szTermServiceSlimPath, DEFAULT_TERMSRV_PATH);
  660. ExpandPath(szTermServiceSlimPath, szTermServicePath, MAX_PATH);
  661. FILE_VERSION fv = { 0 };
  662. GetFileVersion(szTermServicePath, &fv);
  663. TCHAR szVersion[64] = { 0 };
  664. sprintf_s(szVersion, TEXT("%d.%d.%d.%d"), fv.w.Major, fv.w.Minor, fv.Release, fv.Build);
  665. Dbg(TEXT("[*] Terminal Services version: %s"), szVersion);
  666. CopyMemory(&FV, &fv, sizeof(FILE_VERSION));
  667. if (fv.w.Major == 5 && fv.w.Minor == 1) {
  668. if (gArch == 32) {
  669. Dbg(TEXT("[!] Windows XP is not supported."));
  670. Dbg(TEXT("You may take a look at RDP Realtime Patch by Stas''M for Windows XP"));
  671. }
  672. else if (gArch == 64) {
  673. Dbg(TEXT("[!] Windows XP 64-bit Edition is not supported."));
  674. }
  675. return FALSE;
  676. }
  677. if (fv.w.Major == 5 && fv.w.Minor == 2) {
  678. if (gArch == 32) {
  679. Dbg(TEXT("[!] Windows Server 2003 is not supported."));
  680. }
  681. else if (gArch == 64) {
  682. Dbg(TEXT("[!] Windows Server 2003 or XP 64-bit Edition is not supported."));
  683. }
  684. return FALSE;
  685. }
  686. int situation = 0;
  687. if (fv.w.Major == 6 && fv.w.Minor == 0) {
  688. situation = 1;
  689. if (gArch == 32 && fv.Release == 6000 && fv.Build == 16386) {
  690. Dbg(TEXT("[!] This version of Terminal Services may crash on logon attempt."));
  691. Dbg(TEXT("It''s recommended to upgrade to Service Pack 1 or higher."));
  692. }
  693. }
  694. if (fv.w.Major == 6 && fv.w.Minor == 1) {
  695. situation = 1;
  696. }
  697. TCHAR szWrapPath[MAX_PATH + 1] = { 0 };
  698. if (!GetWrapperINIPath(szWrapPath, MAX_PATH)) {
  699. Dbg(TEXT("[-] Get wrap config file failed."));
  700. }
  701. else
  702. {
  703. char section[MAX_PATH] = { 0 };
  704. sprintf_s(section, TEXT("[%d.%d.%d.%d]"), fv.w.Major, fv.w.Minor, fv.Release, fv.Build);
  705. if (CheckIfSectionExist(szWrapPath, section)) {
  706. situation = 2;
  707. } else {
  708. LogWarn(Severity_None, Error_Succeed, 0, (LPCTSTR)CSimpleStringA::Format("Terminal Services version: %s", szVersion));
  709. //GetSystemVersion();
  710. }
  711. }
  712. if (situation == 0) {
  713. Dbg(TEXT("[-] This version of Terminal Services is not supported."));
  714. LogError(Severity_Middle, Error_InvalidState, ERROR_FREERDP_RDPWRAP_NOT_SUPPORT_FOR_NOW, "This version of Terminal Services is not supported.");
  715. }
  716. else if (situation == 1) {
  717. Dbg(TEXT("[!] This version of Terminal Services is supported partially."));
  718. LogWarn(Severity_Middle, Error_NotMeetCondition, ERROR_FREERDP_RDPWRAP_NOT_SUPPORT_FOR_NOW, "This version of Terminal Services is supported partially.");
  719. Dbg(TEXT("[!] It means you may have some limitations such as only 2 concurrent sessions."));
  720. }
  721. else if (situation == 2) {
  722. Dbg(TEXT("[+] This version of Terminal Services is fully supported."));
  723. LogEvent(Severity_Middle, 0, "This version of Terminal Services is fully supported.");
  724. }
  725. return (situation == 2);
  726. }
  727. /*consider that sometimes the windows system would upgrade...*/
  728. BOOL CheckTermsrvIsSupportForNow()
  729. {
  730. BOOL result = CheckTermsrvVersion();
  731. if(!result) {
  732. LogWarn(Severity_Middle, Error_InvalidState, ERROR_FREERDP_RDPWRAP_NOT_SUPPORT_DUE_SYS_UPDATE,
  733. "RDPWrap is not supported due to system upgrade or newer config lack of section.");
  734. }
  735. return result;
  736. }
  737. BOOL CheckTermsrvVersionEx(LPCTSTR TermsrvFilePath)
  738. {
  739. if(TermsrvFilePath == NULL || strlen(TermsrvFilePath) <= 0) {
  740. return FALSE;
  741. }
  742. TCHAR szTermServicePath[MAX_PATH] = { 0 };
  743. ExpandPath(TermsrvFilePath, szTermServicePath, MAX_PATH);
  744. FILE_VERSION fv = { 0 };
  745. GetFileVersion(szTermServicePath, &fv);
  746. TCHAR szVersion[64] = { 0 };
  747. sprintf_s(szVersion, TEXT("%d.%d.%d.%d"), fv.w.Major, fv.w.Minor, fv.Release, fv.Build);
  748. Dbg(TEXT("[*] Terminal Services version: %s"), szVersion);
  749. CopyMemory(&FV, &fv, sizeof(FILE_VERSION));
  750. if (fv.w.Major == 5 && fv.w.Minor == 1) {
  751. if (gArch == 32) {
  752. Dbg(TEXT("[!] Windows XP is not supported."));
  753. Dbg(TEXT("You may take a look at RDP Realtime Patch by Stas''M for Windows XP"));
  754. }
  755. else if (gArch == 64) {
  756. Dbg(TEXT("[!] Windows XP 64-bit Edition is not supported."));
  757. }
  758. return FALSE;
  759. }
  760. if (fv.w.Major == 5 && fv.w.Minor == 2) {
  761. if (gArch == 32) {
  762. Dbg(TEXT("[!] Windows Server 2003 is not supported."));
  763. }
  764. else if (gArch == 64) {
  765. Dbg(TEXT("[!] Windows Server 2003 or XP 64-bit Edition is not supported."));
  766. }
  767. return FALSE;
  768. }
  769. int situation = 0;
  770. if (fv.w.Major == 6 && fv.w.Minor == 0) {
  771. situation = 1;
  772. if (gArch == 32 && fv.Release == 6000 && fv.Build == 16386) {
  773. Dbg(TEXT("[!] This version of Terminal Services may crash on logon attempt."));
  774. Dbg(TEXT("It''s recommended to upgrade to Service Pack 1 or higher."));
  775. }
  776. }
  777. if (fv.w.Major == 6 && fv.w.Minor == 1) {
  778. situation = 1;
  779. }
  780. TCHAR szWrapPath[MAX_PATH + 1] = { 0 };
  781. if (!GetWrapperINIPath(szWrapPath, MAX_PATH)) {
  782. Dbg(TEXT("[-] Get wrap config file failed."));
  783. }
  784. else
  785. {
  786. char section[MAX_PATH] = { 0 };
  787. sprintf_s(section, TEXT("[%d.%d.%d.%d]"), fv.w.Major, fv.w.Minor, fv.Release, fv.Build);
  788. if (CheckIfSectionExist(szWrapPath, section)) {
  789. situation = 2;
  790. } else {
  791. LogWarn(Severity_None, Error_Succeed, 0, (LPCTSTR)CSimpleStringA::Format("Terminal Services version: %s", szVersion));
  792. }
  793. }
  794. if (situation == 0) {
  795. Dbg(TEXT("[-] This version of Terminal Services is not supported."));
  796. LogError(Severity_High, Error_InvalidState, ERROR_FREERDP_RDPWRAP_NOT_SUPPORT_FOR_NOW, "This version of Terminal Services is not supported.");
  797. }
  798. else if (situation == 1) {
  799. Dbg(TEXT("[!] This version of Terminal Services is supported partially."));
  800. LogWarn(Severity_Low, Error_NotMeetCondition, ERROR_FREERDP_RDPWRAP_NOT_SUPPORT_FOR_NOW, "This version of Terminal Services is supported partially.");
  801. Dbg(TEXT("[!] It means you may have some limitations such as only 2 concurrent sessions."));
  802. }
  803. else if (situation == 2) {
  804. Dbg(TEXT("[+] This version of Terminal Services is fully supported."));
  805. LogEvent(Severity_Middle, 0, "This version of Terminal Services is fully supported.");
  806. }
  807. return (situation == 2);
  808. }
  809. BOOL DisableWowRedirection()
  810. {
  811. PFuncWow64DisableWow64FsRedirection func = NULL;
  812. PVOID OldWow64RedirectionValue;
  813. BOOL Result = FALSE;
  814. HMODULE hMoudle = GetModuleHandle(TEXT("kernel32"));
  815. if (hMoudle) {
  816. func = (PFuncWow64DisableWow64FsRedirection)::GetProcAddress(hMoudle,
  817. "Wow64DisableWow64FsRedirection");
  818. }
  819. if (func) {
  820. Result = func(&OldWow64RedirectionValue);
  821. }
  822. return Result;
  823. }
  824. BOOLEAN RevertWowRedirection()
  825. {
  826. PFuncWow64RevertWow64FsRedirection func = NULL;
  827. PVOID OldWow64RedirectionValue;
  828. BOOL Result = FALSE;
  829. HMODULE hMoudle = GetModuleHandle(TEXT("kernel32"));
  830. if (hMoudle) {
  831. func = (PFuncWow64DisableWow64FsRedirection)::GetProcAddress(hMoudle,
  832. "Wow64RevertWow64FsRedirection");
  833. }
  834. if (func) {
  835. Result = func(&OldWow64RedirectionValue);
  836. }
  837. return Result;
  838. }
  839. /*
  840. * Result:
  841. * -1: inner error leads to be disabled to figure out it's installed status.
  842. * 2: cannot install because occruption.
  843. * 0: not installed.
  844. * 1: installed.
  845. * Addition:
  846. * Set gszTermServicePath
  847. *
  848. */
  849. int CheckInstall()
  850. {
  851. HKEY hKey;
  852. int fResult = 0;
  853. DWORD dwFlag = KEY_READ | KEY_QUERY_VALUE | KEY_ENUMERATE_SUB_KEYS;
  854. if (gArch == 64/*Win64Bit*/) {
  855. dwFlag |= KEY_WOW64_64KEY;
  856. }
  857. else {
  858. dwFlag |= KEY_WOW64_32KEY;
  859. }
  860. LONG lResult = RegOpenKeyEx(HKEY_LOCAL_MACHINE, TEXT("SYSTEM\\CurrentControlSet\\Services\\TermService"),
  861. 0, dwFlag, &hKey);
  862. if (lResult == ERROR_SUCCESS) {
  863. DWORD dwType = REG_SZ;
  864. DWORD dwSize = MAX_PATH*sizeof(TCHAR);
  865. TCHAR szValue[MAX_PATH + 1] = { 0 };
  866. lResult = RegQueryValueEx(hKey, TEXT("ImagePath"), NULL, &dwType, (LPBYTE)szValue, &dwSize);
  867. if (lResult == ERROR_SUCCESS) {
  868. Dbg(TEXT("[*] ImagePath: %s"), szValue);
  869. ToLowerCase(szValue);
  870. if (_tcsstr(szValue, TEXT("svchost.exe")) == NULL && _tcsstr(szValue, TEXT("svchost -k")) == NULL) {
  871. Dbg(TEXT("[-] TermService is hosted in a custom application (BeTwin, etc.) - unsupported."));
  872. LogError(Severity_High, Error_AlreadyExist, 0, "TermService is hosted in a custom application (BeTwin, etc.) - unsupported.");
  873. fResult = 2;
  874. }
  875. else {
  876. dwType = REG_EXPAND_SZ;
  877. dwSize = MAX_PATH * sizeof(TCHAR);
  878. //windows 7 bug occurs if only set RRF_RT_REG_EXPAND_SZ !!
  879. DWORD dwSpecified = RRF_RT_REG_EXPAND_SZ | RRF_RT_REG_SZ | RRF_NOEXPAND;
  880. ZeroMemory(szValue, sizeof(TCHAR)*(MAX_PATH + 1));
  881. lResult = RegGetValue(hKey, TEXT("Parameters"), TEXT("ServiceDll"), dwSpecified, NULL, (PVOID)szValue, &dwSize);
  882. if (lResult == ERROR_SUCCESS) {
  883. Dbg(TEXT("[*] ServiceDll: %s"), szValue);
  884. _tcscpy_s(gszTermServicePath, szValue);
  885. ToLowerCase(szValue);
  886. if (_tcsstr(szValue, TEXT("termsrv.dll")) == NULL
  887. && _tcsstr(szValue, TEXT("rdpwrap.dll")) == NULL
  888. && _tcsstr(szValue, TEXT("rdpwrap64.dll")) == NULL) {
  889. Dbg(TEXT("[-] Another third-party TermService library is installed."));
  890. LogWarn(Severity_Middle, Error_AlreadyExist, ERROR_FREERDP_RDPWRAP_THIRD_PARTY,
  891. "Another third-party TermService library is installed.");
  892. fResult = 2;
  893. }
  894. else {
  895. if (!!_tcsstr(szValue, TEXT("rdpwrap.dll"))
  896. ||
  897. !!_tcsstr(szValue, TEXT("rdpwrap64.dll"))) {
  898. Dbg(TEXT("[*] RDP Wrapper Library is already installed."));
  899. fResult = 1;
  900. }
  901. }
  902. }
  903. else {
  904. Dbg(TEXT("[-] RegGetValue error returned %u, GLE=%u."), lResult, GetLastError());
  905. fResult = -1;
  906. }
  907. }
  908. }
  909. else {
  910. Dbg(TEXT("[-] RegQueryValueEx error returned %u, GLE=%u."), lResult, GetLastError());
  911. fResult = -1;
  912. }
  913. }
  914. else {
  915. Dbg(TEXT("[-] RegOpenKeyEx error, GLE=%u."), GetLastError());
  916. fResult = -1;
  917. }
  918. RegCloseKey(hKey);
  919. return fResult;
  920. }
  921. BOOL ExecWait(LPTSTR lpszCmdLine)
  922. {
  923. BOOL fResult = FALSE;
  924. STARTUPINFO si = { 0 };
  925. PROCESS_INFORMATION pi = { 0 };
  926. ZeroMemory(&si, sizeof(STARTUPINFO));
  927. si.cb = sizeof(si);
  928. if (!CreateProcess(NULL, lpszCmdLine, NULL, NULL, TRUE, 0, NULL, NULL, &si, &pi)) {
  929. Dbg(TEXT("[-] CreateProcess with \"%s\" error, GLE=%u."), lpszCmdLine, GetLastError());
  930. return fResult;
  931. }
  932. CloseHandle(pi.hThread);
  933. WaitForSingleObject(pi.hProcess, INFINITE);
  934. CloseHandle(pi.hProcess);
  935. return TRUE;
  936. }
  937. BOOL TSConfigRegistry(BOOL fEnable)
  938. {
  939. BOOL fResult = FALSE;
  940. HKEY hKey = NULL;
  941. HKEY hInnerKey = NULL;
  942. LONG lResult;
  943. DWORD dwFlag = KEY_WRITE;
  944. if (gArch == 64/*Win64Bit*/) {
  945. dwFlag |= KEY_WOW64_64KEY;
  946. }
  947. else {
  948. dwFlag |= KEY_WOW64_32KEY;
  949. }
  950. lResult = RegOpenKeyEx(HKEY_LOCAL_MACHINE, TEXT("SYSTEM\\CurrentControlSet\\Control\\Terminal Server"),
  951. 0, dwFlag, &hKey);
  952. if (lResult == ERROR_SUCCESS) {
  953. DWORD dwEnable = fEnable == TRUE ? (DWORD)0 : (DWORD)1;
  954. lResult = RegSetValueEx(hKey, TEXT("fDenyTSConnections"), 0, REG_DWORD, (const BYTE*)&dwEnable, sizeof(DWORD));
  955. if (lResult == ERROR_SUCCESS) {
  956. Dbg(TEXT("[+] RegSetValueEx for \"fDenyTSConnections\" succ: Enable(%u)"), dwEnable);
  957. }
  958. else {
  959. Dbg(TEXT("[-] RegSetValueEx for \"fDenyTSConnections\" error %ld, GLE=%u"), lResult, GetLastError());
  960. goto FAILED;
  961. }
  962. }
  963. else {
  964. Dbg(TEXT("[-] RegOpenKeyEx for \"SYSTEM\\CurrentControlSet\\Control\\Terminal Server\" error %ld, GLE=%u"), lResult, GetLastError());
  965. goto FAILED;
  966. }
  967. RegCloseKey(hKey);
  968. if (fEnable) {
  969. lResult = RegOpenKeyEx(HKEY_LOCAL_MACHINE, TEXT("SYSTEM\\CurrentControlSet\\Control\\Terminal Server\\Licensing Core"),
  970. 0, dwFlag, &hKey);
  971. if (lResult == ERROR_FILE_NOT_FOUND) {
  972. Dbg(TEXT("[*] Start to create \"Licensing Core\" key..."));
  973. DWORD dwDisposition = REG_OPENED_EXISTING_KEY;
  974. lResult = RegCreateKeyEx(HKEY_LOCAL_MACHINE, TEXT("SYSTEM\\CurrentControlSet\\Control\\Terminal Server\\Licensing Core"),
  975. 0, NULL, REG_OPTION_NON_VOLATILE, KEY_ALL_ACCESS, NULL, &hKey, &dwDisposition);
  976. }
  977. if (lResult == ERROR_SUCCESS) {
  978. DWORD dwEnable = (DWORD)1;
  979. lResult = RegSetValueEx(hKey, TEXT("EnableConcurrentSessions"), 0, REG_DWORD, (const BYTE*)&dwEnable, sizeof(DWORD));
  980. if (lResult == ERROR_SUCCESS) {
  981. Dbg(TEXT("[+] RegSetValueEx for \"EnableConcurrentSessions\" succ: Enable(%u)"), dwEnable);
  982. }
  983. else {
  984. Dbg(TEXT("[-] RegSetValueEx for \"EnableConcurrentSessions\" error, GLE=%u"), GetLastError());
  985. goto FAILED;
  986. }
  987. }
  988. else {
  989. Dbg(TEXT("[-] RegOpenKeyEx for \"SYSTEM\\CurrentControlSet\\Control\\Terminal Server\\Licensing Core\" error %ld, GLE=%u"),
  990. lResult, GetLastError());
  991. goto FAILED;
  992. }
  993. RegCloseKey(hKey);
  994. lResult = RegOpenKeyEx(HKEY_LOCAL_MACHINE, TEXT("SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\Winlogon"),
  995. 0, dwFlag, &hKey);
  996. if (lResult == ERROR_SUCCESS) {
  997. DWORD dwEnable = TRUE;
  998. lResult = RegSetValueEx(hKey, TEXT("AllowMultipleTSSessions"), 0, REG_DWORD, (const BYTE*)&dwEnable, sizeof(DWORD));
  999. if (lResult == ERROR_SUCCESS) {
  1000. Dbg(TEXT("[+] RegSetValueEx for \"AllowMultipleTSSessions\" succ: Enable(%u)"), dwEnable);
  1001. }
  1002. else {
  1003. Dbg(TEXT("[-] RegSetValueEx for \"AllowMultipleTSSessions\" error %ld, GLE=%u"), lResult, GetLastError());
  1004. goto FAILED;
  1005. }
  1006. }
  1007. else {
  1008. Dbg(TEXT("[-] RegOpenKeyEx for \"SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\Winlogon\" error %ld, GLE=%u"), lResult, GetLastError());
  1009. goto FAILED;
  1010. }
  1011. RegCloseKey(hKey);
  1012. lResult = RegOpenKeyEx(HKEY_LOCAL_MACHINE, TEXT("SYSTEM\\CurrentControlSet\\Control\\Terminal Server\\AddIns"),
  1013. 0, dwFlag, &hKey);
  1014. if (lResult == ERROR_FILE_NOT_FOUND) {
  1015. Dbg(TEXT("[*] Start to create \"AddIns\" key..."));
  1016. DWORD dwDisposition = REG_OPENED_EXISTING_KEY;
  1017. lResult = RegCreateKeyEx(HKEY_LOCAL_MACHINE, TEXT("SYSTEM\\CurrentControlSet\\Control\\Terminal Server\\AddIns"),
  1018. 0, NULL, REG_OPTION_NON_VOLATILE, KEY_ALL_ACCESS, NULL, &hKey, &dwDisposition);
  1019. if (lResult == ERROR_SUCCESS) {
  1020. //lResult = RegOpenKeyEx(HKEY_LOCAL_MACHINE, TEXT("SYSTEM\\CurrentControlSet\\Control\\Terminal Server\\AddIns\\Clip Redirector"),
  1021. // 0, dwFlag, &hInnerKey);
  1022. lResult = RegCreateKeyEx(HKEY_LOCAL_MACHINE,
  1023. TEXT("SYSTEM\\CurrentControlSet\\Control\\Terminal Server\\AddIns\\Clip Redirector"),
  1024. 0, NULL, REG_OPTION_NON_VOLATILE, KEY_ALL_ACCESS, NULL, &hInnerKey, &dwDisposition);
  1025. if (lResult == ERROR_SUCCESS) {
  1026. //Refer to "atlbase.h"
  1027. TCHAR szValue[] = TEXT("RDPClip\0");
  1028. DWORD dwValSize = ((DWORD)(_tcslen(szValue)) + 1)*sizeof(TCHAR);
  1029. lResult = RegSetValueEx(hInnerKey, TEXT("Name"), 0, REG_SZ, (const BYTE*)szValue, dwValSize);
  1030. if (lResult != ERROR_SUCCESS) {
  1031. Dbg(TEXT("[-] RegSetValueEx for \"Name\" error %ld, GLE=%u"), lResult, GetLastError());
  1032. goto FAILED;
  1033. }
  1034. DWORD dwValue = (DWORD)3;
  1035. lResult = RegSetValueEx(hInnerKey, TEXT("Type"), 0, REG_DWORD, (const BYTE*)&dwValue, sizeof(DWORD));
  1036. if (lResult != ERROR_SUCCESS) {
  1037. Dbg(TEXT("[-] RegSetValueEx for \"Type\" error %ld, GLE=%u"), lResult, GetLastError());
  1038. goto FAILED;
  1039. }
  1040. RegCloseKey(hInnerKey);
  1041. }
  1042. else {
  1043. Dbg(TEXT("[-] RegCreateKeyEx for \"SYSTEM\\CurrentControlSet\\Control\\Terminal Server\\AddIns\\Clip Redirector\" error %ld, GLE=%u"), lResult, GetLastError());
  1044. goto FAILED;
  1045. }
  1046. //lResult = RegOpenKeyEx(HKEY_LOCAL_MACHINE, TEXT("SYSTEM\\CurrentControlSet\\Control\\Terminal Server\\AddIns\\DND Redirector"),
  1047. // 0, dwFlag, &hInnerKey);
  1048. lResult = RegCreateKeyEx(HKEY_LOCAL_MACHINE,
  1049. TEXT("SYSTEM\\CurrentControlSet\\Control\\Terminal Server\\AddIns\\DND Redirector"),
  1050. 0, NULL, REG_OPTION_NON_VOLATILE, KEY_ALL_ACCESS, NULL, &hInnerKey, &dwDisposition);
  1051. if (lResult == ERROR_SUCCESS) {
  1052. TCHAR szRDPDND[] = TEXT("RDPDND\0");
  1053. DWORD dwValSize = ((DWORD)(_tcslen(szRDPDND)) + 1)*sizeof(TCHAR);
  1054. lResult = RegSetValueEx(hInnerKey, TEXT("Name"), 0, REG_SZ, (const BYTE*)szRDPDND, dwValSize);
  1055. if (lResult != ERROR_SUCCESS) {
  1056. Dbg(TEXT("[-] RegSetValueEx for \"Type\" error %ld, GLE=%u"), lResult, GetLastError());
  1057. goto FAILED;
  1058. }
  1059. DWORD dwValue = (DWORD)3;
  1060. lResult = RegSetValueEx(hInnerKey, TEXT("Type"), 0, REG_DWORD, (const BYTE*)&dwValue, sizeof(DWORD));
  1061. if (lResult != ERROR_SUCCESS) {
  1062. Dbg(TEXT("[-] RegSetValueEx for \"Type\" error %ld, GLE=%u"), lResult, GetLastError());
  1063. goto FAILED;
  1064. }
  1065. }
  1066. else {
  1067. Dbg(TEXT("[-] RegCreateKeyEx for \"SYSTEM\\CurrentControlSet\\Control\\Terminal Server\\AddIns\\DND Redirector\" error %ld, GLE=%u"), lResult, GetLastError());
  1068. goto FAILED;
  1069. }
  1070. RegCloseKey(hInnerKey);
  1071. //lResult = RegOpenKeyEx(HKEY_LOCAL_MACHINE, TEXT("SYSTEM\\CurrentControlSet\\Control\\Terminal Server\\AddIns\\Dynamic VC"),
  1072. // 0, dwFlag, &hInnerKey);
  1073. lResult = RegCreateKeyEx(HKEY_LOCAL_MACHINE,
  1074. TEXT("SYSTEM\\CurrentControlSet\\Control\\Terminal Server\\AddIns\\Dynamic VC"),
  1075. 0, NULL, REG_OPTION_NON_VOLATILE, KEY_ALL_ACCESS, NULL, &hInnerKey, &dwDisposition);
  1076. if (lResult == ERROR_SUCCESS) {
  1077. DWORD dwValue = (DWORD)-1;
  1078. lResult = RegSetValueEx(hInnerKey, TEXT("Type"), 0, REG_DWORD, (const BYTE*)&dwValue, sizeof(DWORD));
  1079. if (lResult != ERROR_SUCCESS) {
  1080. Dbg(TEXT("[-] RegSetValueEx for \"Type\" error %ld, GLE=%u"), lResult, GetLastError());
  1081. goto FAILED;
  1082. }
  1083. }
  1084. else {
  1085. Dbg(TEXT("[-] RegCreateKeyEx for \"SYSTEM\\CurrentControlSet\\Control\\Terminal Server\\AddIns\\Dynamic VC\" error %ld, GLE=%u"), lResult, GetLastError());
  1086. goto FAILED;
  1087. }
  1088. RegCloseKey(hInnerKey);
  1089. }
  1090. else {
  1091. Dbg(TEXT("[-] RegCreateKeyEx for \"SYSTEM\\CurrentControlSet\\Control\\Terminal Server\\AddIns\" error %ld, GLE=%u"), lResult, GetLastError());
  1092. goto FAILED;
  1093. }
  1094. }
  1095. else {
  1096. //Dbg(TEXT("[-] RegOpenKeyEx for \"SYSTEM\\CurrentControlSet\\Control\\Terminal Server\\AddIns\" error %ld, GLE=%u"), lResult, GetLastError());
  1097. }
  1098. RegCloseKey(hKey);
  1099. }
  1100. return TRUE;
  1101. FAILED:
  1102. if (hInnerKey != NULL) {
  1103. RegCloseKey(hInnerKey);
  1104. }
  1105. if (hKey != NULL) {
  1106. RegCloseKey(hKey);
  1107. }
  1108. return FALSE;
  1109. }
  1110. BOOL TSConfigFirewall(BOOL fEnable)
  1111. {
  1112. BOOL fResult = FALSE;
  1113. TCHAR szCmdLine[MAX_PATH] = { 0 };
  1114. if (fEnable) {
  1115. _tcscpy_s(szCmdLine, TEXT("netsh advfirewall firewall add rule name=\"Remote Desktop\" dir=in protocol=tcp localport=3389 profile=any action=allow"));
  1116. }
  1117. else {
  1118. _tcscpy_s(szCmdLine, TEXT("netsh advfirewall firewall delete rule name=\"Remote Desktop\""));
  1119. }
  1120. return ExecWait(szCmdLine);
  1121. }
  1122. /*
  1123. Returned:
  1124. -1: Unknown
  1125. 0: Not Installed
  1126. 1: Installed
  1127. 2: 3rd-party
  1128. */
  1129. int IsWrapperInstalled()
  1130. {
  1131. HKEY hKey = NULL;
  1132. HKEY hSubKey = NULL;
  1133. int fResult = -1;
  1134. DWORD dwFlag = KEY_READ | KEY_QUERY_VALUE | KEY_ENUMERATE_SUB_KEYS;
  1135. if (gArch == 64/*Win64Bit*/) {
  1136. dwFlag |= KEY_WOW64_64KEY;
  1137. }
  1138. else {
  1139. dwFlag |= KEY_WOW64_32KEY;
  1140. }
  1141. LONG lResult = RegOpenKeyEx(HKEY_LOCAL_MACHINE, TEXT("SYSTEM\\CurrentControlSet\\Services\\TermService"),
  1142. 0, dwFlag, &hKey);
  1143. if (lResult == ERROR_SUCCESS) {
  1144. DWORD dwType = REG_SZ;
  1145. DWORD dwSize = MAX_PATH*sizeof(TCHAR);
  1146. TCHAR szValue[MAX_PATH + 1] = { 0 };
  1147. lResult = RegQueryValueEx(hKey, TEXT("ImagePath"), NULL, &dwType, (LPBYTE)szValue, &dwSize);
  1148. if (lResult == ERROR_SUCCESS) {
  1149. Dbg(TEXT("[*] ImagePath: %s"), szValue);
  1150. ToLowerCase(szValue);
  1151. if (_tcsstr(szValue, TEXT("svchost.exe")) == NULL) {
  1152. fResult = 2;
  1153. goto End;
  1154. }
  1155. }
  1156. RegCloseKey(hKey);
  1157. hKey = NULL;
  1158. lResult = RegOpenKeyEx(HKEY_LOCAL_MACHINE,
  1159. TEXT("SYSTEM\\CurrentControlSet\\Services\\TermService\\Parameters"),
  1160. 0, dwFlag, &hKey);
  1161. if (lResult == ERROR_SUCCESS) {
  1162. dwType = RRF_RT_REG_EXPAND_SZ | RRF_RT_REG_SZ | RRF_NOEXPAND;
  1163. dwSize = MAX_PATH*sizeof(TCHAR);
  1164. ZeroMemory(szValue, MAX_PATH*sizeof(TCHAR));
  1165. lResult = RegQueryValueEx(hKey, TEXT("ServiceDll"), NULL, &dwType, (LPBYTE)szValue, &dwSize);
  1166. if (lResult == ERROR_SUCCESS) {
  1167. Dbg(TEXT("[*] ServiceDll: %s"), szValue);
  1168. memset(gszExistedTSPath, 0, sizeof(gszExistedTSPath));
  1169. _tcscpy_s(gszExistedTSPath, szValue);
  1170. ToLowerCase(szValue);
  1171. if (_tcsstr(szValue, TEXT("termsrv.dll")) == NULL
  1172. && _tcsstr(szValue, TEXT("rdpwrap.dll")) == NULL
  1173. && _tcsstr(szValue, TEXT("rdpwrap64.dll")) == NULL) {
  1174. Dbg(TEXT("[-] Another third-party TermService library is installed."));
  1175. LogWarn(Severity_Low, Error_AlreadyExist, 0, "Another third-party TermService library is installed.");
  1176. fResult = 2;
  1177. goto End;
  1178. }
  1179. else {
  1180. if (!!_tcsstr(szValue, TEXT("rdpwrap.dll"))
  1181. ||
  1182. !!_tcsstr(szValue, TEXT("rdpwrap64.dll"))) {
  1183. Dbg(TEXT("[*] RDP Wrapper Library is already installed."));
  1184. fResult = 1;
  1185. }
  1186. else {
  1187. fResult = 0;
  1188. }
  1189. }
  1190. }
  1191. }
  1192. }
  1193. End:
  1194. if (hKey) {
  1195. RegCloseKey(hKey);
  1196. hKey = NULL;
  1197. }
  1198. return fResult;
  1199. }
  1200. /*
  1201. Returned:
  1202. -1: Unknown
  1203. SERVICE_STOPPED: Stop
  1204. SERVICE_START_PENDING: Starting...
  1205. ...
  1206. */
  1207. DWORD GetTermSrvState()
  1208. {
  1209. DWORD dwResult = INFINITE;
  1210. SC_HANDLE schSCManager;
  1211. SC_HANDLE schService;
  1212. DWORD cbBytesNeeded;
  1213. DWORD cbBufSize;
  1214. PBYTE Buf = NULL;
  1215. schSCManager = OpenSCManager(NULL, SERVICES_ACTIVE_DATABASE, SC_MANAGER_CONNECT);
  1216. if (!schSCManager)
  1217. {
  1218. Dbg(TEXT("[-] Open SC Manager failed with status %d "), GetLastError());
  1219. return dwResult;
  1220. }
  1221. schService = OpenService(schSCManager, TERM_SERVICE, SERVICE_QUERY_STATUS);
  1222. if (!schService) {
  1223. Dbg(TEXT("[-] Open SC Service failed with status %d "), GetLastError());
  1224. goto Error;
  1225. }
  1226. if (QueryServiceStatusEx(schService, SC_STATUS_PROCESS_INFO, NULL, 0, &cbBytesNeeded)) {
  1227. goto Error;
  1228. }
  1229. Buf = (LPBYTE)LocalAlloc(LMEM_FIXED, cbBytesNeeded);
  1230. cbBufSize = cbBytesNeeded;
  1231. if (Buf == NULL) {
  1232. Dbg(TEXT("[-] LocalAlloc failed with status %d "), GetLastError());
  1233. goto Error;
  1234. }
  1235. ZeroMemory(Buf, cbBufSize);
  1236. if (!QueryServiceStatusEx(schService, SC_STATUS_PROCESS_INFO, Buf, cbBufSize, &cbBytesNeeded)) {
  1237. Dbg(TEXT("[-] QueryServiceStatusEx failed with status %d "), GetLastError());
  1238. goto Error;
  1239. }
  1240. LPSERVICE_STATUS_PROCESS lpServiceStatusProcess = (LPSERVICE_STATUS_PROCESS)Buf;
  1241. dwResult = lpServiceStatusProcess->dwCurrentState;
  1242. Error:
  1243. if (Buf != NULL) {
  1244. LocalFree(Buf);
  1245. Buf = NULL;
  1246. }
  1247. if (schService) {
  1248. CloseServiceHandle(schService);
  1249. schService = NULL;
  1250. }
  1251. if (schSCManager) {
  1252. CloseServiceHandle(schSCManager);
  1253. schSCManager = NULL;
  1254. }
  1255. return dwResult;
  1256. }
  1257. bool IsListenerWorking()
  1258. {
  1259. bool fListen = false;
  1260. ULONG Count;
  1261. PSESSIONIDW PSessionIDW;
  1262. static PFuncWinStationEnumerateW pFuncWinStationQueryInformationW = NULL;
  1263. static PFuncWinStationFreeMemory pFuncWinStationFreeMemory = NULL;
  1264. if (!pFuncWinStationQueryInformationW || !pFuncWinStationFreeMemory) {
  1265. HMODULE winsta;
  1266. winsta = LoadLibrary(TEXT("winsta.dll"));
  1267. //pFuncWinStationQueryInformationW = (PFuncWinStationEnumerateW)GetProcAddress(winsta, "WinStationEnumerateW");
  1268. pFuncWinStationQueryInformationW = (PFuncWinStationEnumerateW)GetProcAddress(winsta, "WinStationEnumerateW");
  1269. pFuncWinStationFreeMemory = (PFuncWinStationFreeMemory)GetProcAddress(winsta, "WinStationFreeMemory");
  1270. }
  1271. if (!pFuncWinStationQueryInformationW || pFuncWinStationFreeMemory) {
  1272. Dbg(TEXT("[-] pFuncWinStationQueryInformationW is invalid"));
  1273. return false;
  1274. }
  1275. if (!pFuncWinStationQueryInformationW(NULL, &PSessionIDW, &Count)) {
  1276. Dbg(TEXT("[-] WinStationQueryInformationW failed with status %d "), GetLastError());
  1277. return false;
  1278. }
  1279. for (ULONG i = 0; i < Count; ++i) {
  1280. if (lstrcmpW(PSessionIDW[i].WinStationName, L"RDP-Tcp") == 0) {
  1281. fListen = true;
  1282. break;
  1283. }
  1284. }
  1285. pFuncWinStationFreeMemory(&PSessionIDW);
  1286. return fListen;
  1287. }
  1288. int InstallEntry(WillItem option)
  1289. {
  1290. int arch = 0;
  1291. if (!SupportedArchitecture(arch)) {
  1292. Dbg(TEXT("[-] Unsupported processor architecture."));
  1293. return 0;
  1294. }
  1295. BOOL fWow64 = FALSE;
  1296. //IsWow64Process(GetCurrentProcess(), &fWow64);
  1297. fWow64 = arch == 64 ? TRUE : FALSE;
  1298. int installed = CheckInstall();
  1299. if (option != Invalid) {
  1300. if (option == Install) {
  1301. Will = Install;
  1302. if (installed == 0) {
  1303. Dbg(TEXT("[*] Installing..."));
  1304. EnterWowRedirection();
  1305. TCHAR szWrapPath[MAX_PATH + 1] = { 0 };
  1306. IFCALLEXIT_WITH_RESULT(GetWrapperDllPath(szWrapPath, MAX_PATH), GetRes);
  1307. IFCALLEXIT_WITH_RESULT(CheckTermsrvVersion(), ChkTsVer);
  1308. DWORD dwTSProcessID = 0;
  1309. TCHAR pszSharedSvc[128][MAX_PATH] = { 0 };
  1310. DWORD dwSharedSvcCount = 128;
  1311. CheckTermsrvProcess(dwTSProcessID, pszSharedSvc, dwSharedSvcCount);
  1312. if (dwTSProcessID != 0) {
  1313. Dbg(TEXT("[*] Configuring service library..."));
  1314. IFCALLEXIT_WITH_RESULT(SetWrapperDll(szWrapPath), SetRes);
  1315. Dbg(TEXT("[*] Checking dependencies..."));
  1316. CheckTermsrvDependencies();
  1317. Dbg(TEXT("[*] Terminating service..."));
  1318. AddPrivilege(SE_DEBUG_NAME);
  1319. KillProcess(dwTSProcessID);
  1320. Sleep(1000);
  1321. if (dwSharedSvcCount > 0) {
  1322. for (DWORD i = 0; i < dwSharedSvcCount; ++i) {
  1323. SvcStartService(pszSharedSvc[i]);
  1324. }
  1325. }
  1326. Sleep(500);
  1327. IFCALLEXIT_WITH_RESULT(SvcStartService(TERM_SERVICE, dwTSProcessID), StaSvc);
  1328. Sleep(500);
  1329. Dbg(TEXT("[*] Configuring registry..."));
  1330. IFCALLEXIT_WITH_RESULT(TSConfigRegistry(TRUE), CfgReg);
  1331. Dbg(TEXT("[*] Configuring firewall..."));
  1332. IFCALLEXIT_WITH_RESULT(TSConfigFirewall(TRUE), CfgFWall);
  1333. Dbg(TEXT("[+] Successfully installed."));
  1334. }
  1335. else {
  1336. LeaveWowRedirection();
  1337. return (ChkTsPce);
  1338. }
  1339. LeaveWowRedirection();
  1340. return Success;
  1341. }
  1342. else if(installed == 1) {
  1343. return Success;
  1344. }
  1345. }
  1346. else if (option == Unstall) {
  1347. Will = Unstall;
  1348. if (installed != 1) {
  1349. if(installed == 0) {
  1350. Dbg(TEXT("[*] RDP Wrapper Library is not installed."));
  1351. return Success;
  1352. }
  1353. Dbg(TEXT("[*] RDP Wrapper Library is not supported."));
  1354. return NoSupport;
  1355. }
  1356. Dbg(TEXT("[*] Uninstalling..."));
  1357. EnterWowRedirection();
  1358. DWORD dwTSProcessID = 0;
  1359. TCHAR pszSharedSvc[128][MAX_PATH] = { 0 };
  1360. DWORD dwSharedSvcCount = 128;
  1361. CheckTermsrvProcess(dwTSProcessID, pszSharedSvc, dwSharedSvcCount);
  1362. if (dwTSProcessID != 0) {
  1363. Dbg(TEXT("[*] Resetting service library..."));
  1364. IFCALLEXIT_WITH_RESULT(ResetServiceDll(), ResetRes);
  1365. Dbg(TEXT("[*] Terminating service..."));
  1366. AddPrivilege(SE_DEBUG_NAME);
  1367. KillProcess(dwTSProcessID);
  1368. Sleep(1000);
  1369. //Dbg(TEXT("[*] Removing files..."));
  1370. //DeleteFiles();
  1371. if (dwSharedSvcCount > 0) {
  1372. for (DWORD i = 0; i < dwSharedSvcCount; ++i) {
  1373. SvcStartService(pszSharedSvc[i]);
  1374. }
  1375. }
  1376. Sleep(500);
  1377. IFCALLEXIT_WITH_RESULT(SvcStartService(TERM_SERVICE, dwTSProcessID), StaSvc);
  1378. Sleep(500);
  1379. Dbg(TEXT("[*] Configuring registry..."));
  1380. IFCALLEXIT_WITH_RESULT(TSConfigRegistry(FALSE), CfgReg);
  1381. Dbg(TEXT("[*] Configuring firewall..."));
  1382. IFCALLEXIT_WITH_RESULT(TSConfigFirewall(FALSE), CfgFWall);
  1383. Dbg(TEXT("[+] Successfully uninstalled."));
  1384. }
  1385. else {
  1386. LeaveWowRedirection();
  1387. return (ChkTsPce);
  1388. }
  1389. LeaveWowRedirection();
  1390. return Success;
  1391. }
  1392. else if (option == Restart) {
  1393. Will = Restart;
  1394. Dbg(TEXT("[*] Restarting..."));
  1395. DWORD dwTSProcessID = 0;
  1396. TCHAR pszSharedSvc[128][MAX_PATH] = { 0 };
  1397. DWORD dwSharedSvcCount = 128;
  1398. CheckTermsrvProcess(dwTSProcessID, pszSharedSvc, dwSharedSvcCount);
  1399. if (dwTSProcessID != 0) {
  1400. Dbg(TEXT("[*] Terminating service..."));
  1401. AddPrivilege(SE_DEBUG_NAME);
  1402. KillProcess(dwTSProcessID);
  1403. Sleep(1000);
  1404. if (dwSharedSvcCount > 0) {
  1405. for (DWORD i = 0; i < dwSharedSvcCount; ++i) {
  1406. SvcStartService(pszSharedSvc[i]);
  1407. }
  1408. }
  1409. Sleep(500);
  1410. IFCALLEXIT_WITH_RESULT(SvcStartService(TERM_SERVICE, dwTSProcessID), StaSvc);
  1411. Dbg(TEXT("[+] Done."));
  1412. return Success;
  1413. }
  1414. else {
  1415. return (ChkTsPce);
  1416. }
  1417. }
  1418. else if (option == Update) {
  1419. Will = Update;
  1420. if (installed != 1) {
  1421. Dbg(TEXT("[*] RDP Wrapper Library is not installed."));
  1422. return NoSupport;
  1423. }
  1424. Dbg(TEXT("[+] New update is available, updating..."));
  1425. EnterWowRedirection();
  1426. TCHAR szWrapPath[MAX_PATH + 1] = { 0 };
  1427. IFCALLEXIT_WITH_RESULT(GetWrapperDllPath(szWrapPath, MAX_PATH), GetRes);
  1428. //TODO: delete it
  1429. TCHAR szTermsrv[MAX_PATH] = DEFAULT_TERMSRV_PATH;
  1430. IFCALLEXIT_WITH_RESULT(CheckTermsrvVersionEx(szTermsrv), ChkTsVer);
  1431. DWORD dwTSProcessID = 0;
  1432. TCHAR pszSharedSvc[128][MAX_PATH] = { 0 };
  1433. DWORD dwSharedSvcCount = 128;
  1434. CheckTermsrvProcess(dwTSProcessID, pszSharedSvc, dwSharedSvcCount);
  1435. if (dwTSProcessID != 0) {
  1436. Dbg(TEXT("[*] Configuring service library..."));
  1437. IFCALLEXIT_WITH_RESULT(SetWrapperDll(szWrapPath), SetRes);
  1438. Dbg(TEXT("[*] Checking dependencies..."));
  1439. CheckTermsrvDependencies();
  1440. Dbg(TEXT("[*] Terminating service..."));
  1441. AddPrivilege(SE_DEBUG_NAME);
  1442. KillProcess(dwTSProcessID);
  1443. Sleep(1000);
  1444. if (dwSharedSvcCount > 0) {
  1445. for (DWORD i = 0; i < dwSharedSvcCount; ++i) {
  1446. SvcStartService(pszSharedSvc[i]);
  1447. }
  1448. }
  1449. Sleep(500);
  1450. IFCALLEXIT_WITH_RESULT(SvcStartService(TERM_SERVICE, dwTSProcessID), StaSvc);
  1451. Dbg(TEXT("[+] Successfully upated."));
  1452. }
  1453. else {
  1454. LeaveWowRedirection();
  1455. return (ChkTsPce);
  1456. }
  1457. LeaveWowRedirection();
  1458. return Success;
  1459. }
  1460. else if (option == Check) {
  1461. Will = Check;
  1462. if (installed == 1) {
  1463. //Dbg(TEXT("[*] RDP Wrapper Library has been installed."));
  1464. return Installed;
  1465. }
  1466. }
  1467. else {
  1468. return NoSupport;
  1469. }
  1470. }
  1471. return 0;
  1472. Error:
  1473. LeaveWowRedirection();
  1474. Dbg(TEXT("[!] The specified procedure operated failed !"));
  1475. return 0;
  1476. }
  1477. VOID RestartTsvProcess()
  1478. {
  1479. DWORD dwTSProcessID = 0;
  1480. TCHAR pszSharedSvc[128][MAX_PATH] = { 0 };
  1481. DWORD dwSharedSvcCount = 128;
  1482. CheckTermsrvProcess(dwTSProcessID, pszSharedSvc, dwSharedSvcCount);
  1483. if (dwTSProcessID != 0) {
  1484. Dbg(TEXT("[*] Terminating service..."));
  1485. AddPrivilege(SE_DEBUG_NAME);
  1486. KillProcess(dwTSProcessID);
  1487. Sleep(1000);
  1488. if (dwSharedSvcCount > 0) {
  1489. for (DWORD i = 0; i < dwSharedSvcCount; ++i) {
  1490. SvcStartService(pszSharedSvc[i]);
  1491. }
  1492. }
  1493. Sleep(500);
  1494. SvcStartService(TERM_SERVICE, dwTSProcessID);
  1495. }
  1496. return;
  1497. }
  1498. BOOL CheckTsvRestarted(DWORD dwLastPID)
  1499. {
  1500. DWORD dwTSProcessID = 0;
  1501. TCHAR pszSharedSvc[128][MAX_PATH] = { 0 };
  1502. DWORD dwSharedSvcCount = 128;
  1503. CheckTermsrvProcess(dwTSProcessID, pszSharedSvc, dwSharedSvcCount);
  1504. if (dwTSProcessID != 0) {
  1505. if(dwLastPID != 0 && dwLastPID != dwTSProcessID) {
  1506. Dbg(TEXT("[!] Tsv has been restart ! current pid: %d, previous pid: %d"), dwTSProcessID, dwLastPID);
  1507. return TRUE;
  1508. } else if(dwLastPID != 0) {
  1509. Dbg(TEXT("[!] Tsv is same as before, pid: %d"), dwTSProcessID);
  1510. return FALSE;
  1511. } else if(dwLastPID == 0) {
  1512. return TRUE;
  1513. }
  1514. } else {
  1515. Dbg(TEXT("[!] Get PID failed during CheckTermsrvProcess"));
  1516. }
  1517. return FALSE;
  1518. }
  1519. VOID AppQuit(int nExitCode)
  1520. {
  1521. BOOL process = TRUE;
  1522. if (nExitCode != 0) {
  1523. Dbg(TEXT("[!] ========================================="));
  1524. Dbg(TEXT("[!] The specified procedure operated failed !"));
  1525. InstPrgItem result = static_cast<InstPrgItem>(nExitCode);
  1526. switch (result) {
  1527. case ResetRes:
  1528. Dbg(TEXT("[x] It's a really serious error, but cannot do anything because what it's doing is just recover job."));
  1529. break;
  1530. case CfgFWall:
  1531. if (Will == Install) {
  1532. ResetServiceDll();
  1533. RestartTsvProcess();
  1534. TSConfigRegistry(FALSE);
  1535. TSConfigFirewall(FALSE);
  1536. }
  1537. else if (Will == Unstall) {
  1538. }
  1539. break;
  1540. case CfgReg:
  1541. if (Will == Install) {
  1542. ResetServiceDll();
  1543. RestartTsvProcess();
  1544. TSConfigRegistry(FALSE);
  1545. }
  1546. else if (Will == Unstall) {
  1547. }
  1548. break;
  1549. case SetRes:
  1550. ResetServiceDll();
  1551. break;
  1552. case StaSvc:
  1553. if (Will == Install) {
  1554. ResetServiceDll();
  1555. RestartTsvProcess();
  1556. }
  1557. else if (Will == Restart) {
  1558. }
  1559. else if (Will == Update) {
  1560. ResetServiceDll();
  1561. RestartTsvProcess();
  1562. }
  1563. break;
  1564. default: // GetRes, ChkTsVer, ChkTsPce
  1565. goto Exit;
  1566. break;
  1567. }
  1568. }
  1569. Exit:
  1570. //exit(-nExitCode);
  1571. return;
  1572. }
  1573. ErrorCodeEnum CheckRdpWrapInstall(BOOL& bInstalled)
  1574. {
  1575. ErrorCodeEnum ec = Error_Succeed;
  1576. const int installed = CheckInstall();
  1577. if(installed == 0) {
  1578. bInstalled = FALSE;
  1579. }else if(installed == 1) {
  1580. if(!CheckTermsrvIsSupportForNow()) {
  1581. if((ec = UnstallRdpWrap()) == Error_Succeed) {
  1582. bInstalled = FALSE;
  1583. Sleep(200);
  1584. }
  1585. } else {
  1586. bInstalled = TRUE;
  1587. }
  1588. }else if(installed == 2){
  1589. if(!ResetServiceDll()) {
  1590. ec = Error_Unexpect;
  1591. } else {
  1592. bInstalled = FALSE;
  1593. Sleep(200);
  1594. }
  1595. }else {
  1596. ec = Error_Unexpect;
  1597. }
  1598. return ec;
  1599. }
  1600. ErrorCodeEnum InstallRdpWrap()
  1601. {
  1602. ErrorCodeEnum ec = Error_Succeed;
  1603. if(InstallEntry(Install) != Success) {
  1604. ec = Error_Unexpect;
  1605. }
  1606. return ec;
  1607. }
  1608. ErrorCodeEnum UnstallRdpWrap()
  1609. {
  1610. ErrorCodeEnum ec = Error_Succeed;
  1611. if(InstallEntry(Unstall) != Success) {
  1612. ec = Error_Unexpect;
  1613. }
  1614. return ec;
  1615. }
  1616. ErrorCodeEnum RestartRdpWrap()
  1617. {
  1618. ErrorCodeEnum ec = Error_Succeed;
  1619. if(InstallEntry(Restart) != Success) {
  1620. ec = Error_Unexpect;
  1621. }
  1622. return ec;
  1623. }
  1624. ErrorCodeEnum UpdateRdpWrap()
  1625. {
  1626. ErrorCodeEnum ec = Error_Succeed;
  1627. if(InstallEntry(Update) != Success) {
  1628. ec = Error_Unexpect;
  1629. }
  1630. return ec;
  1631. }