diff --git a/bin/RDPCheck.exe b/bin/RDPCheck.exe new file mode 100644 index 0000000..5f62298 Binary files /dev/null and b/bin/RDPCheck.exe differ diff --git a/bin/RDPWInst.exe b/bin/RDPWInst.exe new file mode 100644 index 0000000..ebecf59 Binary files /dev/null and b/bin/RDPWInst.exe differ diff --git a/bin/install.bat b/bin/install.bat new file mode 100644 index 0000000..e9f4f78 --- /dev/null +++ b/bin/install.bat @@ -0,0 +1,7 @@ +@echo off +RDPWInst -i +echo ______________________________________________________ +echo. +echo You can check RDP functionality with RDPCheck program. +echo. +pause diff --git a/bin/uninstall.bat b/bin/uninstall.bat new file mode 100644 index 0000000..ace7aa5 --- /dev/null +++ b/bin/uninstall.bat @@ -0,0 +1,4 @@ +@echo off +RDPWInst -u +echo. +pause diff --git a/res/clearres.bat b/res/clearres.bat new file mode 100644 index 0000000..278e6cd --- /dev/null +++ b/res/clearres.bat @@ -0,0 +1,19 @@ +@echo off +echo [FILENAMES]> clearres.txt +echo Exe=%1>> clearres.txt +echo SaveAs=%1>> clearres.txt +echo Log=>> clearres.txt +echo.>> clearres.txt +echo [COMMANDS]>> clearres.txt +echo -delete RCDATA,CHARTABLE,>> clearres.txt +echo -delete RCDATA,DVCLAL,>> clearres.txt +echo -delete RCDATA,PACKAGEINFO,>> clearres.txt +echo -delete CURSORGROUP,32761,>> clearres.txt +echo -delete CURSORGROUP,32762,>> clearres.txt +echo -delete CURSORGROUP,32763,>> clearres.txt +echo -delete CURSORGROUP,32764,>> clearres.txt +echo -delete CURSORGROUP,32765,>> clearres.txt +echo -delete CURSORGROUP,32766,>> clearres.txt +echo -delete CURSORGROUP,32767,>> clearres.txt +"C:\Program Files\Resource Hacker\ResHacker.exe" -script clearres.txt +del clearres.txt diff --git a/res/legacy.install.bat b/res/legacy.install.bat new file mode 100644 index 0000000..a7d8de2 --- /dev/null +++ b/res/legacy.install.bat @@ -0,0 +1,91 @@ +@echo off +setlocal EnableDelayedExpansion +echo RDP Wrapper Library Installer v1.0 +echo Copyright (C) Stas'M Corp. 2013 +echo. + +set PROCESSOR_ARCHITECTURE | find "x86" > nul +if !errorlevel!==0 ( + goto WOW64CHK +) else ( + goto UNSUPPORTED +) + +:WOW64CHK +echo [*] Check if running WOW64 subsystem... +set PROCESSOR_ARCHITEW6432 > nul +if !errorlevel!==0 ( + goto UNSUPPORTED +) else ( + goto SUPPORTED +) + +:SUPPORTED +echo [+] Processor architecture is Intel x86 [supported] +goto INSTALL + +:UNSUPPORTED +echo [-] Unsupported processor architecture +goto END + +:INSTALL +echo [*] Installing... +if not exist rdpwrap.dll ( + echo [-] Error: rdpwrap.dll file not found + goto END +) +echo [*] Copying file to Program Files... +md "%ProgramFiles%\RDP Wrapper" +xcopy /y rdpwrap.dll "%ProgramFiles%\RDP Wrapper\" +if not !errorlevel!==0 ( + echo [-] Failed to copy rdpwrap.dll to Program Files folder + goto END +) +echo [*] Modifying registry... +reg add "HKLM\SYSTEM\CurrentControlSet\Services\TermService\Parameters" /v ServiceDll /t REG_EXPAND_SZ /d "%ProgramFiles%\RDP Wrapper\rdpwrap.dll" /f +if not !errorlevel!==0 ( + echo [-] Failed to modify registry + goto END +) +echo [*] Setting firewall configuration... +reg add "HKLM\SYSTEM\CurrentControlSet\Control\Terminal Server" /v fDenyTSConnections /t REG_DWORD /d 0 /f +netsh advfirewall firewall add rule name="Remote Desktop" dir=in protocol=tcp localport=3389 profile=any action=allow +echo [*] Looking for TermService PID... +tasklist /SVC /FI "SERVICES eq TermService" | find "PID" /V +echo. +if !errorlevel!==0 ( + goto DONE +) else ( + goto SVCSTART +) + +:SVCSTART +echo [*] TermService is stopped. Starting it... +sc config TermService start= auto | find "1060" > nul +if !errorlevel!==0 ( + echo [-] TermService is not installed. You need to install it manually. + goto END +) else ( + net start TermService + goto DONE +) + +:DONE +echo [+] Installation complete! +echo Now reboot or restart service. +echo. +echo To reboot computer type: +echo shutdown /r +echo. +echo To restart TermService type: +echo taskkill /f /pid 1234 ^(replace 1234 with real PID which is shown above^) +echo net start TermService +echo. +echo If second method is used, and there are another services sharing svchost.exe, +echo you must start it too: +echo net start Service1 +echo net start Service2 +echo etc. +goto END + +:END \ No newline at end of file diff --git a/res/rdpclip-x64.exe b/res/rdpclip-x64.exe new file mode 100644 index 0000000..bc2fcd4 Binary files /dev/null and b/res/rdpclip-x64.exe differ diff --git a/res/rdpclip-x86.exe b/res/rdpclip-x86.exe new file mode 100644 index 0000000..4b9bb5b Binary files /dev/null and b/res/rdpclip-x86.exe differ diff --git a/src-installer/RDPWInst.dpr b/src-installer/RDPWInst.dpr new file mode 100644 index 0000000..f14bdc6 --- /dev/null +++ b/src-installer/RDPWInst.dpr @@ -0,0 +1,1012 @@ +program RDPWInst; + +{$APPTYPE CONSOLE} + +{$R resource.res} + +uses + SysUtils, + Windows, + Classes, + WinSvc, + Registry; + +function EnumServicesStatusEx( + hSCManager: SC_HANDLE; + InfoLevel, + dwServiceType, + dwServiceState: DWORD; + lpServices: PByte; + cbBufSize: DWORD; + var pcbBytesNeeded, + lpServicesReturned, + lpResumeHandle: DWORD; + pszGroupName: PWideChar): BOOL; stdcall; + external advapi32 name 'EnumServicesStatusExW'; + +type + FILE_VERSION = record + Version: record case Boolean of + True: (dw: DWORD); + False: (w: record + Minor, Major: Word; + end;) + end; + Release, Build: Word; + bDebug, bPrerelease, bPrivate, bSpecial: Boolean; + end; + SERVICE_STATUS_PROCESS = packed record + dwServiceType, + dwCurrentState, + dwControlsAccepted, + dwWin32ExitCode, + dwServiceSpecificExitCode, + dwCheckPoint, + dwWaitHint, + dwProcessId, + dwServiceFlags: DWORD; + end; + PSERVICE_STATUS_PROCESS = ^SERVICE_STATUS_PROCESS; + ENUM_SERVICE_STATUS_PROCESS = packed record + lpServiceName, + lpDisplayName: PWideChar; + ServiceStatusProcess: SERVICE_STATUS_PROCESS; + end; + PENUM_SERVICE_STATUS_PROCESS = ^ENUM_SERVICE_STATUS_PROCESS; + +const + SC_ENUM_PROCESS_INFO = 0; + TermService = 'TermService'; +var + Installed: Boolean; + WrapPath: String; + Arch: Byte; + OldWow64RedirectionValue: LongBool; + + TermServicePath: String; + FV: FILE_VERSION; + TermServicePID: DWORD; + ShareSvc: Array of String; + sShareSvc: String; + +function SupportedArchitecture: Boolean; +var + SI: TSystemInfo; +begin + GetNativeSystemInfo(SI); + case SI.wProcessorArchitecture of + 0: + begin + Arch := 32; + Result := True; // Intel x86 + end; + 6: Result := False; // Itanium-based x64 + 9: begin + Arch := 64; + Result := True; // Intel/AMD x64 + end; + else Result := False; + end; +end; + +function DisableWowRedirection: Boolean; +type + TFunc = function(var Wow64FsEnableRedirection: LongBool): LongBool; stdcall; +var + hModule: THandle; + Wow64DisableWow64FsRedirection: TFunc; +begin + Result := False; + hModule := GetModuleHandle(kernel32); + if hModule <> 0 then + Wow64DisableWow64FsRedirection := GetProcAddress(hModule, 'Wow64DisableWow64FsRedirection') + else + Exit; + if @Wow64DisableWow64FsRedirection <> nil then + Result := Wow64DisableWow64FsRedirection(OldWow64RedirectionValue); +end; + +function RevertWowRedirection: Boolean; +type + TFunc = function(var Wow64RevertWow64FsRedirection: LongBool): LongBool; stdcall; +var + hModule: THandle; + Wow64RevertWow64FsRedirection: TFunc; +begin + Result := False; + hModule := GetModuleHandle(kernel32); + if hModule <> 0 then + Wow64RevertWow64FsRedirection := GetProcAddress(hModule, 'Wow64RevertWow64FsRedirection') + else + Exit; + if @Wow64RevertWow64FsRedirection <> nil then + Result := Wow64RevertWow64FsRedirection(OldWow64RedirectionValue); +end; + +procedure CheckInstall; +var + Code: DWORD; + TermServiceHost: String; + Reg: TRegistry; +begin + if Arch = 64 then + Reg := TRegistry.Create(KEY_WOW64_64KEY) + else + Reg := TRegistry.Create; + Reg.RootKey := HKEY_LOCAL_MACHINE; + if not Reg.OpenKeyReadOnly('\SYSTEM\CurrentControlSet\Services\TermService') then + begin + Reg.Free; + Code := GetLastError; + Writeln('[-] OpenKeyReadOnly error (code ', Code, ').'); + Halt(Code); + end; + TermServiceHost := Reg.ReadString('ImagePath'); + Reg.CloseKey; + if Pos('svchost.exe', LowerCase(TermServiceHost)) = 0 then + begin + Reg.Free; + Writeln('[-] TermService is hosted in a custom application (BeTwin, etc.) - unsupported.'); + Writeln('[*] ImagePath: "', TermServiceHost, '".'); + Halt(ERROR_NOT_SUPPORTED); + end; + if not Reg.OpenKeyReadOnly('\SYSTEM\CurrentControlSet\Services\TermService\Parameters') then + begin + Reg.Free; + Code := GetLastError; + Writeln('[-] OpenKeyReadOnly error (code ', Code, ').'); + Halt(Code); + end; + TermServicePath := Reg.ReadString('ServiceDll'); + Reg.CloseKey; + if (Pos('termsrv.dll', LowerCase(TermServicePath)) = 0) + and (Pos('rdpwrap.dll', LowerCase(TermServicePath)) = 0) then + begin + Reg.Free; + Writeln('[-] Another third-party TermService library is installed.'); + Writeln('[*] ServiceDll: "', TermServicePath, '".'); + Halt(ERROR_NOT_SUPPORTED); + end; + Reg.Free; + + Installed := Pos('rdpwrap.dll', LowerCase(TermServicePath)) > 0; +end; + +function SvcGetStart(SvcName: String): Integer; +var + hSC: SC_HANDLE; + hSvc: THandle; + Code: DWORD; + lpServiceConfig: PQueryServiceConfig; + Buf: Pointer; + cbBufSize, pcbBytesNeeded: Cardinal; +begin + Result := -1; + Writeln('[*] Checking ', SvcName, '...'); + hSC := OpenSCManager(nil, SERVICES_ACTIVE_DATABASE, SC_MANAGER_CONNECT); + if hSC = 0 then + begin + Code := GetLastError; + Writeln('[-] OpenSCManager error (code ', Code, ').'); + Exit; + end; + + hSvc := OpenService(hSC, PWideChar(SvcName), SERVICE_QUERY_CONFIG); + if hSvc = 0 then + begin + CloseServiceHandle(hSC); + Code := GetLastError; + Writeln('[-] OpenService error (code ', Code, ').'); + Exit; + end; + + if QueryServiceConfig(hSvc, nil, 0, pcbBytesNeeded) then begin + Writeln('[-] QueryServiceConfig failed.'); + Exit; + end; + + cbBufSize := pcbBytesNeeded; + GetMem(Buf, cbBufSize); + + if not QueryServiceConfig(hSvc, Buf, cbBufSize, pcbBytesNeeded) then begin + FreeMem(Buf, cbBufSize); + CloseServiceHandle(hSvc); + CloseServiceHandle(hSC); + Code := GetLastError; + Writeln('[-] QueryServiceConfig error (code ', Code, ').'); + Exit; + end else begin + lpServiceConfig := Buf; + Result := Integer(lpServiceConfig^.dwStartType); + end; + FreeMem(Buf, cbBufSize); + CloseServiceHandle(hSvc); + CloseServiceHandle(hSC); +end; + +procedure SvcConfigStart(SvcName: String; dwStartType: Cardinal); +var + hSC: SC_HANDLE; + hSvc: THandle; + Code: DWORD; +begin + Writeln('[*] Configuring ', SvcName, '...'); + hSC := OpenSCManager(nil, SERVICES_ACTIVE_DATABASE, SC_MANAGER_CONNECT); + if hSC = 0 then + begin + Code := GetLastError; + Writeln('[-] OpenSCManager error (code ', Code, ').'); + Exit; + end; + + hSvc := OpenService(hSC, PWideChar(SvcName), SERVICE_CHANGE_CONFIG); + if hSvc = 0 then + begin + CloseServiceHandle(hSC); + Code := GetLastError; + Writeln('[-] OpenService error (code ', Code, ').'); + Exit; + end; + + if not ChangeServiceConfig(hSvc, SERVICE_NO_CHANGE, dwStartType, + SERVICE_NO_CHANGE, nil, nil, nil, nil, nil, nil, nil) then begin + CloseServiceHandle(hSvc); + CloseServiceHandle(hSC); + Code := GetLastError; + Writeln('[-] ChangeServiceConfig error (code ', Code, ').'); + Exit; + end; + CloseServiceHandle(hSvc); + CloseServiceHandle(hSC); +end; + +procedure SvcStart(SvcName: String); +var + hSC: SC_HANDLE; + hSvc: THandle; + Code: DWORD; + pch: PWideChar; +begin + Writeln('[*] Starting ', SvcName, '...'); + hSC := OpenSCManager(nil, SERVICES_ACTIVE_DATABASE, SC_MANAGER_CONNECT); + if hSC = 0 then + begin + Code := GetLastError; + Writeln('[-] OpenSCManager error (code ', Code, ').'); + Exit; + end; + + hSvc := OpenService(hSC, PWideChar(SvcName), SERVICE_START); + if hSvc = 0 then + begin + CloseServiceHandle(hSC); + Code := GetLastError; + Writeln('[-] OpenService error (code ', Code, ').'); + Exit; + end; + + pch := nil; + if not StartService(hSvc, 0, pch) then begin + CloseServiceHandle(hSvc); + CloseServiceHandle(hSC); + Code := GetLastError; + Writeln('[-] StartService error (code ', Code, ').'); + Exit; + end; + CloseServiceHandle(hSvc); + CloseServiceHandle(hSC); +end; + +procedure CheckTermsrvProcess; +label + back; +var + hSC: SC_HANDLE; + dwNeedBytes, dwReturnBytes, dwResumeHandle, Code: DWORD; + Svc: Array of ENUM_SERVICE_STATUS_PROCESS; + I: Integer; + Found, Started: Boolean; + TermServiceName: String; +begin + Started := False; + back: + hSC := OpenSCManager(nil, SERVICES_ACTIVE_DATABASE, SC_MANAGER_CONNECT or SC_MANAGER_ENUMERATE_SERVICE); + if hSC = 0 then + begin + Code := GetLastError; + Writeln('[-] OpenSCManager error (code ', Code, ').'); + Halt(Code); + end; + + SetLength(Svc, 1489); + FillChar(Svc[0], sizeof(Svc[0])*Length(Svc), 0); + if not EnumServicesStatusEx(hSC, SC_ENUM_PROCESS_INFO, SERVICE_WIN32, SERVICE_STATE_ALL, + @Svc[0], sizeof(Svc[0])*Length(Svc), dwNeedBytes, dwReturnBytes, dwResumeHandle, nil) then begin + Code := GetLastError; + if Code <> ERROR_MORE_DATA then + begin + CloseServiceHandle(hSC); + Writeln('[-] EnumServicesStatusEx error (code ', Code, ').'); + Halt(Code); + end + else + begin + SetLength(Svc, 5957); + FillChar(Svc[0], sizeof(Svc[0])*Length(Svc), 0); + if not EnumServicesStatusEx(hSC, SC_ENUM_PROCESS_INFO, SERVICE_WIN32, SERVICE_STATE_ALL, + @Svc[0], sizeof(Svc[0])*Length(Svc), dwNeedBytes, dwReturnBytes, dwResumeHandle, nil) then begin + CloseServiceHandle(hSC); + Code := GetLastError; + Writeln('[-] EnumServicesStatusEx error (code ', Code, ').'); + Halt(Code); + end; + end; + end; + CloseServiceHandle(hSC); + + Found := False; + for I := 0 to Length(Svc) - 1 do + begin + if Svc[I].lpServiceName = nil then + Break; + if LowerCase(Svc[I].lpServiceName) = LowerCase(TermService) then + begin + Found := True; + TermServiceName := Svc[I].lpServiceName; + TermServicePID := Svc[I].ServiceStatusProcess.dwProcessId; + Break; + end; + end; + if not Found then + begin + Writeln('[-] TermService not found.'); + Halt(ERROR_SERVICE_DOES_NOT_EXIST); + end; + if TermServicePID = 0 then + begin + if Started then begin + Writeln('[-] Failed to set up TermService. Unknown error.'); + Halt(ERROR_SERVICE_NOT_ACTIVE); + end; + SvcConfigStart(TermService, SERVICE_AUTO_START); + SvcStart(TermService); + Started := True; + goto back; + end + else + Writeln('[+] TermService found (pid ', TermServicePID, ').'); + + SetLength(ShareSvc, 0); + for I := 0 to Length(Svc) - 1 do + begin + if Svc[I].lpServiceName = nil then + Break; + if Svc[I].ServiceStatusProcess.dwProcessId = TermServicePID then + if Svc[I].lpServiceName <> TermServiceName then + begin + SetLength(ShareSvc, Length(ShareSvc)+1); + ShareSvc[Length(ShareSvc)-1] := Svc[I].lpServiceName; + end; + end; + sShareSvc := ''; + for I := 0 to Length(ShareSvc) - 1 do + if sShareSvc = '' then + sShareSvc := ShareSvc[I] + else + sShareSvc := sShareSvc + ', ' + ShareSvc[I]; + if sShareSvc <> '' then + Writeln('[*] Shared services found: ', sShareSvc) + else + Writeln('[*] No shared services found.'); +end; + +function AddPrivilege(SePriv: String): Boolean; +var + hToken: THandle; + SeNameValue: Int64; + tkp: TOKEN_PRIVILEGES; + ReturnLength: Cardinal; + ErrorCode: Cardinal; +begin + Result := False; + if not OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES + or TOKEN_QUERY, hToken) then begin + ErrorCode := GetLastError; + Writeln('[-] OpenProcessToken error (code ' + IntToStr(ErrorCode) + ').'); + Exit; + end; + if not LookupPrivilegeValue(nil, PWideChar(SePriv), SeNameValue) then begin + ErrorCode := GetLastError; + Writeln('[-] LookupPrivilegeValue error (code ' + IntToStr(ErrorCode) + ').'); + Exit; + end; + tkp.PrivilegeCount := 1; + tkp.Privileges[0].Luid := SeNameValue; + tkp.Privileges[0].Attributes := SE_PRIVILEGE_ENABLED; + if not AdjustTokenPrivileges(hToken, False, tkp, SizeOf(tkp), tkp, ReturnLength) then begin + ErrorCode := GetLastError; + Writeln('[-] AdjustTokenPrivileges error (code ' + IntToStr(ErrorCode) + ').'); + Exit; + end; + Result := True; +end; + +procedure KillProcess(PID: DWORD); +var + hProc: THandle; + Code: DWORD; +begin + hProc := OpenProcess(PROCESS_TERMINATE, False, PID); + if hProc = 0 then + begin + Code := GetLastError; + Writeln('[-] OpenProcess error (code ', Code, ').'); + Halt(Code); + end; + if not TerminateProcess(hProc, 0) then + begin + CloseHandle(hProc); + Code := GetLastError; + Writeln('[-] TerminateProcess error (code ', Code, ').'); + Halt(Code); + end; + CloseHandle(hProc); +end; + +function ExecWait(Cmdline: String): Boolean; +var + si: STARTUPINFO; + pi: PROCESS_INFORMATION; +begin + Result := False; + ZeroMemory(@si, sizeof(si)); + si.cb := sizeof(si); + UniqueString(Cmdline); + if not CreateProcess(nil, PWideChar(Cmdline), nil, nil, True, 0, nil, nil, si, pi) then begin + Writeln('[-] CreateProcess error (code: ', GetLastError, ').'); + Exit; + end; + CloseHandle(pi.hThread); + WaitForSingleObject(pi.hProcess, INFINITE); + CloseHandle(pi.hProcess); + Result := True; +end; + +function ExpandPath(Path: String): String; +var + Str: Array[0..511] of Char; +begin + Result := ''; + FillChar(Str, 512, 0); + if Arch = 64 then + Path := StringReplace(Path, '%ProgramFiles%', '%ProgramW6432%', [rfReplaceAll, rfIgnoreCase]); + if ExpandEnvironmentStrings(PWideChar(Path), Str, 512) > 0 then + Result := Str; +end; + +procedure SetWrapperDll; +var + Reg: TRegistry; + Code: DWORD; +begin + if Arch = 64 then + Reg := TRegistry.Create(KEY_WRITE or KEY_WOW64_64KEY) + else + Reg := TRegistry.Create; + Reg.RootKey := HKEY_LOCAL_MACHINE; + if not Reg.OpenKey('\SYSTEM\CurrentControlSet\Services\TermService\Parameters', True) then + begin + Code := GetLastError; + Writeln('[-] OpenKey error (code ', Code, ').'); + Halt(Code); + end; + try + Reg.WriteExpandString('ServiceDll', WrapPath); + if (Arch = 64) and (FV.Version.w.Major = 6) and (FV.Version.w.Minor = 0) then + ExecWait('"'+ExpandPath('%SystemRoot%')+'\system32\reg.exe" add HKLM\SYSTEM\CurrentControlSet\Services\TermService\Parameters /v ServiceDll /t REG_EXPAND_SZ /d "'+WrapPath+'" /f'); + except + Writeln('[-] WriteExpandString error.'); + Halt(ERROR_ACCESS_DENIED); + end; + + Reg.CloseKey; + Reg.Free; +end; + +procedure ResetServiceDll; +var + Reg: TRegistry; + Code: DWORD; +begin + if Arch = 64 then + Reg := TRegistry.Create(KEY_WRITE or KEY_WOW64_64KEY) + else + Reg := TRegistry.Create; + Reg.RootKey := HKEY_LOCAL_MACHINE; + if not Reg.OpenKey('\SYSTEM\CurrentControlSet\Services\TermService\Parameters', True) then + begin + Code := GetLastError; + Writeln('[-] OpenKey error (code ', Code, ').'); + Halt(Code); + end; + try + Reg.WriteExpandString('ServiceDll', '%SystemRoot%\System32\termsrv.dll'); + except + Writeln('[-] WriteExpandString error.'); + Halt(ERROR_ACCESS_DENIED); + end; + Reg.CloseKey; + Reg.Free; +end; + +procedure ExtractRes(ResName, Path: String); +var + ResStream: TResourceStream; +begin + ResStream := TResourceStream.Create(HInstance, ResName, RT_RCDATA); + try + ResStream.SaveToFile(Path); + except + Writeln('[-] Failed to extract file.'); + Writeln('[*] Resource name: ' + ResName); + Writeln('[*] Destination path: ' + Path); + ResStream.Free; + Exit; + end; + Writeln('[+] Extracted ', ResName, ' -> ', Path); + ResStream.Free; +end; + +procedure ExtractFiles; +begin + if not DirectoryExists(ExtractFilePath(ExpandPath(WrapPath))) then + if ForceDirectories(ExtractFilePath(ExpandPath(WrapPath))) then + Writeln('[+] Folder created: ', ExtractFilePath(ExpandPath(WrapPath))) + else begin + Writeln('[-] ForceDirectories error.'); + Writeln('[*] Path: ', ExtractFilePath(ExpandPath(WrapPath))); + Halt(0); + end; + case Arch of + 32: begin + ExtractRes('rdpw32', ExpandPath(WrapPath)); + if not FileExists(ExpandPath('%SystemRoot%\System32\rdpclip.exe')) then + ExtractRes('rdpclip32', ExpandPath('%SystemRoot%\System32\rdpclip.exe')); + end; + 64: begin + ExtractRes('rdpw64', ExpandPath(WrapPath)); + if not FileExists(ExpandPath('%SystemRoot%\System32\rdpclip.exe')) then + ExtractRes('rdpclip64', ExpandPath('%SystemRoot%\System32\rdpclip.exe')); + end; + end; +end; + +procedure DeleteFiles; +var + Code: DWORD; +begin + if not DeleteFile(PWideChar(ExpandPath(TermServicePath))) then + begin + Code := GetLastError; + Writeln('[-] DeleteFile error (code ', Code, ').'); + Exit; + end; + Writeln('[+] Removed file: ', ExpandPath(TermServicePath)); + if not RemoveDirectory(PWideChar(ExtractFilePath(ExpandPath(TermServicePath)))) then + begin + Code := GetLastError; + Writeln('[-] RemoveDirectory error (code ', Code, ').'); + Exit; + end; + Writeln('[+] Removed folder: ', ExtractFilePath(ExpandPath(TermServicePath))); +end; + +function GetFileVersion(const FileName: TFileName; var FileVersion: FILE_VERSION): Boolean; +type + VS_VERSIONINFO = record + wLength, wValueLength, wType: Word; + szKey: Array[1..16] of WideChar; + Padding1: Word; + Value: VS_FIXEDFILEINFO; + Padding2, Children: Word; + end; + PVS_VERSIONINFO = ^VS_VERSIONINFO; +const + VFF_DEBUG = 1; + VFF_PRERELEASE = 2; + VFF_PRIVATE = 8; + VFF_SPECIAL = 32; +var + hFile: HMODULE; + hResourceInfo: HRSRC; + VersionInfo: PVS_VERSIONINFO; +begin + Result := False; + + hFile := LoadLibraryEx(PWideChar(FileName), 0, LOAD_LIBRARY_AS_DATAFILE); + if hFile = 0 then + Exit; + + hResourceInfo := FindResource(hFile, PWideChar(1), PWideChar($10)); + if hResourceInfo = 0 then + Exit; + + VersionInfo := Pointer(LoadResource(hFile, hResourceInfo)); + if VersionInfo = nil then + Exit; + + FileVersion.Version.dw := VersionInfo.Value.dwFileVersionMS; + FileVersion.Release := Word(VersionInfo.Value.dwFileVersionLS shr 16); + FileVersion.Build := Word(VersionInfo.Value.dwFileVersionLS); + FileVersion.bDebug := (VersionInfo.Value.dwFileFlags and VFF_DEBUG) = VFF_DEBUG; + FileVersion.bPrerelease := (VersionInfo.Value.dwFileFlags and VFF_PRERELEASE) = VFF_PRERELEASE; + FileVersion.bPrivate := (VersionInfo.Value.dwFileFlags and VFF_PRIVATE) = VFF_PRIVATE; + FileVersion.bSpecial := (VersionInfo.Value.dwFileFlags and VFF_SPECIAL) = VFF_SPECIAL; + + Result := True; +end; + +procedure CheckTermsrvVersion; +var + SuppLvl: Byte; +begin + GetFileVersion(ExpandPath(TermServicePath), FV); + Writeln('[*] Terminal Services version: ', + Format('%d.%d.%d.%d', + [FV.Version.w.Major, FV.Version.w.Minor, FV.Release, FV.Build])); + + if (FV.Version.w.Major = 5) and (FV.Version.w.Minor = 1) then + begin + if Arch = 32 then + begin + Writeln('[!] Windows XP is not supported.'); + Writeln('You may take a look at RDP Realtime Patch by Stas''M for Windows XP'); + Writeln('Link: http://stascorp.com/load/1-1-0-62'); + end; + if Arch = 64 then + Writeln('[!] Windows XP 64-bit Edition is not supported.'); + Exit; + end; + if (FV.Version.w.Major = 5) and (FV.Version.w.Minor = 2) then + begin + if Arch = 32 then + Writeln('[!] Windows Server 2003 is not supported.'); + if Arch = 64 then + Writeln('[!] Windows Server 2003 or XP 64-bit Edition is not supported.'); + Exit; + end; + SuppLvl := 0; + if (FV.Version.w.Major = 6) and (FV.Version.w.Minor = 0) then begin + SuppLvl := 1; + if (Arch = 32) and (FV.Release = 6000) and (FV.Build = 16386) then begin + Writeln('[!] This version of Terminal Services may crash on logon attempt.'); + Writeln('It''s recommended to upgrade to Service Pack 1 or higher.'); + end; + if (FV.Release = 6000) and (FV.Build = 16386) then + SuppLvl := 2; + if (FV.Release = 6001) and (FV.Build = 18000) then + SuppLvl := 2; + if (FV.Release = 6002) and (FV.Build = 18005) then + SuppLvl := 2; + end; + if (FV.Version.w.Major = 6) and (FV.Version.w.Minor = 1) then begin + SuppLvl := 1; + if (FV.Release = 7600) and (FV.Build = 16385) then + SuppLvl := 2; + if (FV.Release = 7601) and (FV.Build = 17514) then + SuppLvl := 2; + if (FV.Release = 7601) and (FV.Build = 18540) then + SuppLvl := 2; + if (FV.Release = 7601) and (FV.Build = 22750) then + SuppLvl := 2; + end; + if (FV.Version.w.Major = 6) and (FV.Version.w.Minor = 2) then begin + if (FV.Release = 8102) and (FV.Build = 0) then + SuppLvl := 2; + if (FV.Release = 8250) and (FV.Build = 0) then + SuppLvl := 2; + if (FV.Release = 8400) and (FV.Build = 0) then + SuppLvl := 2; + if (FV.Release = 9200) and (FV.Build = 16384) then + SuppLvl := 2; + if (FV.Release = 9200) and (FV.Build = 17048) then + SuppLvl := 2; + if (FV.Release = 9200) and (FV.Build = 21166) then + SuppLvl := 2; + end; + if (FV.Version.w.Major = 6) and (FV.Version.w.Minor = 3) then begin + if (FV.Release = 9431) and (FV.Build = 0) then + SuppLvl := 2; + if (FV.Release = 9600) and (FV.Build = 16384) then + SuppLvl := 2; + if (FV.Release = 9600) and (FV.Build = 17095) then + SuppLvl := 2; + end; + if (FV.Version.w.Major = 6) and (FV.Version.w.Minor = 4) then begin + if (FV.Release = 9841) and (FV.Build = 0) then + SuppLvl := 2; + end; + case SuppLvl of + 0: begin + Writeln('[!] This version of Terminal Services is not supported.'); + Writeln('Send your termsrv.dll to project developer for support.'); + end; + 1: begin + Writeln('[!] This version of Terminal Services is supported partially.'); + Writeln('It means you may have some limitations such as only 2 concurrent sessions.'); + Writeln('Send your termsrv.dll to project developer for adding full support.'); + end; + end; +end; + +procedure CheckTermsrvDependencies; +const + CertPropSvc = 'CertPropSvc'; + SessionEnv = 'SessionEnv'; +begin + if SvcGetStart(CertPropSvc) = SERVICE_DISABLED then + SvcConfigStart(CertPropSvc, SERVICE_DEMAND_START); + if SvcGetStart(SessionEnv) = SERVICE_DISABLED then + SvcConfigStart(SessionEnv, SERVICE_DEMAND_START); +end; + +procedure TSConfigRegistry(Enable: Boolean); +var + Reg: TRegistry; + Code: DWORD; +begin + if Arch = 64 then + Reg := TRegistry.Create(KEY_WRITE or KEY_WOW64_64KEY) + else + Reg := TRegistry.Create; + Reg.RootKey := HKEY_LOCAL_MACHINE; + if not Reg.OpenKey('\SYSTEM\CurrentControlSet\Control\Terminal Server', True) then + begin + Code := GetLastError; + Writeln('[-] OpenKey error (code ', Code, ').'); + Halt(Code); + end; + try + Reg.WriteBool('fDenyTSConnections', not Enable); + except + Writeln('[-] WriteBool error.'); + Halt(ERROR_ACCESS_DENIED); + end; + Reg.CloseKey; + if Enable then + begin + if not Reg.OpenKey('\SYSTEM\CurrentControlSet\Control\Terminal Server\Licensing Core', True) then + begin + Code := GetLastError; + Writeln('[-] OpenKey error (code ', Code, ').'); + Halt(Code); + end; + try + Reg.WriteBool('EnableConcurrentSessions', True); + except + Writeln('[-] WriteBool error.'); + Halt(ERROR_ACCESS_DENIED); + end; + Reg.CloseKey; + + if not Reg.OpenKey('\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Winlogon', True) then + begin + Code := GetLastError; + Writeln('[-] OpenKey error (code ', Code, ').'); + Halt(Code); + end; + try + Reg.WriteBool('AllowMultipleTSSessions', True); + except + Writeln('[-] WriteBool error.'); + Halt(ERROR_ACCESS_DENIED); + end; + Reg.CloseKey; + + if not Reg.KeyExists('\SYSTEM\CurrentControlSet\Control\Terminal Server\AddIns') then begin + if not Reg.OpenKey('\SYSTEM\CurrentControlSet\Control\Terminal Server\AddIns', True) then + begin + Code := GetLastError; + Writeln('[-] OpenKey error (code ', Code, ').'); + Halt(Code); + end; + Reg.CloseKey; + if not Reg.OpenKey('\SYSTEM\CurrentControlSet\Control\Terminal Server\AddIns\Clip Redirector', True) then + begin + Code := GetLastError; + Writeln('[-] OpenKey error (code ', Code, ').'); + Halt(Code); + end; + try + Reg.WriteString('Name', 'RDPClip'); + Reg.WriteInteger('Type', 3); + except + Writeln('[-] WriteInteger error.'); + Halt(ERROR_ACCESS_DENIED); + end; + Reg.CloseKey; + if not Reg.OpenKey('\SYSTEM\CurrentControlSet\Control\Terminal Server\AddIns\DND Redirector', True) then + begin + Code := GetLastError; + Writeln('[-] OpenKey error (code ', Code, ').'); + Halt(Code); + end; + try + Reg.WriteString('Name', 'RDPDND'); + Reg.WriteInteger('Type', 3); + except + Writeln('[-] WriteInteger error.'); + Halt(ERROR_ACCESS_DENIED); + end; + Reg.CloseKey; + if not Reg.OpenKey('\SYSTEM\CurrentControlSet\Control\Terminal Server\AddIns\Dynamic VC', True) then + begin + Code := GetLastError; + Writeln('[-] OpenKey error (code ', Code, ').'); + Halt(Code); + end; + try + Reg.WriteInteger('Type', -1); + except + Writeln('[-] WriteInteger error.'); + Halt(ERROR_ACCESS_DENIED); + end; + Reg.CloseKey; + end; + end; + Reg.Free; +end; + +procedure TSConfigFirewall(Enable: Boolean); +begin + if Enable then + ExecWait('netsh advfirewall firewall add rule name="Remote Desktop" dir=in protocol=tcp localport=3389 profile=any action=allow') + else + ExecWait('netsh advfirewall firewall delete rule name="Remote Desktop"'); +end; + +var + I: Integer; +begin + Writeln('RDP Wrapper Library v1.3'); + Writeln('Installer v2.2'); + Writeln('Copyright (C) Stas''M Corp. 2014'); + Writeln(''); + + if (ParamCount < 1) + or ( + (ParamStr(1) <> '-i') + and (ParamStr(1) <> '-u') + and (ParamStr(1) <> '-r') + ) then + begin + Writeln('USAGE:'); + Writeln('RDPWInst.exe [-i[-s]|-u|-r]'); + Writeln(''); + Writeln('-i install wrapper to Program Files folder (default)'); + Writeln('-i -s install wrapper to System32 folder'); + Writeln('-u uninstall wrapper'); + Writeln('-r force restart Terminal Services'); + Exit; + end; + + if not SupportedArchitecture then + begin + Writeln('[-] Unsupported processor architecture.'); + Exit; + end; + + CheckInstall; + + if ParamStr(1) = '-i' then + begin + if Installed then + begin + Writeln('[*] RDP Wrapper Library is already installed.'); + Halt(ERROR_INVALID_FUNCTION); + end; + Writeln('[*] Installing...'); + if ParamStr(2) = '-s' then + WrapPath := '%SystemRoot%\system32\rdpwrap.dll' + else + WrapPath := '%ProgramFiles%\RDP Wrapper\rdpwrap.dll'; + + if Arch = 64 then + DisableWowRedirection; + + CheckTermsrvVersion; + CheckTermsrvProcess; + + Writeln('[*] Extracting files...'); + ExtractFiles; + + Writeln('[*] Configuring service library...'); + SetWrapperDll; + + Writeln('[*] Checking dependencies...'); + CheckTermsrvDependencies; + + Writeln('[*] Terminating service...'); + AddPrivilege('SeDebugPrivilege'); + KillProcess(TermServicePID); + Sleep(1000); + + if Length(ShareSvc) > 0 then + for I := 0 to Length(ShareSvc) - 1 do + SvcStart(ShareSvc[I]); + Sleep(500); + SvcStart(TermService); + Sleep(500); + + Writeln('[*] Configuring registry...'); + TSConfigRegistry(True); + Writeln('[*] Configuring firewall...'); + TSConfigFirewall(True); + + Writeln('[+] Successfully installed.'); + + if Arch = 64 then + RevertWowRedirection; + end; + if ParamStr(1) = '-u' then + begin + if not Installed then + begin + Writeln('[*] RDP Wrapper Library is not installed.'); + Halt(ERROR_INVALID_FUNCTION); + end; + Writeln('[*] Uninstalling...'); + + if Arch = 64 then + DisableWowRedirection; + + CheckTermsrvProcess; + + Writeln('[*] Resetting service library...'); + ResetServiceDll; + + Writeln('[*] Terminating service...'); + AddPrivilege('SeDebugPrivilege'); + KillProcess(TermServicePID); + Sleep(1000); + + Writeln('[*] Removing files...'); + DeleteFiles; + + if Length(ShareSvc) > 0 then + for I := 0 to Length(ShareSvc) - 1 do + SvcStart(ShareSvc[I]); + Sleep(500); + SvcStart(TermService); + Sleep(500); + + Writeln('[*] Configuring registry...'); + TSConfigRegistry(False); + Writeln('[*] Configuring firewall...'); + TSConfigFirewall(False); + + if Arch = 64 then + RevertWowRedirection; + + Writeln('[+] Successfully uninstalled.'); + end; + if ParamStr(1) = '-r' then + begin + Writeln('[*] Restarting...'); + + CheckTermsrvProcess; + + Writeln('[*] Terminating service...'); + AddPrivilege('SeDebugPrivilege'); + KillProcess(TermServicePID); + Sleep(1000); + + if Length(ShareSvc) > 0 then + for I := 0 to Length(ShareSvc) - 1 do + SvcStart(ShareSvc[I]); + Sleep(500); + SvcStart(TermService); + + Writeln('[+] Done.'); + end; +end. diff --git a/src-installer/RDPWInst.dproj b/src-installer/RDPWInst.dproj new file mode 100644 index 0000000..78b7b03 --- /dev/null +++ b/src-installer/RDPWInst.dproj @@ -0,0 +1,105 @@ + + + {AF9BEAA3-99CD-4B2E-BE67-3F3BD27B961A} + 12.0 + RDPWInst.dpr + Release + DCC32 + + + true + + + true + Base + true + + + true + Base + true + + + WinTypes=Windows;WinProcs=Windows;DbiTypes=BDE;DbiProcs=BDE;DbiErrs=BDE;$(DCC_UnitAlias) + RDPWInst.exe + 00400000 + x86 + + + false + RELEASE;$(DCC_Define) + 0 + false + + + DEBUG;$(DCC_Define) + + + + MainSource + + + Base + + + Cfg_2 + Base + + + Cfg_1 + Base + + + + + Delphi.Personality.12 + + + + + False + True + False + -i + + + False + False + 1 + 0 + 0 + 0 + False + False + False + False + False + 1049 + 1251 + + + + + 1.0.0.0 + + + + + + 1.0.0.0 + + + + Embarcadero C++Builder Office 2000 Servers Package + Embarcadero C++Builder Office XP Servers Package + Microsoft Office 2000 Sample Automation Server Wrapper Components + Microsoft Office XP Sample Automation Server Wrapper Components + + + RDPWInst.dpr + + + + 12 + + diff --git a/src-installer/RDPWInst.dproj.local b/src-installer/RDPWInst.dproj.local new file mode 100644 index 0000000..673bb99 --- /dev/null +++ b/src-installer/RDPWInst.dproj.local @@ -0,0 +1,8 @@ + + + + 2013.12.07 17:17:05.152.dproj,C:\Users\user\Documents\RAD Studio\Projects\Project1.dproj=C:\Users\user\Documents\Delphi Projects (local)\RDPWrapInst\RDPInstall.dproj + 2013.12.07 19:48:57.905.dproj,C:\Users\user\Documents\Delphi Projects (local)\RDPWrapInst\RDPInstall.dproj=C:\Users\user\Documents\Delphi Projects (local)\RDPWrapInst\RDPWInst.dproj + 2013.12.08 01:45:08.501.dproj,C:\Users\user\Documents\Delphi Projects (local)\RDPWrapInst\RDPWInst.dproj=C:\Users\user\Documents\Delphi Projects (local)\RDPWrap\devel\installer2.0-binarymaster\RDPWInst.dproj + + diff --git a/src-installer/RDPWInst.identcache b/src-installer/RDPWInst.identcache new file mode 100644 index 0000000..2ed9853 Binary files /dev/null and b/src-installer/RDPWInst.identcache differ diff --git a/src-installer/RDPWInstResource.rc b/src-installer/RDPWInstResource.rc new file mode 100644 index 0000000..a0a5a20 --- /dev/null +++ b/src-installer/RDPWInstResource.rc @@ -0,0 +1,4 @@ +rdpclip64 RCData "..\\rdpclip-x64.exe" +rdpclip32 RCData "..\\rdpclip-x86.exe" +rdpw32 RCData "..\\v1.2-x86-binarymaster\\rdpwrap.dll" +rdpw64 RCData "..\\v1.2-x86-x64-Fusix\\rdpw64.dll" diff --git a/src-installer/resource.res b/src-installer/resource.res new file mode 100644 index 0000000..4c2aa02 Binary files /dev/null and b/src-installer/resource.res differ diff --git a/src-rdpcheck/MainUnit.dcu b/src-rdpcheck/MainUnit.dcu new file mode 100644 index 0000000..97137d3 Binary files /dev/null and b/src-rdpcheck/MainUnit.dcu differ diff --git a/src-rdpcheck/MainUnit.dfm b/src-rdpcheck/MainUnit.dfm new file mode 100644 index 0000000..2533973 --- /dev/null +++ b/src-rdpcheck/MainUnit.dfm @@ -0,0 +1,29 @@ +object Frm: TFrm + Left = 0 + Top = 0 + BorderIcons = [biSystemMenu, biMinimize] + BorderStyle = bsSingle + Caption = 'Local RDP Checker' + ClientHeight = 480 + ClientWidth = 640 + Color = clBtnFace + Font.Charset = DEFAULT_CHARSET + Font.Color = clWindowText + Font.Height = -11 + Font.Name = 'Tahoma' + Font.Style = [] + OldCreateOrder = False + Position = poDesktopCenter + OnCreate = FormCreate + PixelsPerInch = 96 + TextHeight = 13 + object RDP: TMsRdpClient2 + Left = 0 + Top = 0 + Width = 640 + Height = 480 + TabOrder = 0 + OnDisconnected = RDPDisconnected + ControlData = {0003000008000200000000000B0000000B000000} + end +end diff --git a/src-rdpcheck/MainUnit.pas b/src-rdpcheck/MainUnit.pas new file mode 100644 index 0000000..af750f1 --- /dev/null +++ b/src-rdpcheck/MainUnit.pas @@ -0,0 +1,145 @@ +unit MainUnit; + +interface + +uses + Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, + Dialogs, OleServer, MSTSCLib_TLB, OleCtrls, Registry; + +type + TFrm = class(TForm) + RDP: TMsRdpClient2; + procedure RDPDisconnected(ASender: TObject; discReason: Integer); + procedure FormCreate(Sender: TObject); + private + { Private declarations } + public + { Public declarations } + end; + +var + Frm: TFrm; + SecurityLayer, UserAuthentication: DWORD; + +implementation + +{$R *.dfm} + +procedure TFrm.FormCreate(Sender: TObject); +var + Reg: TRegistry; + Port: Integer; +begin + RDP.DisconnectedText := 'Disconnected.'; + RDP.ConnectingText := 'Connecting...'; + RDP.ConnectedStatusText := 'Connected.'; + RDP.UserName := ''; + RDP.Server := '127.0.0.1'; + Reg := TRegistry.Create; + Reg.RootKey := HKEY_LOCAL_MACHINE; + + if Reg.OpenKey('\SYSTEM\CurrentControlSet\Control\Terminal Server\WinStations\RDP-Tcp', True) then + begin + try + SecurityLayer := Reg.ReadInteger('SecurityLayer'); + UserAuthentication := Reg.ReadInteger('UserAuthentication'); + Reg.WriteInteger('SecurityLayer', 0); + Reg.WriteInteger('UserAuthentication', 0); + except + + end; + Reg.CloseKey; + end; + + if Reg.OpenKeyReadOnly('\SYSTEM\CurrentControlSet\Control\Terminal Server\WinStations\RDP-Tcp') then begin + try + RDP.AdvancedSettings2.RDPPort := Reg.ReadInteger('PortNumber'); + except + + end; + Reg.CloseKey; + end; + Reg.Free; + Sleep(1000); + RDP.Connect; +end; + +procedure TFrm.RDPDisconnected(ASender: TObject; discReason: Integer); +var + ErrStr: String; + Reg: TRegistry; +begin + case discReason of + 1: ErrStr := 'Local disconnection.'; + 2: ErrStr := 'Disconnected by user.'; + 3: ErrStr := 'Disconnected by server.'; + $904: ErrStr := 'Socket closed.'; + $C08: ErrStr := 'Decompress error.'; + $108: ErrStr := 'Connection timed out.'; + $C06: ErrStr := 'Decryption error.'; + $104: ErrStr := 'DNS name lookup failure.'; + $508: ErrStr := 'DNS lookup failed.'; + $B06: ErrStr := 'Encryption error.'; + $604: ErrStr := 'Windows Sockets gethostbyname() call failed.'; + $208: ErrStr := 'Host not found error.'; + $408: ErrStr := 'Internal error.'; + $906: ErrStr := 'Internal security error.'; + $A06: ErrStr := 'Internal security error.'; + $506: ErrStr := 'The encryption method specified is not valid.'; + $804: ErrStr := 'Bad IP address specified.'; + $606: ErrStr := 'Server security data is not valid.'; + $406: ErrStr := 'Security data is not valid.'; + $308: ErrStr := 'The IP address specified is not valid.'; + $808: ErrStr := 'License negotiation failed.'; + $908: ErrStr := 'Licensing time-out.'; + $106: ErrStr := 'Out of memory.'; + $206: ErrStr := 'Out of memory.'; + $306: ErrStr := 'Out of memory.'; + $706: ErrStr := 'Failed to unpack server certificate.'; + $204: ErrStr := 'Socket connection failed.'; + $404: ErrStr := 'Windows Sockets recv() call failed.'; + $704: ErrStr := 'Time-out occurred.'; + $608: ErrStr := 'Internal timer error.'; + $304: ErrStr := 'Windows Sockets send() call failed.'; + $B07: ErrStr := 'The account is disabled.'; + $E07: ErrStr := 'The account is expired.'; + $D07: ErrStr := 'The account is locked out.'; + $C07: ErrStr := 'The account is restricted.'; + $1B07: ErrStr := 'The received certificate is expired.'; + $1607: ErrStr := 'The policy does not support delegation of credentials to the target server.'; + $2107: ErrStr := 'The server authentication policy does not allow connection requests using saved credentials. The user must enter new credentials.'; + $807: ErrStr := 'Login failed.'; + $1807: ErrStr := 'No authority could be contacted for authentication. The domain name of the authenticating party could be wrong, the domain could be unreachable, or there might have been a trust relationship failure.'; + $A07: ErrStr := 'The specified user has no account.'; + $F07: ErrStr := 'The password is expired.'; + $1207: ErrStr := 'The user password must be changed before logging on for the first time.'; + $1707: ErrStr := 'Delegation of credentials to the target server is not allowed unless mutual authentication has been achieved.'; + $2207: ErrStr := 'The smart card is blocked.'; + $1C07: ErrStr := 'An incorrect PIN was presented to the smart card.'; + $B09: ErrStr := 'Network Level Authentication is required.'; + $708: ErrStr := 'The RDP seems to work, but your client doesn''t support loopback connections. Try to connect to your PC from another device in the network.'; + else ErrStr := 'Unknown code 0x'+IntToHex(discReason, 1); + end; + if (discReason > 2) then + MessageBox(Handle, PWideChar(ErrStr), 'Disconnected', mb_Ok or mb_IconError); + + Reg := TRegistry.Create; + Reg.RootKey := HKEY_LOCAL_MACHINE; + + if Reg.OpenKey('\SYSTEM\CurrentControlSet\Control\Terminal Server\WinStations\RDP-Tcp', True) then + begin + try + Reg.WriteInteger('SecurityLayer', SecurityLayer); + Reg.WriteInteger('UserAuthentication', UserAuthentication); + except + + end; + Reg.CloseKey; + end; + + Reg.Free; + + Halt(0); +end; + +end. diff --git a/src-rdpcheck/RDP.ico b/src-rdpcheck/RDP.ico new file mode 100644 index 0000000..05a7b71 Binary files /dev/null and b/src-rdpcheck/RDP.ico differ diff --git a/src-rdpcheck/RDPCheck.dpr b/src-rdpcheck/RDPCheck.dpr new file mode 100644 index 0000000..3e05407 --- /dev/null +++ b/src-rdpcheck/RDPCheck.dpr @@ -0,0 +1,15 @@ +program RDPCheck; + +uses + Forms, + MainUnit in 'MainUnit.pas' {Frm}; + +{$R *.res} + +begin + Application.Initialize; + Application.MainFormOnTaskbar := True; + Application.Title := 'Local RDP Checker'; + Application.CreateForm(TFrm, Frm); + Application.Run; +end. diff --git a/src-rdpcheck/RDPCheck.dproj b/src-rdpcheck/RDPCheck.dproj new file mode 100644 index 0000000..d88a8c6 --- /dev/null +++ b/src-rdpcheck/RDPCheck.dproj @@ -0,0 +1,107 @@ + + + {90AE83F6-26B8-45D4-92FE-CF4ACCDE9F68} + 12.0 + RDPCheck.dpr + Release + DCC32 + + + true + + + true + Base + true + + + true + Base + true + + + WinTypes=Windows;WinProcs=Windows;DbiTypes=BDE;DbiProcs=BDE;DbiErrs=BDE;$(DCC_UnitAlias) + RDPCheck.exe + 00400000 + x86 + + + false + RELEASE;$(DCC_Define) + 0 + false + + + DEBUG;$(DCC_Define) + + + + MainSource + + +
Frm
+
+ + Base + + + Cfg_2 + Base + + + Cfg_1 + Base + +
+ + + Delphi.Personality.12 + + + + + False + True + False + + + True + False + 2 + 1 + 0 + 0 + False + False + False + False + False + 1033 + 1252 + + + Stas'M Corp. + Local RDP Checker + 2.1.0.0 + RDPCheck + Copyright © Stas'M Corp. 2014 + Stas'M Corp. + RDPCheck.exe + RDP Host Support + 1.3.0.0 + http://stascorp.com + + + Embarcadero C++Builder Office 2000 Servers Package + Embarcadero C++Builder Office XP Servers Package + Microsoft Office 2000 Sample Automation Server Wrapper Components + Microsoft Office XP Sample Automation Server Wrapper Components + + + RDPCheck.dpr + + + + 12 + +
diff --git a/src-rdpcheck/RDPCheck.dproj.local b/src-rdpcheck/RDPCheck.dproj.local new file mode 100644 index 0000000..51a53c6 --- /dev/null +++ b/src-rdpcheck/RDPCheck.dproj.local @@ -0,0 +1,8 @@ + + + + 2013.12.08 02:49:59.064.pas,C:\Users\user\Documents\RAD Studio\Projects\Unit2.pas=C:\Users\user\Documents\Delphi Projects (local)\RDPWrap\devel\rdpcheck-binarymaster\MainUnit.pas + 2013.12.08 02:49:59.064.dfm,C:\Users\user\Documents\RAD Studio\Projects\Unit2.dfm=C:\Users\user\Documents\Delphi Projects (local)\RDPWrap\devel\rdpcheck-binarymaster\MainUnit.dfm + 2013.12.08 02:50:08.464.dproj,C:\Users\user\Documents\RAD Studio\Projects\Project1.dproj=C:\Users\user\Documents\Delphi Projects (local)\RDPWrap\devel\rdpcheck-binarymaster\RDPCheck.dproj + + diff --git a/src-rdpcheck/RDPCheck.identcache b/src-rdpcheck/RDPCheck.identcache new file mode 100644 index 0000000..d2f5d39 Binary files /dev/null and b/src-rdpcheck/RDPCheck.identcache differ diff --git a/src-rdpcheck/RDPCheck.res b/src-rdpcheck/RDPCheck.res new file mode 100644 index 0000000..9ff016e Binary files /dev/null and b/src-rdpcheck/RDPCheck.res differ diff --git a/src-x86-binarymaster/rdpwrap.dll b/src-x86-binarymaster/rdpwrap.dll new file mode 100644 index 0000000..3c4cc8c Binary files /dev/null and b/src-x86-binarymaster/rdpwrap.dll differ diff --git a/src-x86-binarymaster/src/rdpwrap.dpr b/src-x86-binarymaster/src/rdpwrap.dpr new file mode 100644 index 0000000..07567c4 --- /dev/null +++ b/src-x86-binarymaster/src/rdpwrap.dpr @@ -0,0 +1,1502 @@ +library rdpwrap; + +// RDP Wrapper Library project by Stas'M + +// Terminal Services supported versions +// 6.0.X.X (Windows Vista, any) [policy hook only] +// 6.0.6000.16386 (Windows Vista) [policy hook + extended patch] +// 6.0.6001.18000 (Windows Vista SP1) [policy hook + extended patch] +// 6.0.6001.22565 (Windows Vista SP1 with KB977541) [todo] +// 6.0.6001.22635 (Windows Vista SP1 with KB970911) [todo] +// 6.0.6001.22801 (Windows Vista SP1 with KB2381675) [todo] +// 6.0.6002.18005 (Windows Vista SP2) [policy hook + extended patch] +// 6.0.6002.22269 (Windows Vista SP2 with KB977541) [todo] +// 6.0.6002.22340 (Windows Vista SP2 with KB970911) [todo] +// 6.0.6002.22515 (Windows Vista SP2 with KB2381675) [todo] +// 6.0.6002.22641 (Windows Vista SP2 with KB2523307) [todo] +// 6.1.X.X (Windows 7, any) [policy hook only] +// 6.1.7600.16385 (Windows 7) [policy hook + extended patch] +// 6.1.7600.20890 (Windows 7 with KB2479710) [todo] +// 6.1.7600.21316 (Windows 7 with KB2750090) [todo] +// 6.1.7601.17514 (Windows 7 SP1) [policy hook + extended patch] +// 6.1.7601.21650 (Windows 7 SP1 with KB2479710) [todo] +// 6.1.7601.21866 (Windows 7 SP1 with KB2647409) [todo] +// 6.1.7601.22104 (Windows 7 SP1 with KB2750090) [todo] +// 6.1.7601.18540 (Windows 7 SP1 with KB2984972 GDR) [policy hook + extended patch] +// 6.1.7601.22750 (Windows 7 SP1 with KB2984972 LDR) [policy hook + extended patch] +// 6.2.8102.0 (Windows 8 Developer Preview) [policy hook + extended patch] +// 6.2.8250.0 (Windows 8 Consumer Preview) [policy hook + extended patch] +// 6.2.8400.0 (Windows 8 Release Preview) [policy hook + extended patch] +// 6.2.9200.16384 (Windows 8) [policy hook + extended patch] +// 6.2.9200.17048 (Windows 8 with KB2973501 GDR) [policy hook + extended patch] +// 6.2.9200.21166 (Windows 8 with KB2973501 LDR) [policy hook + extended patch] +// 6.3.9431.0 (Windows 8.1 Preview) [init hook + extended patch] +// 6.3.9600.16384 (Windows 8.1) [init hook + extended patch] +// 6.3.9600.17095 (Windows 8.1 with KB2959626) [init hook + extended patch] +// 6.4.9841.0 (Windows 10 Technical Preview) [init hook + extended patch] + +// Known failures +// 6.0.6000.16386 (Windows Vista RTM x86, crashes on logon attempt) + +// Internal changelog: + +// 2014.10.19 : +// - added support for version 6.0.6000.16386 (x64) +// - added support for version 6.0.6001.18000 (x64) +// - added support for version 6.1.7600.16385 + +// 2014.10.18 : +// - corrected some typos in source +// - simplified signature constants +// - added support for version 6.0.6000.16386 (x86) +// - added support for version 6.0.6001.18000 (x86) +// - added support for version 6.0.6002.18005 +// - added support for version 6.1.7601.17514 +// - added support for version 6.1.7601.18540 +// - added support for version 6.1.7601.22750 +// - added support for version 6.2.9200.17048 +// - added support for version 6.2.9200.21166 + +// 2014.10.17 : +// - collecting information about all versions of Terminal Services beginning from Vista +// - added [todo] to the versions list + +// 2014.10.16 : +// - got new updates: KB2984972 for Win 7 (still works with 2 concurrent users) and KB2973501 for Win 8 (doesn't work) + +// 2014.10.02 : +// - researching Windows 10 TP Remote Desktop +// - done! even without debugging symbols ^^) + +// 2014.07.20 : +// - added support for Windows 8 Release Preview +// - added support for Windows 8 Consumer Preview +// - added support for Windows 8 Developer Preview + +// 2014.07.19 : +// - improved patching of Windows 8 +// - added policy patches +// - will patch CDefPolicy::Query +// - will patch CSessionArbitrationHelper::IsSingleSessionPerUserEnabled + +// 2014.07.18 : +// - researched patched files from MDL forum +// - CSLQuery::GetMaxSessions requires no patching +// - it's better to change the default policy, so... +// - will patch CDefPolicy::Query +// - will patch CEnforcementCore::GetInstanceOfTSLicense +// - will patch CSessionArbitrationHelper::IsSingleSessionPerUserEnabled +// - the function CSLQuery::Initialize is hooked correctly + +// 2014.07.17 : +// - will hook only CSLQuery::Initialize function +// - CSLQuery::GetMaxSessions will be patched +// - added x86 signatures for 6.3.9431.0 (Windows 8.1 Preview) + +// 2014.07.16 : +// - changing asm opcodes is bad, will hook CSL functions + +// 2014.07.15 : +// - added x86 signatures for 6.3.9600.16384 (Windows 8.1) +// 2014.07.15 : +// - added x86 signatures for 6.3.9600.17095 (Windows 8.1 with KB2959626) + +uses + SysUtils, + Windows, + TlHelp32; + +{$R rdpwrap.res} + +// Hook core definitions + +type + OldCode = packed record + One: DWORD; + two: Word; + end; + + far_jmp = packed record + PushOp: Byte; + PushArg: Pointer; + RetOp: Byte; + end; + + mov_far_jmp = packed record + MovOp: Byte; + MovArg: Byte; + PushOp: Byte; + PushArg: Pointer; + RetOp: Byte; + end; + + TTHREADENTRY32 = packed record + dwSize: DWORD; + cntUsage: DWORD; + th32ThreadID: DWORD; + th32OwnerProcessID: DWORD; + tpBasePri: LongInt; + tpDeltaPri: LongInt; + dwFlags: DWORD; + end; + IntArray = Array of Integer; + FILE_VERSION = record + Version: record case Boolean of + True: (dw: DWORD); + False: (w: record + Minor, Major: Word; + end;) + end; + Release, Build: Word; + bDebug, bPrerelease, bPrivate, bSpecial: Boolean; + end; + +const + THREAD_SUSPEND_RESUME = 2; + TH32CS_SNAPTHREAD = 4; +var + bw: DWORD; + IsHooked: Boolean = False; + FCount: Cardinal = 0; + +// Unhooked import + +function OpenThread(dwDesiredAccess: DWORD; bInheritHandle: BOOL; + dwThreadId: DWORD): DWORD; stdcall; external kernel32; + +function CreateToolhelp32Snapshot(dwFlags, th32ProcessID: DWORD): DWORD; + stdcall; external kernel32; + +function Thread32First(hSnapshot: THandle; var lpte: TTHREADENTRY32): bool; + stdcall; external kernel32; + +function Thread32Next(hSnapshot: THandle; var lpte: TTHREADENTRY32): bool; + stdcall; external kernel32; + +// Wrapped import + +var + TSMain: function(dwArgc: DWORD; lpszArgv: PWideChar): DWORD; stdcall; + TSGlobals: function(lpGlobalData: Pointer): DWORD; stdcall; + +// Hooked import and vars + +var + SLGetWindowsInformationDWORD: function(pwszValueName: PWideChar; + pdwValue: PDWORD): HRESULT; stdcall; + TermSrvBase: Pointer; + FV: FILE_VERSION; + +const + CDefPolicy_Query_edx_ecx: Array[0..12] of Byte = + ($BA,$00,$01,$00,$00,$89,$91,$20,$03,$00,$00,$5E,$90); + CDefPolicy_Query_eax_esi: Array[0..11] of Byte = + ($B8,$00,$01,$00,$00,$89,$86,$20,$03,$00,$00,$90); + CDefPolicy_Query_eax_ecx: Array[0..11] of Byte = + ($B8,$00,$01,$00,$00,$89,$81,$20,$03,$00,$00,$90); + +// ------------------- TermService build 6.0.6000.16386 + +// Original +// .text:6F335CD8 cmp edx, [ecx+320h] +// .text:6F335CDE pop esi +// .text:6F335CDF jz loc_6F3426F1 +//_______________ +// +// Changed +// .text:6F335CD8 mov edx, 100h +// .text:6F335CDD mov [ecx+320h], edx +// .text:6F335CE3 pop esi +// .text:6F335CE4 nop +// CDefPolicy_Query_edx_ecx + +// ------------------- TermService build 6.0.6001.18000 + +// Original +// .text:6E817FD8 cmp edx, [ecx+320h] +// .text:6E817FDE pop esi +// .text:6E817FDF jz loc_6E826F16 +//_______________ +// +// Changed +// .text:6E817FD8 mov edx, 100h +// .text:6E817FDD mov [ecx+320h], edx +// .text:6E817FE3 pop esi +// .text:6E817FE4 nop +// CDefPolicy_Query_edx_ecx + +// ------------------- TermService build 6.0.6002.18005 + +// Original +// .text:6F5979C0 cmp edx, [ecx+320h] +// .text:6F5979C6 pop esi +// .text:6F5979C7 jz loc_6F5A6F26 +//_______________ +// +// Changed +// .text:6F5979C0 mov edx, 100h +// .text:6F5979C5 mov [ecx+320h], edx +// .text:6F5979CB pop esi +// .text:6F5979CC nop +// CDefPolicy_Query_edx_ecx + +// ------------------- TermService build 6.1.7600.16385 + +// Original +// .text:6F2F96F3 cmp eax, [esi+320h] +// .text:6F2F96F9 jz loc_6F30E256 +//_______________ +// +// Changed +// .text:6F2F96F3 mov eax, 100h +// .text:6F2F96F8 mov [esi+320h], eax +// .text:6F2F96FE nop +// CDefPolicy_Query_eax_esi + +// ------------------- TermService build 6.1.7601.17514 + +// Original +// .text:6F2F9D53 cmp eax, [esi+320h] +// .text:6F2F9D59 jz loc_6F30B25E +//_______________ +// +// Changed +// .text:6F2F9D53 mov eax, 100h +// .text:6F2F9D58 mov [esi+320h], eax +// .text:6F2F9D5E nop +// CDefPolicy_Query_eax_esi + +// ------------------- TermService build 6.1.7601.18540 + +// Original +// .text:6F2F9D9F cmp eax, [esi+320h] +// .text:6F2F9DA5 jz loc_6F30B2AE +//_______________ +// +// Changed +// .text:6F2F9D9F mov eax, 100h +// .text:6F2F9DA4 mov [esi+320h], eax +// .text:6F2F9DAA nop +// CDefPolicy_Query_eax_esi + +// ------------------- TermService build 6.1.7601.22750 + +// Original +// .text:6F2F9E21 cmp eax, [esi+320h] +// .text:6F2F9E27 jz loc_6F30B6CE +//_______________ +// +// Changed +// .text:6F2F9E21 mov eax, 100h +// .text:6F2F9E26 mov [esi+320h], eax +// .text:6F2F9E2C nop +// CDefPolicy_Query_eax_esi + +// ------------------- TermService build 6.2.8102.0 + +// Original +// .text:1000E47C cmp eax, [esi+320h] +// .text:1000E482 jz loc_1002D775 +//_______________ +// +// Changed +// .text:1000E47C mov eax, 100h +// .text:1000E481 mov [esi+320h], eax +// .text:1000E487 nop +// CDefPolicy_Query_eax_esi + +// ------------------- TermService build 6.2.8250.0 + +// Original +// .text:10013520 cmp eax, [esi+320h] +// .text:10013526 jz loc_1002DB85 +//_______________ +// +// Changed +// .text:10013520 mov eax, 100h +// .text:10013525 mov [esi+320h], eax +// .text:1001352B nop +// CDefPolicy_Query_eax_esi + +// ------------------- TermService build 6.2.8400.0 + +// Original +// .text:10013E48 cmp eax, [esi+320h] +// .text:10013E4E jz loc_1002E079 +//_______________ +// +// Changed +// .text:10013E48 mov eax, 100h +// .text:10013E4D mov [esi+320h], eax +// .text:10013E53 nop +// CDefPolicy_Query_eax_esi + +// ------------------- TermService build 6.2.9200.16384 + +// Original +// .text:10013F08 cmp eax, [esi+320h] +// .text:10013F0E jz loc_1002E161 +//_______________ +// +// Changed +// .text:10013F08 mov eax, 100h +// .text:10013F0D mov [esi+320h], eax +// .text:10013F13 nop +// CDefPolicy_Query_eax_esi + +// ------------------- TermService build 6.2.9200.17048 + +// Original +// .text:1001F408 cmp eax, [esi+320h] +// .text:1001F40E jz loc_1002E201 +//_______________ +// +// Changed +// .text:1001F408 mov eax, 100h +// .text:1001F40D mov [esi+320h], eax +// .text:1001F413 nop +// CDefPolicy_Query_eax_esi + +// ------------------- TermService build 6.2.9200.21166 + +// Original +// .text:10013F30 cmp eax, [esi+320h] +// .text:10013F36 jz loc_1002E189 +//_______________ +// +// Changed +// .text:10013F30 mov eax, 100h +// .text:10013F35 mov [esi+320h], eax +// .text:10013F3B nop +// CDefPolicy_Query_eax_esi + +// ------------------- TermService build 6.3.9431.0 + +// Original +// .text:1002EA25 cmp eax, [ecx+320h] +// .text:1002EA2B jz loc_100348C1 +//_______________ +// +// Changed +// .text:1002EA25 mov eax, 100h +// .text:1002EA2A mov [ecx+320h], eax +// .text:1002EA30 nop +// CDefPolicy_Query_eax_ecx + +// ------------------- TermService build 6.3.9600.16384 + +// Original +// .text:10016115 cmp eax, [ecx+320h] +// .text:1001611B jz loc_10034DE1 +//_______________ +// +// Changed +// .text:10016115 mov eax, 100h +// .text:1001611A mov [ecx+320h], eax +// .text:10016120 nop +// CDefPolicy_Query_eax_ecx + +// ------------------- TermService build 6.3.9600.17095 + +// Original +// .text:10037529 cmp eax, [ecx+320h] +// .text:1003752F jz loc_10043662 +//_______________ +// +// Changed +// .text:10037529 mov eax, 100h +// .text:1003752E mov [ecx+320h], eax +// .text:10037534 nop +// CDefPolicy_Query_eax_ecx + +// ------------------- TermService build 6.4.9841.0 + +// Original +// .text:1003B989 cmp eax, [ecx+320h] +// .text:1003B98F jz loc_1005E809 +//_______________ +// +// Changed +// .text:1003B989 mov eax, 100h +// .text:1003B98E mov [ecx+320h], eax +// .text:1003B994 nop +// CDefPolicy_Query_eax_ecx + +var + Stub_SLGetWindowsInformationDWORD: far_jmp; + Old_SLGetWindowsInformationDWORD: OldCode; + +// Main code + +procedure WriteLog(S: AnsiString); +const + LogFile = '\rdpwrap.txt'; +var + F: TextFile; +begin + if not FileExists(LogFile) then + Exit; + AssignFile(F, LogFile); + Append(F); + Write(F, S+#13#10); + CloseFile(F); +end; + +procedure StopThreads; +var + h, CurrTh, ThrHandle, CurrPr: DWORD; + Thread: TTHREADENTRY32; +begin + CurrTh := GetCurrentThreadId; + CurrPr := GetCurrentProcessId; + h := CreateToolhelp32Snapshot(TH32CS_SNAPTHREAD, 0); + if h <> INVALID_HANDLE_VALUE then + begin + Thread.dwSize := SizeOf(TTHREADENTRY32); + if Thread32First(h, Thread) then + repeat + if (Thread.th32ThreadID <> CurrTh) and + (Thread.th32OwnerProcessID = CurrPr) then + begin + ThrHandle := OpenThread(THREAD_SUSPEND_RESUME, false, + Thread.th32ThreadID); + if ThrHandle > 0 then + begin + SuspendThread(ThrHandle); + CloseHandle(ThrHandle); + end; + end; + until not Thread32Next(h, Thread); + CloseHandle(h); + end; +end; + +procedure RunThreads; +var + h, CurrTh, ThrHandle, CurrPr: DWORD; + Thread: TTHREADENTRY32; +begin + CurrTh := GetCurrentThreadId; + CurrPr := GetCurrentProcessId; + h := CreateToolhelp32Snapshot(TH32CS_SNAPTHREAD, 0); + if h <> INVALID_HANDLE_VALUE then + begin + Thread.dwSize := SizeOf(TTHREADENTRY32); + if Thread32First(h, Thread) then + repeat + if (Thread.th32ThreadID <> CurrTh) and + (Thread.th32OwnerProcessID = CurrPr) then + begin + ThrHandle := OpenThread(THREAD_SUSPEND_RESUME, false, + Thread.th32ThreadID); + if ThrHandle > 0 then + begin + ResumeThread(ThrHandle); + CloseHandle(ThrHandle); + end; + end; + until not Thread32Next(h, Thread); + CloseHandle(h); + end; +end; + +function GetModuleAddress(ModuleName: String; ProcessId: DWORD; var BaseAddr: Pointer; var BaseSize: DWORD): Boolean; +var + hSnap: THandle; + md: MODULEENTRY32; +begin + Result := False; + hSnap := CreateToolhelp32Snapshot(TH32CS_SNAPMODULE, ProcessId); + if hSnap = INVALID_HANDLE_VALUE Then + Exit; + md.dwSize := SizeOf(MODULEENTRY32); + if Module32First(hSnap, md) then + begin + if LowerCase(ExtractFileName(md.szExePath)) = LowerCase(ModuleName) then + begin + Result := True; + BaseAddr := Pointer(md.modBaseAddr); + BaseSize := md.modBaseSize; + CloseHandle(hSnap); + Exit; + end; + while Module32Next(hSnap, md) Do + begin + if LowerCase(ExtractFileName(md.szExePath)) = LowerCase(ModuleName) then + begin + Result := True; + BaseAddr := Pointer(md.modBaseAddr); + BaseSize := md.modBaseSize; + Break; + end; + end; + end; + CloseHandle(hSnap); +end; + +{procedure FindMem(Mem: Pointer; MemSz: DWORD; Buf: Pointer; BufSz: DWORD; + From: DWORD; var A: IntArray); +var + I: Integer; +begin + SetLength(A, 0); + I:=From; + if From>0 then + Inc(PByte(Mem), From); + while I < MemSz - BufSz + 1 do + begin + if (not IsBadReadPtr(Mem, BufSz)) and (CompareMem(Mem, Buf, BufSz)) then + begin + SetLength(A, Length(A)+1); + A[Length(A)-1] := I; + end; + Inc(I); + Inc(PByte(Mem)); + end; +end;} + +function GetModuleVersion(const ModuleName: TFileName; var FileVersion: FILE_VERSION): Boolean; +type + VS_VERSIONINFO = record + wLength, wValueLength, wType: Word; + szKey: Array[1..16] of WideChar; + Padding1: Word; + Value: VS_FIXEDFILEINFO; + Padding2, Children: Word; + end; + PVS_VERSIONINFO = ^VS_VERSIONINFO; +const + VFF_DEBUG = 1; + VFF_PRERELEASE = 2; + VFF_PRIVATE = 8; + VFF_SPECIAL = 32; +var + hMod: HMODULE; + hResourceInfo: HRSRC; + VersionInfo: PVS_VERSIONINFO; +begin + Result := False; + + if ModuleName = '' then + hMod := GetModuleHandle(nil) + else + hMod := GetModuleHandle(PWideChar(ModuleName)); + if hMod = 0 then + Exit; + + hResourceInfo := FindResource(hMod, PWideChar(1), PWideChar($10)); + if hResourceInfo = 0 then + Exit; + + VersionInfo := Pointer(LoadResource(hMod, hResourceInfo)); + if VersionInfo = nil then + Exit; + + FileVersion.Version.dw := VersionInfo.Value.dwFileVersionMS; + FileVersion.Release := Word(VersionInfo.Value.dwFileVersionLS shr 16); + FileVersion.Build := Word(VersionInfo.Value.dwFileVersionLS); + FileVersion.bDebug := (VersionInfo.Value.dwFileFlags and VFF_DEBUG) = VFF_DEBUG; + FileVersion.bPrerelease := (VersionInfo.Value.dwFileFlags and VFF_PRERELEASE) = VFF_PRERELEASE; + FileVersion.bPrivate := (VersionInfo.Value.dwFileFlags and VFF_PRIVATE) = VFF_PRIVATE; + FileVersion.bSpecial := (VersionInfo.Value.dwFileFlags and VFF_SPECIAL) = VFF_SPECIAL; + + Result := True; +end; + +function GetFileVersion(const FileName: TFileName; var FileVersion: FILE_VERSION): Boolean; +type + VS_VERSIONINFO = record + wLength, wValueLength, wType: Word; + szKey: Array[1..16] of WideChar; + Padding1: Word; + Value: VS_FIXEDFILEINFO; + Padding2, Children: Word; + end; + PVS_VERSIONINFO = ^VS_VERSIONINFO; +const + VFF_DEBUG = 1; + VFF_PRERELEASE = 2; + VFF_PRIVATE = 8; + VFF_SPECIAL = 32; +var + hFile: HMODULE; + hResourceInfo: HRSRC; + VersionInfo: PVS_VERSIONINFO; +begin + Result := False; + + hFile := LoadLibraryEx(PWideChar(FileName), 0, LOAD_LIBRARY_AS_DATAFILE); + if hFile = 0 then + Exit; + + hResourceInfo := FindResource(hFile, PWideChar(1), PWideChar($10)); + if hResourceInfo = 0 then + Exit; + + VersionInfo := Pointer(LoadResource(hFile, hResourceInfo)); + if VersionInfo = nil then + Exit; + + FileVersion.Version.dw := VersionInfo.Value.dwFileVersionMS; + FileVersion.Release := Word(VersionInfo.Value.dwFileVersionLS shr 16); + FileVersion.Build := Word(VersionInfo.Value.dwFileVersionLS); + FileVersion.bDebug := (VersionInfo.Value.dwFileFlags and VFF_DEBUG) = VFF_DEBUG; + FileVersion.bPrerelease := (VersionInfo.Value.dwFileFlags and VFF_PRERELEASE) = VFF_PRERELEASE; + FileVersion.bPrivate := (VersionInfo.Value.dwFileFlags and VFF_PRIVATE) = VFF_PRIVATE; + FileVersion.bSpecial := (VersionInfo.Value.dwFileFlags and VFF_SPECIAL) = VFF_SPECIAL; + + Result := True; +end; + +function OverrideSL(ValueName: String; var Value: DWORD): Boolean; +begin + Result := True; + // Allow Remote Connections + if ValueName = 'TerminalServices-RemoteConnectionManager-AllowRemoteConnections' then begin + Value := 1; + Exit; + end; + // Allow Multiple Sessions + if ValueName = 'TerminalServices-RemoteConnectionManager-AllowMultipleSessions' then begin + Value := 1; + Exit; + end; + // Allow Multiple Sessions (Application Server Mode) + if ValueName = 'TerminalServices-RemoteConnectionManager-AllowAppServerMode' then begin + Value := 1; + Exit; + end; + // Allow Multiple Monitors + if ValueName = 'TerminalServices-RemoteConnectionManager-AllowMultimon' then begin + Value := 1; + Exit; + end; + // Max User Sessions (0 = unlimited) + if ValueName = 'TerminalServices-RemoteConnectionManager-MaxUserSessions' then begin + Value := 0; + Exit; + end; + // Max Debug Sessions (Win 8, 0 = unlimited) + if ValueName = 'TerminalServices-RemoteConnectionManager-ce0ad219-4670-4988-98fb-89b14c2f072b-MaxSessions' then begin + Value := 0; + Exit; + end; + // Max Sessions + // 0 - logon not possible even from console + // 1 - only one active user (console or remote) + // 2 - allow concurrent sessions + if ValueName = 'TerminalServices-RemoteConnectionManager-45344fe7-00e6-4ac6-9f01-d01fd4ffadfb-MaxSessions' then begin + Value := 2; + Exit; + end; + // Allow Advanced Compression with RDP 7 Protocol + if ValueName = 'TerminalServices-RDP-7-Advanced-Compression-Allowed' then begin + Value := 1; + Exit; + end; + // IsTerminalTypeLocalOnly = 0 + if ValueName = 'TerminalServices-RemoteConnectionManager-45344fe7-00e6-4ac6-9f01-d01fd4ffadfb-LocalOnly' then begin + Value := 0; + Exit; + end; + // Max Sessions (hard limit) + if ValueName = 'TerminalServices-RemoteConnectionManager-8dc86f1d-9969-4379-91c1-06fe1dc60575-MaxSessions' then begin + Value := 1000; + Exit; + end; + // Allow Easy Print + if ValueName = 'TerminalServices-DeviceRedirection-Licenses-TSEasyPrintAllowed' then begin + Value := 1; + Exit; + end; + Result := False; +end; + +function New_SLGetWindowsInformationDWORD(pwszValueName: PWideChar; + pdwValue: PDWORD): HRESULT; stdcall; +var + dw: DWORD; +begin + // wrapped SLGetWindowsInformationDWORD function + // termsrv.dll will call this function instead of original SLC.dll + + // Override SL Policy + + WriteLog('Policy query: ' + pwszValueName); + if OverrideSL(pwszValueName, dw) then begin + pdwValue^ := dw; + Result := S_OK; + WriteLog('Rewrite: ' + IntToStr(pdwValue^)); + Exit; + end; + + // If the requested value name is not defined above + + // revert to original SL Policy function + WriteProcessMemory(GetCurrentProcess, @SLGetWindowsInformationDWORD, + @Old_SLGetWindowsInformationDWORD, SizeOf(OldCode), bw); + + // get result + Result := SLGetWindowsInformationDWORD(pwszValueName, pdwValue); + if Result = S_OK then + WriteLog('Result: ' + IntToStr(pdwValue^)) + else + WriteLog('Failed'); + // wrap it back + WriteProcessMemory(GetCurrentProcess, @SLGetWindowsInformationDWORD, + @Stub_SLGetWindowsInformationDWORD, SizeOf(far_jmp), bw); +end; + +function New_Win8SL(pwszValueName: PWideChar; pdwValue: PDWORD): HRESULT; register; +var + dw: DWORD; +begin + // wrapped unexported function SLGetWindowsInformationDWORDWrapper in termsrv.dll + // for Windows 8 support + + // Override SL Policy + + WriteLog('Policy query: ' + pwszValueName); + if OverrideSL(pwszValueName, dw) then begin + pdwValue^ := dw; + Result := S_OK; + WriteLog('Rewrite: ' + IntToStr(pdwValue^)); + Exit; + end; + + // If the requested value name is not defined above + // use function from SLC.dll + + Result := SLGetWindowsInformationDWORD(pwszValueName, pdwValue); + if Result = S_OK then + WriteLog('Result: ' + IntToStr(pdwValue^)) + else + WriteLog('Failed'); +end; + +function New_Win8SL_CP(eax: DWORD; pdwValue: PDWORD; ecx: DWORD; pwszValueName: PWideChar): HRESULT; register; +begin + // wrapped unexported function SLGetWindowsInformationDWORDWrapper in termsrv.dll + // for Windows 8 Consumer Preview support + + Result := New_Win8SL(pwszValueName, pdwValue); +end; + +function New_CSLQuery_Initialize: HRESULT; stdcall; +var + bServerSku, + bRemoteConnAllowed, + bFUSEnabled, + bAppServerAllowed, + bMultimonAllowed, + lMaxUserSessions, + ulMaxDebugSessions, + bInitialized: PDWORD; +begin + bServerSku := nil; + bRemoteConnAllowed := nil; + bFUSEnabled := nil; + bAppServerAllowed := nil; + bMultimonAllowed := nil; + lMaxUserSessions := nil; + ulMaxDebugSessions := nil; + bInitialized := nil; + WriteLog('> CSLQuery::Initialize'); + if (FV.Release = 9431) and (FV.Build = 0) then begin + bFUSEnabled := Pointer(Cardinal(TermSrvBase) + $A22A8); + lMaxUserSessions := Pointer(Cardinal(TermSrvBase) + $A22AC); + bAppServerAllowed := Pointer(Cardinal(TermSrvBase) + $A22B0); + bInitialized := Pointer(Cardinal(TermSrvBase) + $A22B4); + bMultimonAllowed := Pointer(Cardinal(TermSrvBase) + $A22B8); + bServerSku := Pointer(Cardinal(TermSrvBase) + $A22BC); + ulMaxDebugSessions := Pointer(Cardinal(TermSrvBase) + $A22C0); + bRemoteConnAllowed := Pointer(Cardinal(TermSrvBase) + $A22C4); + end; + if (FV.Release = 9600) and (FV.Build = 16384) then begin + bFUSEnabled := Pointer(Cardinal(TermSrvBase) + $C02A8); + lMaxUserSessions := Pointer(Cardinal(TermSrvBase) + $C02AC); + bAppServerAllowed := Pointer(Cardinal(TermSrvBase) + $C02B0); + bInitialized := Pointer(Cardinal(TermSrvBase) + $C02B4); + bMultimonAllowed := Pointer(Cardinal(TermSrvBase) + $C02B8); + bServerSku := Pointer(Cardinal(TermSrvBase) + $C02BC); + ulMaxDebugSessions := Pointer(Cardinal(TermSrvBase) + $C02C0); + bRemoteConnAllowed := Pointer(Cardinal(TermSrvBase) + $C02C4); + end; + if (FV.Release = 9600) and (FV.Build = 17095) then begin + bFUSEnabled := Pointer(Cardinal(TermSrvBase) + $C12A8); + lMaxUserSessions := Pointer(Cardinal(TermSrvBase) + $C12AC); + bAppServerAllowed := Pointer(Cardinal(TermSrvBase) + $C12B0); + bInitialized := Pointer(Cardinal(TermSrvBase) + $C12B4); + bMultimonAllowed := Pointer(Cardinal(TermSrvBase) + $C12B8); + bServerSku := Pointer(Cardinal(TermSrvBase) + $C12BC); + ulMaxDebugSessions := Pointer(Cardinal(TermSrvBase) + $C12C0); + bRemoteConnAllowed := Pointer(Cardinal(TermSrvBase) + $C12C4); + end; + if (FV.Release = 9841) and (FV.Build = 0) then begin + bFUSEnabled := Pointer(Cardinal(TermSrvBase) + $BF9F0); + lMaxUserSessions := Pointer(Cardinal(TermSrvBase) + $BF9F4); + bAppServerAllowed := Pointer(Cardinal(TermSrvBase) + $BF9F8); + bInitialized := Pointer(Cardinal(TermSrvBase) + $BF9FC); + bMultimonAllowed := Pointer(Cardinal(TermSrvBase) + $BFA00); + bServerSku := Pointer(Cardinal(TermSrvBase) + $BFA04); + ulMaxDebugSessions := Pointer(Cardinal(TermSrvBase) + $BFA08); + bRemoteConnAllowed := Pointer(Cardinal(TermSrvBase) + $BFA0C); + end; + if bServerSku <> nil then begin + WriteLog('[0x'+IntToHex(DWORD(bServerSku), 1)+'] bServerSku = 1'); + bServerSku^ := 1; + end; + if bRemoteConnAllowed <> nil then begin + WriteLog('[0x'+IntToHex(DWORD(bRemoteConnAllowed), 1)+'] bRemoteConnAllowed = 1'); + bRemoteConnAllowed^ := 1; + end; + if bFUSEnabled <> nil then begin + WriteLog('[0x'+IntToHex(DWORD(bFUSEnabled), 1)+'] bFUSEnabled = 1'); + bFUSEnabled^ := 1; + end; + if bAppServerAllowed <> nil then begin + WriteLog('[0x'+IntToHex(DWORD(bAppServerAllowed), 1)+'] bAppServerAllowed = 1'); + bAppServerAllowed^ := 1; + end; + if bMultimonAllowed <> nil then begin + WriteLog('[0x'+IntToHex(DWORD(bMultimonAllowed), 1)+'] bMultimonAllowed = 1'); + bMultimonAllowed^ := 1; + end; + if lMaxUserSessions <> nil then begin + WriteLog('[0x'+IntToHex(DWORD(lMaxUserSessions), 1)+'] lMaxUserSessions = 0'); + lMaxUserSessions^ := 0; + end; + if ulMaxDebugSessions <> nil then begin + WriteLog('[0x'+IntToHex(DWORD(ulMaxDebugSessions), 1)+'] ulMaxDebugSessions = 0'); + ulMaxDebugSessions^ := 0; + end; + if bInitialized <> nil then begin + WriteLog('[0x'+IntToHex(DWORD(bInitialized), 1)+'] bInitialized = 1'); + bInitialized^ := 1; + end; + Result := S_OK; +end; + +procedure HookFunctions; +var + V: DWORD; + TS_Handle, SLC_Handle: THandle; + TermSrvSize: DWORD; + SignPtr: Pointer; + Results: IntArray; + Jump: far_jmp; + MovJump: mov_far_jmp; + nop: DWORD; + b: Byte; +begin + { hook function ^^ + (called once) } + IsHooked := True; + nop := $90909090; + TSMain := nil; + TSGlobals := nil; + SLGetWindowsInformationDWORD := nil; + WriteLog('init'); + + // load termsrv.dll and get functions + TS_Handle := LoadLibrary('termsrv.dll'); + if TS_Handle = 0 then begin + WriteLog('Error: Failed to load Terminal Services library'); + Exit; + end; + WriteLog('Base addr: 0x'+IntToHex(TS_Handle, 8)); + TSMain := GetProcAddress(TS_Handle, 'ServiceMain'); + WriteLog('SvcMain: termsrv.dll+0x'+IntToHex(Cardinal(@TSMain) - TS_Handle, 1)); + TSGlobals := GetProcAddress(TS_Handle, 'SvchostPushServiceGlobals'); + WriteLog('SvcGlobals: termsrv.dll+0x'+IntToHex(Cardinal(@TSGlobals) - TS_Handle, 1)); + + V := 0; + // check termsrv version + if GetModuleVersion('termsrv.dll', FV) then + V := Byte(FV.Version.w.Minor) or (Byte(FV.Version.w.Major) shl 8) + else begin + // check NT version + // V := GetVersion; // deprecated + // V := ((V and $FF) shl 8) or ((V and $FF00) shr 8); + end; + if V = 0 then begin + WriteLog('Error: Failed to detect Terminal Services version'); + Exit; + end; + + WriteLog('Version: '+IntToStr(FV.Version.w.Major)+'.'+IntToStr(FV.Version.w.Minor)); + WriteLog('Release: '+IntToStr(FV.Release)); + WriteLog('Build: '+IntToStr(FV.Build)); + + // temporarily freeze threads + WriteLog('freeze'); + StopThreads(); + + if (V = $0600) then begin + // Windows Vista + // uses SL Policy API (slc.dll) + + // load slc.dll and hook function + SLC_Handle := LoadLibrary('slc.dll'); + SLGetWindowsInformationDWORD := GetProcAddress(SLC_Handle, 'SLGetWindowsInformationDWORD'); + + if @SLGetWindowsInformationDWORD <> nil then + begin + // rewrite original function to call our function (make hook) + + WriteLog('Hook SLGetWindowsInformationDWORD'); + Stub_SLGetWindowsInformationDWORD.PushOp := $68; + Stub_SLGetWindowsInformationDWORD.PushArg := @New_SLGetWindowsInformationDWORD; + Stub_SLGetWindowsInformationDWORD.RetOp := $C3; + ReadProcessMemory(GetCurrentProcess, @SLGetWindowsInformationDWORD, + @Old_SLGetWindowsInformationDWORD, SizeOf(OldCode), bw); + WriteProcessMemory(GetCurrentProcess, @SLGetWindowsInformationDWORD, + @Stub_SLGetWindowsInformationDWORD, SizeOf(far_jmp), bw); + end; + + if GetModuleAddress('termsrv.dll', GetCurrentProcessId, TermSrvBase, TermSrvSize) then begin + // Patch functions: + // CSessionArbitrationHelper::IsSingleSessionPerUserEnabled + // CDefPolicy::Query + + if (FV.Release = 6000) and (FV.Build = 16386) then begin + WriteLog('Patch CSessionArbitrationHelper::IsSingleSessionPerUserEnabled'); + // Imagebase: 6F320000 + // .text:6F3360B9 lea eax, [ebp+VersionInformation] + // .text:6F3360BF inc ebx <- nop + // .text:6F3360C0 push eax ; lpVersionInformation + // .text:6F3360C1 mov [ebp+VersionInformation.dwOSVersionInfoSize], 11Ch + // .text:6F3360CB mov [esi], ebx + // .text:6F3360CD call ds:__imp__GetVersionExW@4 ; GetVersionExW(x) + SignPtr := Pointer(Cardinal(TermSrvBase) + $160BF); + WriteProcessMemory(GetCurrentProcess, SignPtr, @nop, 1, bw); + + WriteLog('Patch CDefPolicy::Query'); + SignPtr := Pointer(Cardinal(TermSrvBase) + $15CD8); + WriteProcessMemory(GetCurrentProcess, SignPtr, + @CDefPolicy_Query_edx_ecx[0], + SizeOf(CDefPolicy_Query_edx_ecx), bw); + end; + if (FV.Release = 6001) and (FV.Build = 18000) then begin + WriteLog('Patch CSessionArbitrationHelper::IsSingleSessionPerUserEnabled'); + // Imagebase: 6E800000 + // .text:6E8185DE lea eax, [ebp+VersionInformation] + // .text:6E8185E4 inc ebx <- nop + // .text:6E8185E5 push eax ; lpVersionInformation + // .text:6E8185E6 mov [ebp+VersionInformation.dwOSVersionInfoSize], 11Ch + // .text:6E8185F0 mov [esi], ebx + // .text:6E8185F2 call ds:__imp__GetVersionExW@4 ; GetVersionExW(x) + SignPtr := Pointer(Cardinal(TermSrvBase) + $185E4); + WriteProcessMemory(GetCurrentProcess, SignPtr, @nop, 1, bw); + + WriteLog('Patch CDefPolicy::Query'); + SignPtr := Pointer(Cardinal(TermSrvBase) + $17FD8); + WriteProcessMemory(GetCurrentProcess, SignPtr, + @CDefPolicy_Query_edx_ecx[0], + SizeOf(CDefPolicy_Query_edx_ecx), bw); + end; + if (FV.Release = 6002) and (FV.Build = 18005) then begin + WriteLog('Patch CSessionArbitrationHelper::IsSingleSessionPerUserEnabled'); + // Imagebase: 6F580000 + // .text:6F597FA2 lea eax, [ebp+VersionInformation] + // .text:6F597FA8 inc ebx <- nop + // .text:6F597FA9 push eax ; lpVersionInformation + // .text:6F597FAA mov [ebp+VersionInformation.dwOSVersionInfoSize], 11Ch + // .text:6F597FB4 mov [esi], ebx + // .text:6F597FB6 call ds:__imp__GetVersionExW@4 ; GetVersionExW(x) + SignPtr := Pointer(Cardinal(TermSrvBase) + $17FA8); + WriteProcessMemory(GetCurrentProcess, SignPtr, @nop, 1, bw); + + WriteLog('Patch CDefPolicy::Query'); + SignPtr := Pointer(Cardinal(TermSrvBase) + $179C0); + WriteProcessMemory(GetCurrentProcess, SignPtr, + @CDefPolicy_Query_edx_ecx[0], + SizeOf(CDefPolicy_Query_edx_ecx), bw); + end; + end; + end; + if (V = $0601) then begin + // Windows 7 + // uses SL Policy API (slc.dll) + + // load slc.dll and hook function + SLC_Handle := LoadLibrary('slc.dll'); + SLGetWindowsInformationDWORD := GetProcAddress(SLC_Handle, 'SLGetWindowsInformationDWORD'); + + if @SLGetWindowsInformationDWORD <> nil then + begin + // rewrite original function to call our function (make hook) + + WriteLog('Hook SLGetWindowsInformationDWORD'); + Stub_SLGetWindowsInformationDWORD.PushOp := $68; + Stub_SLGetWindowsInformationDWORD.PushArg := @New_SLGetWindowsInformationDWORD; + Stub_SLGetWindowsInformationDWORD.RetOp := $C3; + ReadProcessMemory(GetCurrentProcess, @SLGetWindowsInformationDWORD, + @Old_SLGetWindowsInformationDWORD, SizeOf(OldCode), bw); + WriteProcessMemory(GetCurrentProcess, @SLGetWindowsInformationDWORD, + @Stub_SLGetWindowsInformationDWORD, SizeOf(far_jmp), bw); + end; + + if GetModuleAddress('termsrv.dll', GetCurrentProcessId, TermSrvBase, TermSrvSize) then begin + // Patch functions: + // CSessionArbitrationHelper::IsSingleSessionPerUserEnabled + // CDefPolicy::Query + + if (FV.Release = 7600) and (FV.Build = 16385) then begin + WriteLog('Patch CSessionArbitrationHelper::IsSingleSessionPerUserEnabled'); + // Imagebase: 6F2E0000 + // .text:6F2F9E1F lea eax, [ebp+VersionInformation] + // .text:6F2F9E25 inc ebx <- nop + // .text:6F2F9E26 push eax ; lpVersionInformation + // .text:6F2F9E27 mov [ebp+VersionInformation.dwOSVersionInfoSize], 11Ch + // .text:6F2F9E31 mov [esi], ebx + // .text:6F2F9E33 call ds:__imp__GetVersionExW@4 ; GetVersionExW(x) + SignPtr := Pointer(Cardinal(TermSrvBase) + $19E25); + WriteProcessMemory(GetCurrentProcess, SignPtr, @nop, 1, bw); + + WriteLog('Patch CDefPolicy::Query'); + SignPtr := Pointer(Cardinal(TermSrvBase) + $196F3); + WriteProcessMemory(GetCurrentProcess, SignPtr, + @CDefPolicy_Query_eax_esi[0], + SizeOf(CDefPolicy_Query_eax_esi), bw); + end; + if (FV.Release = 7601) and (FV.Build = 17514) then begin + WriteLog('Patch CSessionArbitrationHelper::IsSingleSessionPerUserEnabled'); + // Imagebase: 6F2E0000 + // .text:6F2FA497 lea eax, [ebp+VersionInformation] + // .text:6F2FA49D inc ebx <- nop + // .text:6F2FA49E push eax ; lpVersionInformation + // .text:6F2FA49F mov [ebp+VersionInformation.dwOSVersionInfoSize], 11Ch + // .text:6F2FA4A9 mov [esi], ebx + // .text:6F2FA4AB call ds:__imp__GetVersionExW@4 ; GetVersionExW(x) + SignPtr := Pointer(Cardinal(TermSrvBase) + $1A49D); + WriteProcessMemory(GetCurrentProcess, SignPtr, @nop, 1, bw); + + WriteLog('Patch CDefPolicy::Query'); + SignPtr := Pointer(Cardinal(TermSrvBase) + $19D53); + WriteProcessMemory(GetCurrentProcess, SignPtr, + @CDefPolicy_Query_eax_esi[0], + SizeOf(CDefPolicy_Query_eax_esi), bw); + end; + if (FV.Release = 7601) and (FV.Build = 18540) then begin + WriteLog('Patch CSessionArbitrationHelper::IsSingleSessionPerUserEnabled'); + // Imagebase: 6F2E0000 + // .text:6F2FA4DF lea eax, [ebp+VersionInformation] + // .text:6F2FA4E5 inc ebx <- nop + // .text:6F2FA4E6 push eax ; lpVersionInformation + // .text:6F2FA4E7 mov [ebp+VersionInformation.dwOSVersionInfoSize], 11Ch + // .text:6F2FA4F1 mov [esi], ebx + // .text:6F2FA4F3 call ds:__imp__GetVersionExW@4 ; GetVersionExW(x) + SignPtr := Pointer(Cardinal(TermSrvBase) + $1A4E5); + WriteProcessMemory(GetCurrentProcess, SignPtr, @nop, 1, bw); + + WriteLog('Patch CDefPolicy::Query'); + SignPtr := Pointer(Cardinal(TermSrvBase) + $19D9F); + WriteProcessMemory(GetCurrentProcess, SignPtr, + @CDefPolicy_Query_eax_esi[0], + SizeOf(CDefPolicy_Query_eax_esi), bw); + end; + if (FV.Release = 7601) and (FV.Build = 22750) then begin + WriteLog('Patch CSessionArbitrationHelper::IsSingleSessionPerUserEnabled'); + // Imagebase: 6F2E0000 + // .text:6F2FA64F lea eax, [ebp+VersionInformation] + // .text:6F2FA655 inc ebx <- nop + // .text:6F2FA656 push eax ; lpVersionInformation + // .text:6F2FA657 mov [ebp+VersionInformation.dwOSVersionInfoSize], 11Ch + // .text:6F2FA661 mov [esi], ebx + // .text:6F2FA663 call ds:__imp__GetVersionExW@4 ; GetVersionExW(x) + SignPtr := Pointer(Cardinal(TermSrvBase) + $1A655); + WriteProcessMemory(GetCurrentProcess, SignPtr, @nop, 1, bw); + + WriteLog('Patch CDefPolicy::Query'); + SignPtr := Pointer(Cardinal(TermSrvBase) + $19E21); + WriteProcessMemory(GetCurrentProcess, SignPtr, + @CDefPolicy_Query_eax_esi[0], + SizeOf(CDefPolicy_Query_eax_esi), bw); + end; + end; + end; + if V = $0602 then begin + // Windows 8 + // uses SL Policy internal unexported function + + // load slc.dll and get function + // (will be used on intercepting undefined values) + SLC_Handle := LoadLibrary('slc.dll'); + SLGetWindowsInformationDWORD := GetProcAddress(SLC_Handle, 'SLGetWindowsInformationDWORD'); + + if GetModuleAddress('termsrv.dll', GetCurrentProcessId, TermSrvBase, TermSrvSize) then begin + // Patch functions: + // CSessionArbitrationHelper::IsSingleSessionPerUserEnabled + // CDefPolicy::Query + // Hook function: + // SLGetWindowsInformationDWORDWrapper + + if (FV.Release = 8102) and (FV.Build = 0) then begin + WriteLog('Patch CSessionArbitrationHelper::IsSingleSessionPerUserEnabled'); + // .text:1000F7E5 lea eax, [esp+150h+VersionInformation] + // .text:1000F7E9 inc esi <- nop + // .text:1000F7EA push eax ; lpVersionInformation + // .text:1000F7EB mov [esp+154h+VersionInformation.dwOSVersionInfoSize], 11Ch + // .text:1000F7F3 mov [edi], esi + // .text:1000F7F5 call ds:__imp__GetVersionExW@4 ; GetVersionExW(x) + SignPtr := Pointer(Cardinal(TermSrvBase) + $F7E9); + WriteProcessMemory(GetCurrentProcess, SignPtr, @nop, 1, bw); + + WriteLog('Patch CDefPolicy::Query'); + SignPtr := Pointer(Cardinal(TermSrvBase) + $E47C); + WriteProcessMemory(GetCurrentProcess, SignPtr, + @CDefPolicy_Query_eax_esi[0], + SizeOf(CDefPolicy_Query_eax_esi), bw); + + WriteLog('Hook SLGetWindowsInformationDWORDWrapper'); + SignPtr := Pointer(Cardinal(TermSrvBase) + $1B909); + MovJump.MovOp := $89; // mov eax, ecx + MovJump.MovArg := $C8; // __msfastcall compatibility + MovJump.PushOp := $68; + MovJump.PushArg := @New_Win8SL; + MovJump.RetOp := $C3; + WriteProcessMemory(GetCurrentProcess, SignPtr, + @MovJump, SizeOf(mov_far_jmp), bw); + end; + if (FV.Release = 8250) and (FV.Build = 0) then begin + WriteLog('Patch CSessionArbitrationHelper::IsSingleSessionPerUserEnabled'); + // .text:100159C5 lea eax, [esp+150h+VersionInformation] + // .text:100159C9 inc esi <- nop + // .text:100159CA push eax ; lpVersionInformation + // .text:100159CB mov [esp+154h+VersionInformation.dwOSVersionInfoSize], 11Ch + // .text:100159D3 mov [edi], esi + // .text:100159D5 call ds:__imp__GetVersionExW@4 ; GetVersionExW(x) + SignPtr := Pointer(Cardinal(TermSrvBase) + $159C9); + WriteProcessMemory(GetCurrentProcess, SignPtr, @nop, 1, bw); + + WriteLog('Patch CDefPolicy::Query'); + SignPtr := Pointer(Cardinal(TermSrvBase) + $13520); + WriteProcessMemory(GetCurrentProcess, SignPtr, + @CDefPolicy_Query_eax_esi[0], + SizeOf(CDefPolicy_Query_eax_esi), bw); + + WriteLog('Hook SLGetWindowsInformationDWORDWrapper'); + SignPtr := Pointer(Cardinal(TermSrvBase) + $1A0A9); + MovJump.MovOp := $89; // mov eax, ecx + MovJump.MovArg := $C8; // __msfastcall compatibility + MovJump.PushOp := $68; + MovJump.PushArg := @New_Win8SL_CP; + MovJump.RetOp := $C3; + WriteProcessMemory(GetCurrentProcess, SignPtr, + @MovJump, SizeOf(mov_far_jmp), bw); + end; + if (FV.Release = 8400) and (FV.Build = 0) then begin + WriteLog('Patch CSessionArbitrationHelper::IsSingleSessionPerUserEnabled'); + // .text:1001547E lea eax, [esp+150h+VersionInformation] + // .text:10015482 inc esi <- nop + // .text:10015483 push eax ; lpVersionInformation + // .text:10015484 mov [esp+154h+VersionInformation.dwOSVersionInfoSize], 11Ch + // .text:1001548C mov [edi], esi + // .text:1001548E call ds:__imp__GetVersionExW@4 ; GetVersionExW(x) + SignPtr := Pointer(Cardinal(TermSrvBase) + $15482); + WriteProcessMemory(GetCurrentProcess, SignPtr, @nop, 1, bw); + + WriteLog('Patch CDefPolicy::Query'); + SignPtr := Pointer(Cardinal(TermSrvBase) + $13E48); + WriteProcessMemory(GetCurrentProcess, SignPtr, + @CDefPolicy_Query_eax_esi[0], + SizeOf(CDefPolicy_Query_eax_esi), bw); + + WriteLog('Hook SLGetWindowsInformationDWORDWrapper'); + SignPtr := Pointer(Cardinal(TermSrvBase) + $19629); + MovJump.MovOp := $89; // mov eax, ecx + MovJump.MovArg := $C8; // __msfastcall compatibility + MovJump.PushOp := $68; + MovJump.PushArg := @New_Win8SL; + MovJump.RetOp := $C3; + WriteProcessMemory(GetCurrentProcess, SignPtr, + @MovJump, SizeOf(mov_far_jmp), bw); + end; + if (FV.Release = 9200) and (FV.Build = 16384) then begin + WriteLog('Patch CSessionArbitrationHelper::IsSingleSessionPerUserEnabled'); + // .text:1001554E lea eax, [esp+150h+VersionInformation] + // .text:10015552 inc esi <- nop + // .text:10015553 push eax ; lpVersionInformation + // .text:10015554 mov [esp+154h+VersionInformation.dwOSVersionInfoSize], 11Ch + // .text:1001555C mov [edi], esi + // .text:1001555E call ds:__imp__GetVersionExW@4 ; GetVersionExW(x) + SignPtr := Pointer(Cardinal(TermSrvBase) + $15552); + WriteProcessMemory(GetCurrentProcess, SignPtr, @nop, 1, bw); + + WriteLog('Patch CDefPolicy::Query'); + SignPtr := Pointer(Cardinal(TermSrvBase) + $13F08); + WriteProcessMemory(GetCurrentProcess, SignPtr, + @CDefPolicy_Query_eax_esi[0], + SizeOf(CDefPolicy_Query_eax_esi), bw); + + WriteLog('Hook SLGetWindowsInformationDWORDWrapper'); + SignPtr := Pointer(Cardinal(TermSrvBase) + $19559); + MovJump.MovOp := $89; // mov eax, ecx + MovJump.MovArg := $C8; // __msfastcall compatibility + MovJump.PushOp := $68; + MovJump.PushArg := @New_Win8SL; + MovJump.RetOp := $C3; + WriteProcessMemory(GetCurrentProcess, SignPtr, + @MovJump, SizeOf(mov_far_jmp), bw); + end; + if (FV.Release = 9200) and (FV.Build = 17048) then begin + WriteLog('Patch CSessionArbitrationHelper::IsSingleSessionPerUserEnabled'); + // .text:1002058E lea eax, [esp+150h+VersionInformation] + // .text:10020592 inc esi <- nop + // .text:10020593 push eax ; lpVersionInformation + // .text:10020594 mov [esp+154h+VersionInformation.dwOSVersionInfoSize], 11Ch + // .text:1002059C mov [edi], esi + // .text:1002059E call ds:__imp__GetVersionExW@4 ; GetVersionExW(x) + SignPtr := Pointer(Cardinal(TermSrvBase) + $20592); + WriteProcessMemory(GetCurrentProcess, SignPtr, @nop, 1, bw); + + WriteLog('Patch CDefPolicy::Query'); + SignPtr := Pointer(Cardinal(TermSrvBase) + $1F408); + WriteProcessMemory(GetCurrentProcess, SignPtr, + @CDefPolicy_Query_eax_esi[0], + SizeOf(CDefPolicy_Query_eax_esi), bw); + + WriteLog('Hook SLGetWindowsInformationDWORDWrapper'); + SignPtr := Pointer(Cardinal(TermSrvBase) + $17059); + MovJump.MovOp := $89; // mov eax, ecx + MovJump.MovArg := $C8; // __msfastcall compatibility + MovJump.PushOp := $68; + MovJump.PushArg := @New_Win8SL; + MovJump.RetOp := $C3; + WriteProcessMemory(GetCurrentProcess, SignPtr, + @MovJump, SizeOf(mov_far_jmp), bw); + end; + if (FV.Release = 9200) and (FV.Build = 21166) then begin + WriteLog('Patch CSessionArbitrationHelper::IsSingleSessionPerUserEnabled'); + // .text:10015576 lea eax, [esp+150h+VersionInformation] + // .text:1001557A inc esi <- nop + // .text:1001557B push eax ; lpVersionInformation + // .text:1001557C mov [esp+154h+VersionInformation.dwOSVersionInfoSize], 11Ch + // .text:10015584 mov [edi], esi + // .text:10015586 call ds:__imp__GetVersionExW@4 ; GetVersionExW(x) + SignPtr := Pointer(Cardinal(TermSrvBase) + $1557A); + WriteProcessMemory(GetCurrentProcess, SignPtr, @nop, 1, bw); + + WriteLog('Patch CDefPolicy::Query'); + SignPtr := Pointer(Cardinal(TermSrvBase) + $13F30); + WriteProcessMemory(GetCurrentProcess, SignPtr, + @CDefPolicy_Query_eax_esi[0], + SizeOf(CDefPolicy_Query_eax_esi), bw); + + WriteLog('Hook SLGetWindowsInformationDWORDWrapper'); + SignPtr := Pointer(Cardinal(TermSrvBase) + $19581); + MovJump.MovOp := $89; // mov eax, ecx + MovJump.MovArg := $C8; // __msfastcall compatibility + MovJump.PushOp := $68; + MovJump.PushArg := @New_Win8SL; + MovJump.RetOp := $C3; + WriteProcessMemory(GetCurrentProcess, SignPtr, + @MovJump, SizeOf(mov_far_jmp), bw); + end; + end; + end; + if V = $0603 then begin + // Windows 8.1 + // uses SL Policy internal inline code + + if GetModuleAddress('termsrv.dll', GetCurrentProcessId, TermSrvBase, TermSrvSize) then begin + // Patch functions: + // CEnforcementCore::GetInstanceOfTSLicense + // CSessionArbitrationHelper::IsSingleSessionPerUserEnabled + // CDefPolicy::Query + // Hook function: + // CSLQuery::Initialize + + if (FV.Release = 9431) and (FV.Build = 0) then begin + WriteLog('Patch CEnforcementCore::GetInstanceOfTSLicense'); + // .text:1008A604 call ?IsLicenseTypeLocalOnly@CSLQuery@@SGJAAU_GUID@@PAH@Z ; CSLQuery::IsLicenseTypeLocalOnly(_GUID &,int *) + // .text:1008A609 test eax, eax + // .text:1008A60B js short loc_1008A628 + // .text:1008A60D cmp [ebp+var_8], 0 + // .text:1008A611 jz short loc_1008A628 <- jmp + SignPtr := Pointer(Cardinal(TermSrvBase) + $8A611); + b := $EB; + WriteProcessMemory(GetCurrentProcess, SignPtr, @b, 1, bw); + + WriteLog('Patch CSessionArbitrationHelper::IsSingleSessionPerUserEnabled'); + // .text:100306A4 lea eax, [esp+150h+VersionInformation] + // .text:100306A8 inc ebx <- nop + // .text:100306A9 mov [edi], ebx + // .text:100306AB push eax ; lpVersionInformation + // .text:100306AC call ds:__imp__GetVersionExW@4 ; GetVersionExW(x) + SignPtr := Pointer(Cardinal(TermSrvBase) + $306A8); + WriteProcessMemory(GetCurrentProcess, SignPtr, @nop, 1, bw); + + WriteLog('Patch CDefPolicy::Query'); + SignPtr := Pointer(Cardinal(TermSrvBase) + $2EA25); + WriteProcessMemory(GetCurrentProcess, SignPtr, + @CDefPolicy_Query_eax_ecx[0], + SizeOf(CDefPolicy_Query_eax_ecx), bw); + + WriteLog('Hook CSLQuery::Initialize'); + SignPtr := Pointer(Cardinal(TermSrvBase) + $196B0); + Jump.PushOp := $68; + Jump.PushArg := @New_CSLQuery_Initialize; + Jump.RetOp := $C3; + WriteProcessMemory(GetCurrentProcess, SignPtr, + @Jump, SizeOf(far_jmp), bw); + end; + if (FV.Release = 9600) and (FV.Build = 16384) then begin + WriteLog('Patch CEnforcementCore::GetInstanceOfTSLicense'); + // .text:100A271C call ?IsLicenseTypeLocalOnly@CSLQuery@@SGJAAU_GUID@@PAH@Z ; CSLQuery::IsLicenseTypeLocalOnly(_GUID &,int *) + // .text:100A2721 test eax, eax + // .text:100A2723 js short loc_100A2740 + // .text:100A2725 cmp [ebp+var_8], 0 + // .text:100A2729 jz short loc_100A2740 <- jmp + SignPtr := Pointer(Cardinal(TermSrvBase) + $A2729); + b := $EB; + WriteProcessMemory(GetCurrentProcess, SignPtr, @b, 1, bw); + + WriteLog('Patch CSessionArbitrationHelper::IsSingleSessionPerUserEnabled'); + // .text:10018024 lea eax, [esp+150h+VersionInformation] + // .text:10018028 inc ebx <- nop + // .text:10018029 mov [edi], ebx + // .text:1001802B push eax ; lpVersionInformation + // .text:1001802C call ds:__imp__GetVersionExW@4 ; GetVersionExW(x) + SignPtr := Pointer(Cardinal(TermSrvBase) + $18028); + WriteProcessMemory(GetCurrentProcess, SignPtr, @nop, 1, bw); + + WriteLog('Patch CDefPolicy::Query'); + SignPtr := Pointer(Cardinal(TermSrvBase) + $16115); + WriteProcessMemory(GetCurrentProcess, SignPtr, + @CDefPolicy_Query_eax_ecx[0], + SizeOf(CDefPolicy_Query_eax_ecx), bw); + + WriteLog('Hook CSLQuery::Initialize'); + SignPtr := Pointer(Cardinal(TermSrvBase) + $1CEB0); + Jump.PushOp := $68; + Jump.PushArg := @New_CSLQuery_Initialize; + Jump.RetOp := $C3; + WriteProcessMemory(GetCurrentProcess, SignPtr, + @Jump, SizeOf(far_jmp), bw); + end; + if (FV.Release = 9600) and (FV.Build = 17095) then begin + WriteLog('Patch CEnforcementCore::GetInstanceOfTSLicense'); + // .text:100A36C4 call ?IsLicenseTypeLocalOnly@CSLQuery@@SGJAAU_GUID@@PAH@Z ; CSLQuery::IsLicenseTypeLocalOnly(_GUID &,int *) + // .text:100A36C9 test eax, eax + // .text:100A36CB js short loc_100A36E8 + // .text:100A36CD cmp [ebp+var_8], 0 + // .text:100A36D1 jz short loc_100A36E8 <- jmp + SignPtr := Pointer(Cardinal(TermSrvBase) + $A36D1); + b := $EB; + WriteProcessMemory(GetCurrentProcess, SignPtr, @b, 1, bw); + + WriteLog('Patch CSessionArbitrationHelper::IsSingleSessionPerUserEnabled'); + // .text:10036BA5 lea eax, [esp+150h+VersionInformation] + // .text:10036BA9 inc ebx <- nop + // .text:10036BAA mov [edi], ebx + // .text:10036BAC push eax ; lpVersionInformation + // .text:10036BAD call ds:__imp__GetVersionExW@4 ; GetVersionExW(x) + SignPtr := Pointer(Cardinal(TermSrvBase) + $36BA9); + WriteProcessMemory(GetCurrentProcess, SignPtr, @nop, 1, bw); + + WriteLog('Patch CDefPolicy::Query'); + SignPtr := Pointer(Cardinal(TermSrvBase) + $37529); + WriteProcessMemory(GetCurrentProcess, SignPtr, + @CDefPolicy_Query_eax_ecx[0], + SizeOf(CDefPolicy_Query_eax_ecx), bw); + + WriteLog('Hook CSLQuery::Initialize'); + SignPtr := Pointer(Cardinal(TermSrvBase) + $117F1); + Jump.PushOp := $68; + Jump.PushArg := @New_CSLQuery_Initialize; + Jump.RetOp := $C3; + WriteProcessMemory(GetCurrentProcess, SignPtr, + @Jump, SizeOf(far_jmp), bw); + end; + + end; + end; + if V = $0604 then begin + // Windows 10 + // uses SL Policy internal inline code + + if GetModuleAddress('termsrv.dll', GetCurrentProcessId, TermSrvBase, TermSrvSize) then begin + // Patch functions: + // CEnforcementCore::GetInstanceOfTSLicense + // CSessionArbitrationHelper::IsSingleSessionPerUserEnabled + // CDefPolicy::Query + // Hook function: + // CSLQuery::Initialize + + if (FV.Release = 9841) and (FV.Build = 0) then begin + WriteLog('Patch CEnforcementCore::GetInstanceOfTSLicense'); + // .text:1009569B call sub_100B7EE5 + // .text:100956A0 test eax, eax + // .text:100956A2 js short loc_100956BF + // .text:100956A4 cmp [ebp+var_C], 0 + // .text:100956A8 jz short loc_100956BF <- jmp + SignPtr := Pointer(Cardinal(TermSrvBase) + $956A8); + b := $EB; + WriteProcessMemory(GetCurrentProcess, SignPtr, @b, 1, bw); + + WriteLog('Patch CSessionArbitrationHelper::IsSingleSessionPerUserEnabled'); + // .text:10030121 lea eax, [esp+150h+VersionInformation] + // .text:10030125 inc ebx <- nop + // .text:10030126 mov [edi], ebx + // .text:10030128 push eax ; lpVersionInformation + // .text:10030129 call ds:GetVersionExW + SignPtr := Pointer(Cardinal(TermSrvBase) + $30125); + WriteProcessMemory(GetCurrentProcess, SignPtr, @nop, 1, bw); + + WriteLog('Patch CDefPolicy::Query'); + SignPtr := Pointer(Cardinal(TermSrvBase) + $3B989); + WriteProcessMemory(GetCurrentProcess, SignPtr, + @CDefPolicy_Query_eax_ecx[0], + SizeOf(CDefPolicy_Query_eax_ecx), bw); + + WriteLog('Hook CSLQuery::Initialize'); + SignPtr := Pointer(Cardinal(TermSrvBase) + $46A68); + Jump.PushOp := $68; + Jump.PushArg := @New_CSLQuery_Initialize; + Jump.RetOp := $C3; + WriteProcessMemory(GetCurrentProcess, SignPtr, + @Jump, SizeOf(far_jmp), bw); + end; + + end; + end; + + // unfreeze threads + WriteLog('resume'); + RunThreads(); +end; + +function TermServiceMain(dwArgc: DWORD; lpszArgv: PWideChar): DWORD; stdcall; +begin + // wrap ServiceMain function + WriteLog('> ServiceMain'); + if not IsHooked then + HookFunctions; + Result := 0; + if @TSMain <> nil then + Result := TSMain(dwArgc, lpszArgv); +end; + +function TermServiceGlobals(lpGlobalData: Pointer): DWORD; stdcall; +begin + // wrap SvchostPushServiceGlobals function + WriteLog('> SvchostPushServiceGlobals'); + if not IsHooked then + HookFunctions; + Result := 0; + if @TSGlobals <> nil then + Result := TSGlobals(lpGlobalData); +end; + +// export section + +exports + TermServiceMain index 1 name 'ServiceMain'; +exports + TermServiceGlobals index 2 name 'SvchostPushServiceGlobals'; + +begin + // DllMain procedure is not used +end. \ No newline at end of file diff --git a/src-x86-binarymaster/src/rdpwrap.dproj b/src-x86-binarymaster/src/rdpwrap.dproj new file mode 100644 index 0000000..36208c0 --- /dev/null +++ b/src-x86-binarymaster/src/rdpwrap.dproj @@ -0,0 +1,105 @@ + + + {D6811241-D595-4809-B3B8-13BECEA56E11} + rdpwrap.dpr + Release + DCC32 + 12.0 + + + true + + + true + Base + true + + + true + Base + true + + + rdpwrap.dll + WinTypes=Windows;WinProcs=Windows;$(DCC_UnitAlias) + true + 00400000 + x86 + + + false + RELEASE;$(DCC_Define) + 0 + false + + + DEBUG;$(DCC_Define) + + + + MainSource + + + Base + + + Cfg_2 + Base + + + Cfg_1 + Base + + + + + Delphi.Personality.12 + VCLApplication + + + + rdpwrap.dpr + + + False + True + False + + + False + False + 1 + 0 + 0 + 0 + False + False + False + False + False + 1049 + 1251 + + + + + 1.0.0.0 + + + + + + 1.0.0.0 + + + + Embarcadero C++Builder Office 2000 Servers Package + Embarcadero C++Builder Office XP Servers Package + Microsoft Office 2000 Sample Automation Server Wrapper Components + Microsoft Office XP Sample Automation Server Wrapper Components + + + + 12 + + diff --git a/src-x86-binarymaster/src/rdpwrap.dproj.local b/src-x86-binarymaster/src/rdpwrap.dproj.local new file mode 100644 index 0000000..b3811b7 --- /dev/null +++ b/src-x86-binarymaster/src/rdpwrap.dproj.local @@ -0,0 +1,2 @@ + + diff --git a/src-x86-binarymaster/src/rdpwrap.identcache b/src-x86-binarymaster/src/rdpwrap.identcache new file mode 100644 index 0000000..b288331 Binary files /dev/null and b/src-x86-binarymaster/src/rdpwrap.identcache differ diff --git a/src-x86-binarymaster/src/rdpwrap.res b/src-x86-binarymaster/src/rdpwrap.res new file mode 100644 index 0000000..0986250 Binary files /dev/null and b/src-x86-binarymaster/src/rdpwrap.res differ diff --git a/src-x86-x64-Fusix/rdpw32.dll b/src-x86-x64-Fusix/rdpw32.dll new file mode 100644 index 0000000..306889d Binary files /dev/null and b/src-x86-x64-Fusix/rdpw32.dll differ diff --git a/src-x86-x64-Fusix/rdpw64.dll b/src-x86-x64-Fusix/rdpw64.dll new file mode 100644 index 0000000..9fddf48 Binary files /dev/null and b/src-x86-x64-Fusix/rdpw64.dll differ diff --git a/src-x86-x64-Fusix/src/Export.def b/src-x86-x64-Fusix/src/Export.def new file mode 100644 index 0000000..60a4c22 --- /dev/null +++ b/src-x86-x64-Fusix/src/Export.def @@ -0,0 +1,4 @@ +LIBRARY BTREE +EXPORTS + ServiceMain + SvchostPushServiceGlobals \ No newline at end of file diff --git a/src-x86-x64-Fusix/src/RDPWrap.cpp b/src-x86-x64-Fusix/src/RDPWrap.cpp new file mode 100644 index 0000000..69df681 --- /dev/null +++ b/src-x86-x64-Fusix/src/RDPWrap.cpp @@ -0,0 +1,2166 @@ +// RDPWrap C++ port by Fusix (Nikita Parshin) +// assisted by binarymaster (Stas'M) + +// Terminal Services supported versions +// 6.0.X.X (Windows Vista, any) [policy hook only] +// 6.0.6000.16386 (Windows Vista) [policy hook + extended patch] +// 6.0.6001.18000 (Windows Vista SP1) [policy hook + extended patch] +// 6.0.6001.22565 (Windows Vista SP1 with KB977541) [todo] +// 6.0.6001.22635 (Windows Vista SP1 with KB970911) [todo] +// 6.0.6001.22801 (Windows Vista SP1 with KB2381675) [todo] +// 6.0.6002.18005 (Windows Vista SP2) [policy hook + extended patch] +// 6.0.6002.22269 (Windows Vista SP2 with KB977541) [todo] +// 6.0.6002.22340 (Windows Vista SP2 with KB970911) [todo] +// 6.0.6002.22515 (Windows Vista SP2 with KB2381675) [todo] +// 6.0.6002.22641 (Windows Vista SP2 with KB2523307) [todo] +// 6.1.X.X (Windows 7, any) [policy hook only] +// 6.1.7600.16385 (Windows 7) [policy hook + extended patch] +// 6.1.7600.20890 (Windows 7 with KB2479710) [todo] +// 6.1.7600.21316 (Windows 7 with KB2750090) [todo] +// 6.1.7601.17514 (Windows 7 SP1) [policy hook + extended patch] +// 6.1.7601.21650 (Windows 7 SP1 with KB2479710) [todo] +// 6.1.7601.21866 (Windows 7 SP1 with KB2647409) [todo] +// 6.1.7601.22104 (Windows 7 SP1 with KB2750090) [todo] +// 6.1.7601.18540 (Windows 7 SP1 with KB2984972 GDR) [policy hook + extended patch] +// 6.1.7601.22750 (Windows 7 SP1 with KB2984972 LDR) [policy hook + extended patch] +// 6.2.8102.0 (Windows 8 Developer Preview) [policy hook + extended patch] +// 6.2.8250.0 (Windows 8 Consumer Preview) [policy hook + extended patch] +// 6.2.8400.0 (Windows 8 Release Preview) [policy hook + extended patch] +// 6.2.9200.16384 (Windows 8) [policy hook + extended patch] +// 6.2.9200.17048 (Windows 8 with KB2973501 GDR) [policy hook + extended patch] +// 6.2.9200.21166 (Windows 8 with KB2973501 LDR) [policy hook + extended patch] +// 6.3.9431.0 (Windows 8.1 Preview) [init hook + extended patch] +// 6.3.9600.16384 (Windows 8.1) [init hook + extended patch] +// 6.3.9600.17095 (Windows 8.1 with KB2959626) [init hook + extended patch] +// 6.4.9841.0 (Windows 10 Technical Preview) [init hook + extended patch] + +// Known failures +// 6.0.6000.16386 (Windows Vista RTM x86, crashes on logon attempt) + +// Internal changelog: + +// 2014.10.19 : +// - added support for version 6.0.6000.16386 (x64) +// - added support for version 6.0.6001.18000 (x64) +// - added support for version 6.1.7600.16385 + +// 2014.10.18 : +// - corrected some typos in source +// - simplified signature constants +// - added support for version 6.0.6000.16386 (x86) +// - added support for version 6.0.6001.18000 (x86) +// - added support for version 6.0.6002.18005 +// - added support for version 6.1.7601.17514 +// - added support for version 6.1.7601.18540 +// - added support for version 6.1.7601.22750 +// - added support for version 6.2.9200.17048 +// - added support for version 6.2.9200.21166 + +// 2014.10.17 : +// - collecting information about all versions of Terminal Services beginning from Vista +// - added [todo] to the versions list + +// 2014.10.16 : +// - got new updates: KB2984972 for Win 7 (still works with 2 concurrent users) and KB2973501 for Win 8 (doesn't work) + +// 2014.10.02 : +// - researching Windows 10 TP Remote Desktop +// - done! even without debugging symbols ^^) + +// 2014.07.25 : +// - added few comments about ARM platform for developers + +// 2014.07.22 : +// - fixed bug in x64 signatures + +// 2014.07.20 : +// - added support for Windows 8 Release Preview +// - added support for Windows 8 Consumer Preview +// - added support for Windows 8 Developer Preview + +// 2014.07.19 : +// - improved patching of Windows 8 +// - added policy patches +// - will patch CDefPolicy::Query +// - will patch CSessionArbitrationHelper::IsSingleSessionPerUserEnabled + +// 2014.07.18 : +// - researched patched files from MDL forum +// - CSLQuery::GetMaxSessions requires no patching +// - it's better to change the default policy, so... +// - will patch CDefPolicy::Query +// - will patch CEnforcementCore::GetInstanceOfTSLicense +// - will patch CSessionArbitrationHelper::IsSingleSessionPerUserEnabled +// - the function CSLQuery::Initialize is hooked correctly + +// 2014.07.17 : +// - will hook only CSLQuery::Initialize function +// - CSLQuery::GetMaxSessions will be patched +// - added x86 signatures for 6.3.9431.0 (Windows 8.1 Preview) +// - added x64 signatures for 6.3.9431.0 (Windows 8.1 Preview) +// - just for check ^^) + +// 2014.07.16 : +// - changing asm opcodes is bad, will hook CSL functions + +// 2014.07.15 : +// - added x86 signatures for 6.3.9600.16384 (Windows 8.1) +// - added x64 signatures for 6.3.9600.16384 (Windows 8.1) +// - added x86 signatures for 6.3.9600.17095 (Windows 8.1 with KB2959626) +// - added x64 signatures for 6.3.9600.17095 (Windows 8.1 with KB2959626) + +#include "stdafx.h" + +typedef struct +{ + union + { + struct + { + WORD Minor; + WORD Major; + } wVersion; + DWORD dwVersion; + }; + WORD Release; + WORD Build; +} FILE_VERSION; + +#ifdef _WIN64 +typedef unsigned long long PLATFORM_DWORD; +struct FARJMP +{ // x64 far jump | opcode | assembly + BYTE MovOp; // 48 mov rax, ptr + BYTE MovRegArg; // B8 + DWORD64 MovArg; // PTR + BYTE PushRaxOp; // 50 push rax + BYTE RetOp; // C3 retn +}; +// x64 signatures +char CDefPolicy_Query_eax_rcx_jmp[] = {0xB8, 0x00, 0x01, 0x00, 0x00, 0x89, 0x81, 0x38, 0x06, 0x00, 0x00, 0x90, 0xEB}; +char CDefPolicy_Query_eax_rdi[] = {0xB8, 0x00, 0x01, 0x00, 0x00, 0x89, 0x87, 0x38, 0x06, 0x00, 0x00, 0x90}; +char CDefPolicy_Query_eax_rcx[] = {0xB8, 0x00, 0x01, 0x00, 0x00, 0x89, 0x81, 0x38, 0x06, 0x00, 0x00, 0x90}; + +// termsrv.dll build 6.0.6000.16386 + +// Original +// .text:000007FF7573C88F mov eax, [rcx+638h] +// .text:000007FF7573C895 cmp [rcx+63Ch], eax +// .text:000007FF7573C89B jnz short loc_7FF7573C8B3 +//_______________ +// +// Changed +// .text:000007FF7573C88F mov eax, 100h +// .text:000007FF7573C894 mov [rcx+638h], eax +// .text:000007FF7573C89A nop +// .text:000007FF7573C89B jmp short loc_7FF7573C8B3 +// char CDefPolicy_Query_eax_rcx_jmp[] + +// termsrv.dll build 6.0.6001.18000 + +// Original +// .text:000007FF76285BD7 mov eax, [rcx+638h] +// .text:000007FF76285BDD cmp [rcx+63Ch], eax +// .text:000007FF76285BE3 jnz short loc_7FF76285BFB +//_______________ +// +// Changed +// .text:000007FF76285BD7 mov eax, 100h +// .text:000007FF76285BDC mov [rcx+638h], eax +// .text:000007FF76285BE2 nop +// .text:000007FF76285BE3 jmp short loc_7FF76285BFB +// char CDefPolicy_Query_eax_rcx_jmp[] + +// termsrv.dll build 6.0.6002.18005 + +// Original +// .text:000007FF76725E83 mov eax, [rcx+638h] +// .text:000007FF76725E89 cmp [rcx+63Ch], eax +// .text:000007FF76725E8F jz short loc_7FF76725EA7 +//_______________ +// +// Changed +// .text:000007FF76725E83 mov eax, 100h +// .text:000007FF76725E88 mov [rcx+638h], eax +// .text:000007FF76725E8E nop +// .text:000007FF76725E8F jmp short loc_7FF76725EA7 +// char CDefPolicy_Query_eax_rcx_jmp[] + +// termsrv.dll build 6.1.7600.16385 + +// Original +// .text:000007FF75A97AD2 cmp [rdi+63Ch], eax +// .text:000007FF75A97AD8 jz loc_7FF75AA4978 +//_______________ +// +// Changed +// .text:000007FF75A97AD2 mov eax, 100h +// .text:000007FF75A97AD7 mov [rdi+638h], eax +// .text:000007FF75A97ADD nop +// char CDefPolicy_Query_eax_rdi[] + +// termsrv.dll build 6.1.7601.17514 + +// Original +// .text:000007FF75A97D8A cmp [rdi+63Ch], eax +// .text:000007FF75A97D90 jz loc_7FF75AA40F4 +//_______________ +// +// Changed +// .text:000007FF75A97D8A mov eax, 100h +// .text:000007FF75A97D8F mov [rdi+638h], eax +// .text:000007FF75A97D95 nop +// char CDefPolicy_Query_eax_rdi[] + +// termsrv.dll build 6.1.7601.18540 + +// Original +// .text:000007FF75A97C82 cmp [rdi+63Ch], eax +// .text:000007FF75A97C88 jz loc_7FF75AA3FBD +//_______________ +// +// Changed +// .text:000007FF75A97C82 mov eax, 100h +// .text:000007FF75A97C87 mov [rdi+638h], eax +// .text:000007FF75A97C8D nop +// char CDefPolicy_Query_eax_rdi[] + +// termsrv.dll build 6.1.7601.22750 + +// Original +// .text:000007FF75A97C92 cmp [rdi+63Ch], eax +// .text:000007FF75A97C98 jz loc_7FF75AA40A2 +//_______________ +// +// Changed +// .text:000007FF75A97C92 mov eax, 100h +// .text:000007FF75A97C97 mov [rdi+638h], eax +// .text:000007FF75A97C9D nop +// char CDefPolicy_Query_eax_rdi[] + +// termsrv.dll build 6.2.8102.0 + +// Original +// .text:000000018000D3E6 cmp [rdi+63Ch], eax +// .text:000000018000D3EC jz loc_180027792 +//_______________ +// +// Changed +// .text:000000018000D3E6 mov eax, 100h +// .text:000000018000D3EB mov [rdi+638h], eax +// .text:000000018000D3F1 nop +// char CDefPolicy_Query_eax_rdi[] + +// termsrv.dll build 6.2.8250.0 + +// Original +// .text:000000018001187A cmp [rdi+63Ch], eax +// .text:0000000180011880 jz loc_1800273A2 +//_______________ +// +// Changed +// .text:000000018001187A mov eax, 100h +// .text:000000018001187F mov [rdi+638h], eax +// .text:0000000180011885 nop +// char CDefPolicy_Query_eax_rdi[] + +// termsrv.dll build 6.2.8400.0 + +// Original +// .text:000000018001F102 cmp [rdi+63Ch], eax +// .text:000000018001F108 jz loc_18003A02E +//_______________ +// +// Changed +// .text:000000018001F102 mov eax, 100h +// .text:000000018001F107 mov [rdi+638h], eax +// .text:000000018001F10D nop +// char CDefPolicy_Query_eax_rdi[] + +// termsrv.dll build 6.2.9200.16384 + +// Original +// .text:000000018002A31A cmp [rdi+63Ch], eax +// .text:000000018002A320 jz loc_18003A0F9 +//_______________ +// +// Changed +// .text:000000018002A31A mov eax, 100h +// .text:000000018002A31F mov [rdi+638h], eax +// .text:000000018002A325 nop +// char CDefPolicy_Query_eax_rdi[] + +// termsrv.dll build 6.2.9200.17048 + +// Original +// .text:000000018001F206 cmp [rdi+63Ch], eax +// .text:000000018001F20C jz loc_18003A1B4 +//_______________ +// +// Changed +// .text:000000018001F206 mov eax, 100h +// .text:000000018001F20B mov [rdi+638h], eax +// .text:000000018001F211 nop +// char CDefPolicy_Query_eax_rdi[] + +// termsrv.dll build 6.2.9200.21166 + +// Original +// .text:000000018002A3B6 cmp [rdi+63Ch], eax +// .text:000000018002A3BC jz loc_18003A174 +//_______________ +// +// Changed +// .text:000000018002A3B6 mov eax, 100h +// .text:000000018002A3BB mov [rdi+638h], eax +// .text:000000018002A3C1 nop +// char CDefPolicy_Query_eax_rdi[] + +// termsrv.dll build 6.3.9431.0 + +// Original +// .text:00000001800350FD cmp [rcx+63Ch], eax +// .text:0000000180035103 jz loc_18004F6AE +//_______________ +// +// Changed +// .text:00000001800350FD mov eax, 100h +// .text:0000000180035102 mov [rcx+638h], eax +// .text:0000000180035108 nop +// char CDefPolicy_Query_eax_rcx[] + +// termsrv.dll build 6.3.9600.16384 + +// Original +// .text:0000000180057829 cmp [rcx+63Ch], eax +// .text:000000018005782F jz loc_18005E850 +//_______________ +// +// Changed +// .text:0000000180057829 mov eax, 100h +// .text:000000018005782E mov [rcx+638h], eax +// .text:0000000180057834 nop +// char CDefPolicy_Query_eax_rcx[] + +// termsrv.dll build 6.3.9600.17095 + +// Original +// .text:000000018001F6A1 cmp [rcx+63Ch], eax +// .text:000000018001F6A7 jz loc_18007284B +//_______________ +// +// Changed +// .text:000000018001F6A1 mov eax, 100h +// .text:000000018001F6A6 mov [rcx+638h], eax +// .text:000000018001F6AC nop +// char CDefPolicy_Query_eax_rcx[] + +// termsrv.dll build 6.4.9841.0 + +// Original +// .text:000000018000C125 cmp [rcx+63Ch], eax +// .text:000000018000C12B jz sub_18003BABC +//_______________ +// +// Changed +// .text:000000018000C125 mov eax, 100h +// .text:000000018000C12A mov [rcx+638h], eax +// .text:000000018000C130 nop +// char CDefPolicy_Query_eax_rcx[] + +#else +typedef unsigned long PLATFORM_DWORD; +struct FARJMP +{ // x86 far jump | opcode | assembly + BYTE PushOp; // 68 push ptr + DWORD PushArg; // PTR + BYTE RetOp; // C3 retn +}; +// x86 signatures +char CDefPolicy_Query_edx_ecx[] = {0xBA, 0x00, 0x01, 0x00, 0x00, 0x89, 0x91, 0x20, 0x03, 0x00, 0x00, 0x5E, 0x90}; +char CDefPolicy_Query_eax_esi[] = {0xB8, 0x00, 0x01, 0x00, 0x00, 0x89, 0x86, 0x20, 0x03, 0x00, 0x00, 0x90}; +char CDefPolicy_Query_eax_ecx[] = {0xB8, 0x00, 0x01, 0x00, 0x00, 0x89, 0x81, 0x20, 0x03, 0x00, 0x00, 0x90}; + +// termsrv.dll build 6.0.6000.16386 + +// Original +// .text:6F335CD8 cmp edx, [ecx+320h] +// .text:6F335CDE pop esi +// .text:6F335CDF jz loc_6F3426F1 +//_______________ +// +// Changed +// .text:6F335CD8 mov edx, 100h +// .text:6F335CDD mov [ecx+320h], edx +// .text:6F335CE3 pop esi +// .text:6F335CE4 nop +// char CDefPolicy_Query_edx_ecx[] + +// termsrv.dll build 6.0.6001.18000 + +// Original +// .text:6E817FD8 cmp edx, [ecx+320h] +// .text:6E817FDE pop esi +// .text:6E817FDF jz loc_6E826F16 +//_______________ +// +// Changed +// .text:6E817FD8 mov edx, 100h +// .text:6E817FDD mov [ecx+320h], edx +// .text:6E817FE3 pop esi +// .text:6E817FE4 nop +// char CDefPolicy_Query_edx_ecx[] + +// termsrv.dll build 6.0.6002.18005 + +// Original +// .text:6F5979C0 cmp edx, [ecx+320h] +// .text:6F5979C6 pop esi +// .text:6F5979C7 jz loc_6F5A6F26 +//_______________ +// +// Changed +// .text:6F5979C0 mov edx, 100h +// .text:6F5979C5 mov [ecx+320h], edx +// .text:6F5979CB pop esi +// .text:6F5979CC nop +// char CDefPolicy_Query_edx_ecx[] + +// termsrv.dll build 6.1.7600.16385 + +// Original +// .text:6F2F96F3 cmp eax, [esi+320h] +// .text:6F2F96F9 jz loc_6F30E256 +//_______________ +// +// Changed +// .text:6F2F96F3 mov eax, 100h +// .text:6F2F96F8 mov [esi+320h], eax +// .text:6F2F96FE nop +// char CDefPolicy_Query_eax_esi[] + +// termsrv.dll build 6.1.7601.17514 + +// Original +// .text:6F2F9D53 cmp eax, [esi+320h] +// .text:6F2F9D59 jz loc_6F30B25E +//_______________ +// +// Changed +// .text:6F2F9D53 mov eax, 100h +// .text:6F2F9D58 mov [esi+320h], eax +// .text:6F2F9D5E nop +// char CDefPolicy_Query_eax_esi[] + +// termsrv.dll build 6.1.7601.18540 + +// Original +// .text:6F2F9D9F cmp eax, [esi+320h] +// .text:6F2F9DA5 jz loc_6F30B2AE +//_______________ +// +// Changed +// .text:6F2F9D9F mov eax, 100h +// .text:6F2F9DA4 mov [esi+320h], eax +// .text:6F2F9DAA nop +// char CDefPolicy_Query_eax_esi[] + +// termsrv.dll build 6.1.7601.22750 + +// Original +// .text:6F2F9E21 cmp eax, [esi+320h] +// .text:6F2F9E27 jz loc_6F30B6CE +//_______________ +// +// Changed +// .text:6F2F9E21 mov eax, 100h +// .text:6F2F9E26 mov [esi+320h], eax +// .text:6F2F9E2C nop +// char CDefPolicy_Query_eax_esi[] + +// termsrv.dll build 6.2.8102.0 + +// Original +// .text:1000E47C cmp eax, [esi+320h] +// .text:1000E482 jz loc_1002D775 +//_______________ +// +// Changed +// .text:1000E47C mov eax, 100h +// .text:1000E481 mov [esi+320h], eax +// .text:1000E487 nop +// char CDefPolicy_Query_eax_esi[] + +// termsrv.dll build 6.2.8250.0 + +// Original +// .text:10013520 cmp eax, [esi+320h] +// .text:10013526 jz loc_1002DB85 +//_______________ +// +// Changed +// .text:10013520 mov eax, 100h +// .text:10013525 mov [esi+320h], eax +// .text:1001352B nop +// char CDefPolicy_Query_eax_esi[] + +// termsrv.dll build 6.2.8400.0 + +// Original +// .text:10013E48 cmp eax, [esi+320h] +// .text:10013E4E jz loc_1002E079 +//_______________ +// +// Changed +// .text:10013E48 mov eax, 100h +// .text:10013E4D mov [esi+320h], eax +// .text:10013E53 nop +// char CDefPolicy_Query_eax_esi[] + +// termsrv.dll build 6.2.9200.16384 + +// Original +// .text:10013F08 cmp eax, [esi+320h] +// .text:10013F0E jz loc_1002E161 +//_______________ +// +// Changed +// .text:10013F08 mov eax, 100h +// .text:10013F0D mov [esi+320h], eax +// .text:10013F13 nop +// char CDefPolicy_Query_eax_esi[] + +// termsrv.dll build 6.2.9200.17048 + +// Original +// .text:1001F408 cmp eax, [esi+320h] +// .text:1001F40E jz loc_1002E201 +//_______________ +// +// Changed +// .text:1001F408 mov eax, 100h +// .text:1001F40D mov [esi+320h], eax +// .text:1001F413 nop +// char CDefPolicy_Query_eax_esi[] + +// termsrv.dll build 6.2.9200.21166 + +// Original +// .text:10013F30 cmp eax, [esi+320h] +// .text:10013F36 jz loc_1002E189 +//_______________ +// +// Changed +// .text:10013F30 mov eax, 100h +// .text:10013F35 mov [esi+320h], eax +// .text:10013F3B nop +// char CDefPolicy_Query_eax_esi[] + +// termsrv.dll build 6.3.9431.0 + +// Original +// .text:1002EA25 cmp eax, [ecx+320h] +// .text:1002EA2B jz loc_100348C1 +//_______________ +// +// Changed +// .text:1002EA25 mov eax, 100h +// .text:1002EA2A mov [ecx+320h], eax +// .text:1002EA30 nop +// char CDefPolicy_Query_eax_ecx[] + +// termsrv.dll build 6.3.9600.16384 + +// Original +// .text:10016115 cmp eax, [ecx+320h] +// .text:1001611B jz loc_10034DE1 +//_______________ +// +// Changed +// .text:10016115 mov eax, 100h +// .text:1001611A mov [ecx+320h], eax +// .text:10016120 nop +// char CDefPolicy_Query_eax_ecx[] + +// termsrv.dll build 6.3.9600.17095 + +// Original +// .text:10037529 cmp eax, [ecx+320h] +// .text:1003752F jz loc_10043662 +//_______________ +// +// Changed +// .text:10037529 mov eax, 100h +// .text:1003752E mov [ecx+320h], eax +// .text:10037534 nop +// char CDefPolicy_Query_eax_ecx[] + +// termsrv.dll build 6.4.9841.0 + +// Original +// .text:1003B989 cmp eax, [ecx+320h] +// .text:1003B98F jz loc_1005E809 +//_______________ +// +// Changed +// .text:1003B989 mov eax, 100h +// .text:1003B98E mov [ecx+320h], eax +// .text:1003B994 nop +// char CDefPolicy_Query_eax_ecx[] + +#endif + +FARJMP Old_SLGetWindowsInformationDWORD, Stub_SLGetWindowsInformationDWORD; +SLGETWINDOWSINFORMATIONDWORD _SLGetWindowsInformationDWORD; + +HMODULE hTermSrv; +HMODULE hSLC; +PLATFORM_DWORD TermSrvBase; +FILE_VERSION FV; +SERVICEMAIN _ServiceMain; +SVCHOSTPUSHSERVICEGLOBALS _SvchostPushServiceGlobals; +bool AlreadyHooked = false; + +void WriteToLog(LPSTR Text) +{ + DWORD dwBytesOfWritten; + + HANDLE hFile = CreateFile(L"\\rdpwrap.txt", GENERIC_WRITE, FILE_SHARE_WRITE|FILE_SHARE_READ, NULL, OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL); + if (hFile == INVALID_HANDLE_VALUE) return; + + SetFilePointer(hFile, 0, 0, FILE_END); + WriteFile(hFile, Text, strlen(Text), &dwBytesOfWritten, NULL); + CloseHandle(hFile); +} + +PLATFORM_DWORD SearchAddressBySignature(char *StartPosition, PLATFORM_DWORD Size, char *Signature, int SignatureSize) +{ + PLATFORM_DWORD AddressReturn = -1; + + for (PLATFORM_DWORD i = 0; i < Size; i++) + { + for (int j = 0; StartPosition[i+j] == Signature[j] && j < SignatureSize; j++) + { + if (j == SignatureSize-1) AddressReturn = (PLATFORM_DWORD)&StartPosition[i]; + } + } + + return AddressReturn; +} + +bool GetModuleCodeSectionInfo(HMODULE hModule, PLATFORM_DWORD *BaseAddr, PLATFORM_DWORD *BaseSize) +{ + PIMAGE_DOS_HEADER pDosHeader; + PIMAGE_FILE_HEADER pFileHeader; + PIMAGE_OPTIONAL_HEADER pOptionalHeader; + + if (hModule == NULL) return false; + + pDosHeader = (PIMAGE_DOS_HEADER)hModule; + pFileHeader = (PIMAGE_FILE_HEADER)(((PBYTE)hModule)+pDosHeader->e_lfanew+4); + pOptionalHeader = (PIMAGE_OPTIONAL_HEADER)(pFileHeader+1); + + *BaseAddr = (PLATFORM_DWORD)hModule; + *BaseSize = (PLATFORM_DWORD)pOptionalHeader->SizeOfCode; + + if (*BaseAddr <= 0 || *BaseSize <= 0) return false; + return true; +} + +void SetThreadsState(bool Resume) +{ + HANDLE h, hThread; + DWORD CurrTh, CurrPr; + THREADENTRY32 Thread; + + CurrTh = GetCurrentThreadId(); + CurrPr = GetCurrentProcessId(); + + h = CreateToolhelp32Snapshot(TH32CS_SNAPTHREAD, 0); + if (h != INVALID_HANDLE_VALUE) + { + Thread.dwSize = sizeof(THREADENTRY32); + Thread32First(h, &Thread); + do + { + if (Thread.th32ThreadID != CurrTh && Thread.th32OwnerProcessID == CurrPr) + { + hThread = OpenThread(THREAD_SUSPEND_RESUME, false, Thread.th32ThreadID); + if (hThread != INVALID_HANDLE_VALUE) + { + if (Resume) ResumeThread(hThread); + else SuspendThread(hThread); + CloseHandle(hThread); + } + } + } while (Thread32Next(h, &Thread)); + CloseHandle(h); + } +} + +BOOL __stdcall GetModuleVersion(LPCWSTR lptstrModuleName, FILE_VERSION *FileVersion) +{ + typedef struct + { + WORD wLength; + WORD wValueLength; + WORD wType; + WCHAR szKey[16]; + WORD Padding1; + VS_FIXEDFILEINFO Value; + WORD Padding2; + WORD Children; + } VS_VERSIONINFO; + + HMODULE hMod = GetModuleHandle(lptstrModuleName); + if(!hMod) + { + return false; + } + + HRSRC hResourceInfo = FindResourceW(hMod, (LPCWSTR)1, (LPCWSTR)0x10); + if(!hResourceInfo) + { + return false; + } + + VS_VERSIONINFO *VersionInfo = (VS_VERSIONINFO*)LoadResource(hMod, hResourceInfo); + if(!VersionInfo) + { + return false; + } + + FileVersion->dwVersion = VersionInfo->Value.dwFileVersionMS; + FileVersion->Release = (WORD)(VersionInfo->Value.dwFileVersionLS >> 16); + FileVersion->Build = (WORD)VersionInfo->Value.dwFileVersionLS; + + return true; +} + +BOOL __stdcall GetFileVersion(LPCWSTR lptstrFilename, FILE_VERSION *FileVersion) +{ + typedef struct + { + WORD wLength; + WORD wValueLength; + WORD wType; + WCHAR szKey[16]; + WORD Padding1; + VS_FIXEDFILEINFO Value; + WORD Padding2; + WORD Children; + } VS_VERSIONINFO; + + HMODULE hFile = LoadLibraryExW(lptstrFilename, NULL, LOAD_LIBRARY_AS_DATAFILE); + if(!hFile) + { + return false; + } + + HRSRC hResourceInfo = FindResourceW(hFile, (LPCWSTR)1, (LPCWSTR)0x10); + if(!hResourceInfo) + { + return false; + } + + VS_VERSIONINFO *VersionInfo = (VS_VERSIONINFO*)LoadResource(hFile, hResourceInfo); + if(!VersionInfo) + { + return false; + } + + FileVersion->dwVersion = VersionInfo->Value.dwFileVersionMS; + FileVersion->Release = (WORD)(VersionInfo->Value.dwFileVersionLS >> 16); + FileVersion->Build = (WORD)VersionInfo->Value.dwFileVersionLS; + + return true; +} + +bool OverrideSL(LPWSTR ValueName, DWORD *Value) +{ + // Allow Remote Connections + if (wcscmp(ValueName, L"TerminalServices-RemoteConnectionManager-AllowRemoteConnections") == 0) + { + *Value = 1; + return true; + } + // Allow Multiple Sessions + if (wcscmp(ValueName, L"TerminalServices-RemoteConnectionManager-AllowMultipleSessions") == 0) + { + *Value = 1; + return true; + } + // Allow Multiple Sessions (Application Server Mode) + if (wcscmp(ValueName, L"TerminalServices-RemoteConnectionManager-AllowAppServerMode") == 0) + { + *Value = 1; + return true; + } + // Allow Multiple Monitors + if (wcscmp(ValueName, L"TerminalServices-RemoteConnectionManager-AllowMultimon") == 0) + { + *Value = 1; + return true; + } + // Max User Sessions (0 = unlimited) + if (wcscmp(ValueName, L"TerminalServices-RemoteConnectionManager-MaxUserSessions") == 0) + { + *Value = 0; + return true; + } + // Max Debug Sessions (Win 8, 0 = unlimited) + if (wcscmp(ValueName, L"TerminalServices-RemoteConnectionManager-ce0ad219-4670-4988-98fb-89b14c2f072b-MaxSessions") == 0) + { + *Value = 0; + return true; + } + // Max Sessions + // 0 - logon not possible even from console + // 1 - only one active user (console or remote) + // 2 - allow concurrent sessions + if (wcscmp(ValueName, L"TerminalServices-RemoteConnectionManager-45344fe7-00e6-4ac6-9f01-d01fd4ffadfb-MaxSessions") == 0) + { + *Value = 2; + return true; + } + // Allow Advanced Compression with RDP 7 Protocol + if (wcscmp(ValueName, L"TerminalServices-RDP-7-Advanced-Compression-Allowed") == 0) + { + *Value = 1; + return true; + } + // IsTerminalTypeLocalOnly = 0 + if (wcscmp(ValueName, L"TerminalServices-RemoteConnectionManager-45344fe7-00e6-4ac6-9f01-d01fd4ffadfb-LocalOnly") == 0) + { + *Value = 0; + return true; + } + // Max Sessions (hard limit) + if (wcscmp(ValueName, L"TerminalServices-RemoteConnectionManager-8dc86f1d-9969-4379-91c1-06fe1dc60575-MaxSessions") == 0) + { + *Value = 1000; + return true; + } + return false; +} + +HRESULT WINAPI New_SLGetWindowsInformationDWORD(PWSTR pwszValueName, DWORD *pdwValue) +{ + // wrapped SLGetWindowsInformationDWORD function + // termsrv.dll will call this function instead of original SLC.dll + + // Override SL Policy + + extern FARJMP Old_SLGetWindowsInformationDWORD, Stub_SLGetWindowsInformationDWORD; + extern SLGETWINDOWSINFORMATIONDWORD _SLGetWindowsInformationDWORD; + + char *Log; + DWORD dw; + SIZE_T bw; + HRESULT Result; + + Log = new char[1024]; + wsprintfA(Log, "Policy query: %S\r\n", pwszValueName); + WriteToLog(Log); + delete[] Log; + + if (OverrideSL(pwszValueName, &dw)) + { + *pdwValue = dw; + + Log = new char[1024]; + wsprintfA(Log, "Rewrite: %i\r\n", dw); + WriteToLog(Log); + delete[] Log; + + return S_OK; + } + + WriteProcessMemory(GetCurrentProcess(), _SLGetWindowsInformationDWORD, &Old_SLGetWindowsInformationDWORD, sizeof(FARJMP), &bw); + Result = _SLGetWindowsInformationDWORD(pwszValueName, pdwValue); + if (Result == S_OK) + { + Log = new char[1024]; + wsprintfA(Log, "Result: %i\r\n", dw); + WriteToLog(Log); + delete[] Log; + } else { + WriteToLog("Failed\r\n"); + } + WriteProcessMemory(GetCurrentProcess(), _SLGetWindowsInformationDWORD, &Stub_SLGetWindowsInformationDWORD, sizeof(FARJMP), &bw); + + return Result; +} + +HRESULT __fastcall New_Win8SL(PWSTR pwszValueName, DWORD *pdwValue) +{ + // wrapped unexported function SLGetWindowsInformationDWORDWrapper in termsrv.dll + // for Windows 8 support + + // Override SL Policy + + extern SLGETWINDOWSINFORMATIONDWORD _SLGetWindowsInformationDWORD; + + char *Log; + DWORD dw; + HRESULT Result; + + Log = new char[1024]; + wsprintfA(Log, "Policy query: %S\r\n", pwszValueName); + WriteToLog(Log); + delete[] Log; + + if (OverrideSL(pwszValueName, &dw)) + { + *pdwValue = dw; + + Log = new char[1024]; + wsprintfA(Log, "Rewrite: %i\r\n", dw); + WriteToLog(Log); + delete[] Log; + + return S_OK; + } + + Result = _SLGetWindowsInformationDWORD(pwszValueName, pdwValue); + if (Result == S_OK) + { + Log = new char[1024]; + wsprintfA(Log, "Result: %i\r\n", dw); + WriteToLog(Log); + delete[] Log; + } else { + WriteToLog("Failed\r\n"); + } + + return Result; +} + +#ifndef _WIN64 +HRESULT __fastcall New_Win8SL_CP(DWORD arg1, DWORD *pdwValue, PWSTR pwszValueName, DWORD arg4) +{ + // wrapped unexported function SLGetWindowsInformationDWORDWrapper in termsrv.dll + // for Windows 8 Consumer Preview support + + return New_Win8SL(pwszValueName, pdwValue); +} +#endif + +HRESULT WINAPI New_CSLQuery_Initialize() +{ + extern PLATFORM_DWORD TermSrvBase; + extern FILE_VERSION FV; + + char *Log; + DWORD *bServerSku = NULL; + DWORD *bRemoteConnAllowed = NULL; + DWORD *bFUSEnabled = NULL; + DWORD *bAppServerAllowed = NULL; + DWORD *bMultimonAllowed = NULL; + DWORD *lMaxUserSessions = NULL; + DWORD *ulMaxDebugSessions = NULL; + DWORD *bInitialized = NULL; + + WriteToLog("> CSLQuery::Initialize\r\n"); + + if (FV.Release == 9431 && FV.Build == 0) + { + #ifdef _WIN64 + bFUSEnabled = (DWORD*)(TermSrvBase + 0xC4490); + lMaxUserSessions = (DWORD*)(TermSrvBase + 0xC4494); + bAppServerAllowed = (DWORD*)(TermSrvBase + 0xC4498); + bInitialized = (DWORD*)(TermSrvBase + 0xC449C); + bMultimonAllowed = (DWORD*)(TermSrvBase + 0xC44A0); + bServerSku = (DWORD*)(TermSrvBase + 0xC44A4); + ulMaxDebugSessions = (DWORD*)(TermSrvBase + 0xC44A8); + bRemoteConnAllowed = (DWORD*)(TermSrvBase + 0xC44AC); + #else + bFUSEnabled = (DWORD*)(TermSrvBase + 0xA22A8); + lMaxUserSessions = (DWORD*)(TermSrvBase + 0xA22AC); + bAppServerAllowed = (DWORD*)(TermSrvBase + 0xA22B0); + bInitialized = (DWORD*)(TermSrvBase + 0xA22B4); + bMultimonAllowed = (DWORD*)(TermSrvBase + 0xA22B8); + bServerSku = (DWORD*)(TermSrvBase + 0xA22BC); + ulMaxDebugSessions = (DWORD*)(TermSrvBase + 0xA22C0); + bRemoteConnAllowed = (DWORD*)(TermSrvBase + 0xA22C4); + #endif + } + if (FV.Release == 9600 && FV.Build == 16384) + { + #ifdef _WIN64 + bServerSku = (DWORD*)(TermSrvBase + 0xE6494); + ulMaxDebugSessions = (DWORD*)(TermSrvBase + 0xE6498); + bRemoteConnAllowed = (DWORD*)(TermSrvBase + 0xE649C); + bFUSEnabled = (DWORD*)(TermSrvBase + 0xE64A0); + lMaxUserSessions = (DWORD*)(TermSrvBase + 0xE64A4); + bAppServerAllowed = (DWORD*)(TermSrvBase + 0xE64A8); + bInitialized = (DWORD*)(TermSrvBase + 0xE64AC); + bMultimonAllowed = (DWORD*)(TermSrvBase + 0xE64B0); + #else + bFUSEnabled = (DWORD*)(TermSrvBase + 0xC02A8); + lMaxUserSessions = (DWORD*)(TermSrvBase + 0xC02AC); + bAppServerAllowed = (DWORD*)(TermSrvBase + 0xC02B0); + bInitialized = (DWORD*)(TermSrvBase + 0xC02B4); + bMultimonAllowed = (DWORD*)(TermSrvBase + 0xC02B8); + bServerSku = (DWORD*)(TermSrvBase + 0xC02BC); + ulMaxDebugSessions = (DWORD*)(TermSrvBase + 0xC02C0); + bRemoteConnAllowed = (DWORD*)(TermSrvBase + 0xC02C4); + #endif + /* __ARM_ARCH_7 + bFUSEnabled = (DWORD*)(TermSrvBase + 0x?); + lMaxUserSessions = (DWORD*)(TermSrvBase + 0x?); + bAppServerAllowed = (DWORD*)(TermSrvBase + 0x?); + bInitialized = (DWORD*)(TermSrvBase + 0x?); + bMultimonAllowed = (DWORD*)(TermSrvBase + 0x?); + bServerSku = (DWORD*)(TermSrvBase + 0x?); + ulMaxDebugSessions = (DWORD*)(TermSrvBase + 0x?); + bRemoteConnAllowed = (DWORD*)(TermSrvBase + 0x?); + */ + } + if (FV.Release == 9600 && FV.Build == 17095) + { + #ifdef _WIN64 + bServerSku = (DWORD*)(TermSrvBase + 0xE4494); + ulMaxDebugSessions = (DWORD*)(TermSrvBase + 0xE4498); + bRemoteConnAllowed = (DWORD*)(TermSrvBase + 0xE449C); + bFUSEnabled = (DWORD*)(TermSrvBase + 0xE44A0); + lMaxUserSessions = (DWORD*)(TermSrvBase + 0xE44A4); + bAppServerAllowed = (DWORD*)(TermSrvBase + 0xE44A8); + bInitialized = (DWORD*)(TermSrvBase + 0xE44AC); + bMultimonAllowed = (DWORD*)(TermSrvBase + 0xE44B0); + #else + bFUSEnabled = (DWORD*)(TermSrvBase + 0xC12A8); + lMaxUserSessions = (DWORD*)(TermSrvBase + 0xC12AC); + bAppServerAllowed = (DWORD*)(TermSrvBase + 0xC12B0); + bInitialized = (DWORD*)(TermSrvBase + 0xC12B4); + bMultimonAllowed = (DWORD*)(TermSrvBase + 0xC12B8); + bServerSku = (DWORD*)(TermSrvBase + 0xC12BC); + ulMaxDebugSessions = (DWORD*)(TermSrvBase + 0xC12C0); + bRemoteConnAllowed = (DWORD*)(TermSrvBase + 0xC12C4); + #endif + } + if (FV.Release == 9841 && FV.Build == 0) + { + #ifdef _WIN64 + bFUSEnabled = (DWORD*)(TermSrvBase + 0xECFF8); + lMaxUserSessions = (DWORD*)(TermSrvBase + 0xECFFC); + bAppServerAllowed = (DWORD*)(TermSrvBase + 0xED000); + bInitialized = (DWORD*)(TermSrvBase + 0xED004); + bMultimonAllowed = (DWORD*)(TermSrvBase + 0xED008); + bServerSku = (DWORD*)(TermSrvBase + 0xED00C); + ulMaxDebugSessions = (DWORD*)(TermSrvBase + 0xED010); + bRemoteConnAllowed = (DWORD*)(TermSrvBase + 0xED014); + #else + bFUSEnabled = (DWORD*)(TermSrvBase + 0xBF9F0); + lMaxUserSessions = (DWORD*)(TermSrvBase + 0xBF9F4); + bAppServerAllowed = (DWORD*)(TermSrvBase + 0xBF9F8); + bInitialized = (DWORD*)(TermSrvBase + 0xBF9FC); + bMultimonAllowed = (DWORD*)(TermSrvBase + 0xBFA00); + bServerSku = (DWORD*)(TermSrvBase + 0xBFA04); + ulMaxDebugSessions = (DWORD*)(TermSrvBase + 0xBFA08); + bRemoteConnAllowed = (DWORD*)(TermSrvBase + 0xBFA0C); + #endif + } + if (bServerSku) + { + Log = new char[1024]; + wsprintfA(Log, "[0x%p] bServerSku = 1\r\n", bServerSku); + WriteToLog(Log); + delete[] Log; + + *bServerSku = 1; + } + if (bRemoteConnAllowed) + { + Log = new char[1024]; + wsprintfA(Log, "[0x%p] bRemoteConnAllowed = 1\r\n", bRemoteConnAllowed); + WriteToLog(Log); + delete[] Log; + + *bRemoteConnAllowed = 1; + } + if (bFUSEnabled) + { + Log = new char[1024]; + wsprintfA(Log, "[0x%p] bFUSEnabled = 1\r\n", bFUSEnabled); + WriteToLog(Log); + delete[] Log; + + *bFUSEnabled = 1; + } + if (bAppServerAllowed) + { + Log = new char[1024]; + wsprintfA(Log, "[0x%p] bAppServerAllowed = 1\r\n", bAppServerAllowed); + WriteToLog(Log); + delete[] Log; + + *bAppServerAllowed = 1; + } + if (bMultimonAllowed) + { + Log = new char[1024]; + wsprintfA(Log, "[0x%p] bMultimonAllowed = 1\r\n", bMultimonAllowed); + WriteToLog(Log); + delete[] Log; + + *bMultimonAllowed = 1; + } + if (lMaxUserSessions) + { + Log = new char[1024]; + wsprintfA(Log, "[0x%p] lMaxUserSessions = 0\r\n", lMaxUserSessions); + WriteToLog(Log); + delete[] Log; + + *lMaxUserSessions = 0; + } + if (ulMaxDebugSessions) + { + Log = new char[1024]; + wsprintfA(Log, "[0x%p] ulMaxDebugSessions = 0\r\n", ulMaxDebugSessions); + WriteToLog(Log); + delete[] Log; + + *ulMaxDebugSessions = 0; + } + if (bInitialized) + { + Log = new char[1024]; + wsprintfA(Log, "[0x%p] bInitialized = 1\r\n", bInitialized); + WriteToLog(Log); + delete[] Log; + + *bInitialized = 1; + } + return S_OK; +} + +void Hook() +{ + extern FARJMP Old_SLGetWindowsInformationDWORD, Stub_SLGetWindowsInformationDWORD; + extern SLGETWINDOWSINFORMATIONDWORD _SLGetWindowsInformationDWORD; + extern HMODULE hTermSrv; + extern HMODULE hSLC; + extern PLATFORM_DWORD TermSrvBase; + extern FILE_VERSION FV; + + AlreadyHooked = true; + + bool Result; + char *Log; + SIZE_T bw; + WORD Ver = 0; + PLATFORM_DWORD TermSrvSize, SignPtr; + FARJMP Jump; + BYTE b; + + WriteToLog("init\r\n"); + + hTermSrv = LoadLibrary(L"termsrv.dll"); + if (hTermSrv == 0) + { + WriteToLog("Error: Failed to load Terminal Services library\r\n"); + return; + } + _ServiceMain = (SERVICEMAIN)GetProcAddress(hTermSrv, "ServiceMain"); + _SvchostPushServiceGlobals = (SVCHOSTPUSHSERVICEGLOBALS)GetProcAddress(hTermSrv, "SvchostPushServiceGlobals"); + + Log = new char[1024]; + wsprintfA(Log, "Base addr: 0x%p\r\n", hTermSrv); + WriteToLog(Log); + delete[] Log; + + Log = new char[1024]; + wsprintfA(Log, "SvcMain: termsrv.dll+0x%p\r\n", (PLATFORM_DWORD)_ServiceMain - (PLATFORM_DWORD)hTermSrv); + WriteToLog(Log); + delete[] Log; + + Log = new char[1024]; + wsprintfA(Log, "SvcGlobals: termsrv.dll+0x%p\r\n", (PLATFORM_DWORD)_SvchostPushServiceGlobals - (PLATFORM_DWORD)hTermSrv); + WriteToLog(Log); + delete[] Log; + + // check termsrv version + if (GetModuleVersion(L"termsrv.dll", &FV)) + { + Ver = (BYTE)FV.wVersion.Minor | ((BYTE)FV.wVersion.Major << 8); + } else { + // check NT version + // Ver = GetVersion(); // deprecated + // Ver = ((Ver & 0xFF) << 8) | ((Ver & 0xFF00) >> 8); + } + if (Ver == 0) + { + WriteToLog("Error: Failed to detect Terminal Services version\r\n"); + return; + } + + Log = new char[1024]; + wsprintfA(Log, "Version: %d.%d\r\n", FV.wVersion.Major, FV.wVersion.Minor); + WriteToLog(Log); + delete[] Log; + + Log = new char[1024]; + wsprintfA(Log, "Release: %d\r\n", FV.Release); + WriteToLog(Log); + delete[] Log; + + Log = new char[1024]; + wsprintfA(Log, "Build: %d\r\n", FV.Build); + WriteToLog(Log); + delete[] Log; + + // temporarily freeze threads + WriteToLog("freeze\r\n"); + SetThreadsState(false); + + if (Ver == 0x0600) + { + // Windows Vista + // uses SL Policy API (slc.dll) + + // load slc.dll and hook function + hSLC = LoadLibrary(L"slc.dll"); + _SLGetWindowsInformationDWORD = (SLGETWINDOWSINFORMATIONDWORD)GetProcAddress(hSLC, "SLGetWindowsInformationDWORD"); + if (_SLGetWindowsInformationDWORD != INVALID_HANDLE_VALUE) + { + // rewrite original function to call our function (make hook) + + WriteToLog("Hook SLGetWindowsInformationDWORD\r\n"); + #ifdef _WIN64 + Stub_SLGetWindowsInformationDWORD.MovOp = 0x48; + Stub_SLGetWindowsInformationDWORD.MovRegArg = 0xB8; + Stub_SLGetWindowsInformationDWORD.MovArg = (PLATFORM_DWORD)New_SLGetWindowsInformationDWORD; + Stub_SLGetWindowsInformationDWORD.PushRaxOp = 0x50; + Stub_SLGetWindowsInformationDWORD.RetOp = 0xC3; + #else + Stub_SLGetWindowsInformationDWORD.PushOp = 0x68; + Stub_SLGetWindowsInformationDWORD.PushArg = (PLATFORM_DWORD)New_SLGetWindowsInformationDWORD; + Stub_SLGetWindowsInformationDWORD.RetOp = 0xC3; + #endif + + ReadProcessMemory(GetCurrentProcess(), _SLGetWindowsInformationDWORD, &Old_SLGetWindowsInformationDWORD, sizeof(FARJMP), &bw); + WriteProcessMemory(GetCurrentProcess(), _SLGetWindowsInformationDWORD, &Stub_SLGetWindowsInformationDWORD, sizeof(FARJMP), &bw); + } + + if (GetModuleCodeSectionInfo(hTermSrv, &TermSrvBase, &TermSrvSize)) + { + // Patch functions: + // CSessionArbitrationHelper::IsSingleSessionPerUserEnabled + // CDefPolicy::Query + + if (FV.Release == 6000 && FV.Build == 16386) + { + WriteToLog("Patch CSessionArbitrationHelper::IsSingleSessionPerUserEnabled\r\n"); + #ifdef _WIN64 + // Imagebase: 7FF756E0000 + // .text:000007FF75745E38 lea rcx, [rsp+198h+VersionInformation] ; lpVersionInformation + // .text:000007FF75745E3D mov ebx, 1 <- 0 + // .text:000007FF75745E42 mov [rsp+198h+VersionInformation.dwOSVersionInfoSize], 11Ch + // .text:000007FF75745E4A mov [rdi], ebx + // .text:000007FF75745E4C call cs:__imp_GetVersionExW + SignPtr = (PLATFORM_DWORD)(TermSrvBase + 0x65E3E); + b = 0; + #else + // Imagebase: 6F320000 + // .text:6F3360B9 lea eax, [ebp+VersionInformation] + // .text:6F3360BF inc ebx <- nop + // .text:6F3360C0 push eax ; lpVersionInformation + // .text:6F3360C1 mov [ebp+VersionInformation.dwOSVersionInfoSize], 11Ch + // .text:6F3360CB mov [esi], ebx + // .text:6F3360CD call ds:__imp__GetVersionExW@4 ; GetVersionExW(x) + SignPtr = (PLATFORM_DWORD)(TermSrvBase + 0x160BF); + b = 0x90; + #endif + WriteProcessMemory(GetCurrentProcess(), (LPVOID)SignPtr, &b, sizeof(b), &bw); + + WriteToLog("Patch CDefPolicy::Query\r\n"); + #ifdef _WIN64 + SignPtr = (PLATFORM_DWORD)(TermSrvBase + 0x5C88F); + WriteProcessMemory(GetCurrentProcess(), (LPVOID)SignPtr, &CDefPolicy_Query_eax_rcx_jmp, sizeof(CDefPolicy_Query_eax_rcx_jmp), &bw); + #else + SignPtr = (PLATFORM_DWORD)(TermSrvBase + 0x15CD8); + WriteProcessMemory(GetCurrentProcess(), (LPVOID)SignPtr, &CDefPolicy_Query_edx_ecx, sizeof(CDefPolicy_Query_edx_ecx), &bw); + #endif + } + if (FV.Release == 6001 && FV.Build == 18000) + { + WriteToLog("Patch CSessionArbitrationHelper::IsSingleSessionPerUserEnabled\r\n"); + #ifdef _WIN64 + // Imagebase: 7FF76220000 + // .text:000007FF76290DB4 lea rcx, [rsp+198h+VersionInformation] ; lpVersionInformation + // .text:000007FF76290DB9 mov ebx, 1 <- 0 + // .text:000007FF76290DBE mov [rsp+198h+VersionInformation.dwOSVersionInfoSize], 11Ch + // .text:000007FF76290DC6 mov [rdi], ebx + // .text:000007FF76290DC8 call cs:__imp_GetVersionExW + SignPtr = (PLATFORM_DWORD)(TermSrvBase + 0x70DBA); + b = 0; + #else + // Imagebase: 6E800000 + // .text:6E8185DE lea eax, [ebp+VersionInformation] + // .text:6E8185E4 inc ebx <- nop + // .text:6E8185E5 push eax ; lpVersionInformation + // .text:6E8185E6 mov [ebp+VersionInformation.dwOSVersionInfoSize], 11Ch + // .text:6E8185F0 mov [esi], ebx + // .text:6E8185F2 call ds:__imp__GetVersionExW@4 ; GetVersionExW(x) + SignPtr = (PLATFORM_DWORD)(TermSrvBase + 0x185E4); + b = 0x90; + #endif + WriteProcessMemory(GetCurrentProcess(), (LPVOID)SignPtr, &b, sizeof(b), &bw); + + WriteToLog("Patch CDefPolicy::Query\r\n"); + #ifdef _WIN64 + SignPtr = (PLATFORM_DWORD)(TermSrvBase + 0x65BD7); + WriteProcessMemory(GetCurrentProcess(), (LPVOID)SignPtr, &CDefPolicy_Query_eax_rcx_jmp, sizeof(CDefPolicy_Query_eax_rcx_jmp), &bw); + #else + SignPtr = (PLATFORM_DWORD)(TermSrvBase + 0x17FD8); + WriteProcessMemory(GetCurrentProcess(), (LPVOID)SignPtr, &CDefPolicy_Query_edx_ecx, sizeof(CDefPolicy_Query_edx_ecx), &bw); + #endif + } + if (FV.Release == 6002 && FV.Build == 18005) + { + WriteToLog("Patch CSessionArbitrationHelper::IsSingleSessionPerUserEnabled\r\n"); + #ifdef _WIN64 + // Imagebase: 7FF766C0000 + // .text:000007FF76730FF0 lea rcx, [rsp+198h+VersionInformation] ; lpVersionInformation + // .text:000007FF76730FF5 mov ebx, 1 <- 0 + // .text:000007FF76730FFA mov [rsp+198h+VersionInformation.dwOSVersionInfoSize], 11Ch + // .text:000007FF76731002 mov [rdi], ebx + // .text:000007FF76731004 call cs:__imp_GetVersionExW + SignPtr = (PLATFORM_DWORD)(TermSrvBase + 0x70FF6); + b = 0; + #else + // Imagebase: 6F580000 + // .text:6F597FA2 lea eax, [ebp+VersionInformation] + // .text:6F597FA8 inc ebx <- nop + // .text:6F597FA9 push eax ; lpVersionInformation + // .text:6F597FAA mov [ebp+VersionInformation.dwOSVersionInfoSize], 11Ch + // .text:6F597FB4 mov [esi], ebx + // .text:6F597FB6 call ds:__imp__GetVersionExW@4 ; GetVersionExW(x) + SignPtr = (PLATFORM_DWORD)(TermSrvBase + 0x17FA8); + b = 0x90; + #endif + WriteProcessMemory(GetCurrentProcess(), (LPVOID)SignPtr, &b, sizeof(b), &bw); + + WriteToLog("Patch CDefPolicy::Query\r\n"); + #ifdef _WIN64 + SignPtr = (PLATFORM_DWORD)(TermSrvBase + 0x65E83); + WriteProcessMemory(GetCurrentProcess(), (LPVOID)SignPtr, &CDefPolicy_Query_eax_rcx_jmp, sizeof(CDefPolicy_Query_eax_rcx_jmp), &bw); + #else + SignPtr = (PLATFORM_DWORD)(TermSrvBase + 0x179C0); + WriteProcessMemory(GetCurrentProcess(), (LPVOID)SignPtr, &CDefPolicy_Query_edx_ecx, sizeof(CDefPolicy_Query_edx_ecx), &bw); + #endif + } + } + } + if (Ver == 0x0601) + { + // Windows 7 + // uses SL Policy API (slc.dll) + + // load slc.dll and hook function + hSLC = LoadLibrary(L"slc.dll"); + _SLGetWindowsInformationDWORD = (SLGETWINDOWSINFORMATIONDWORD)GetProcAddress(hSLC, "SLGetWindowsInformationDWORD"); + if (_SLGetWindowsInformationDWORD != INVALID_HANDLE_VALUE) + { + // rewrite original function to call our function (make hook) + + WriteToLog("Hook SLGetWindowsInformationDWORD\r\n"); + #ifdef _WIN64 + Stub_SLGetWindowsInformationDWORD.MovOp = 0x48; + Stub_SLGetWindowsInformationDWORD.MovRegArg = 0xB8; + Stub_SLGetWindowsInformationDWORD.MovArg = (PLATFORM_DWORD)New_SLGetWindowsInformationDWORD; + Stub_SLGetWindowsInformationDWORD.PushRaxOp = 0x50; + Stub_SLGetWindowsInformationDWORD.RetOp = 0xC3; + #else + Stub_SLGetWindowsInformationDWORD.PushOp = 0x68; + Stub_SLGetWindowsInformationDWORD.PushArg = (PLATFORM_DWORD)New_SLGetWindowsInformationDWORD; + Stub_SLGetWindowsInformationDWORD.RetOp = 0xC3; + #endif + + ReadProcessMemory(GetCurrentProcess(), _SLGetWindowsInformationDWORD, &Old_SLGetWindowsInformationDWORD, sizeof(FARJMP), &bw); + WriteProcessMemory(GetCurrentProcess(), _SLGetWindowsInformationDWORD, &Stub_SLGetWindowsInformationDWORD, sizeof(FARJMP), &bw); + } + + if (GetModuleCodeSectionInfo(hTermSrv, &TermSrvBase, &TermSrvSize)) + { + // Patch functions: + // CSessionArbitrationHelper::IsSingleSessionPerUserEnabled + // CDefPolicy::Query + + if (FV.Release == 7600 && FV.Build == 16385) + { + WriteToLog("Patch CSessionArbitrationHelper::IsSingleSessionPerUserEnabled\r\n"); + #ifdef _WIN64 + // Imagebase: 7FF75A80000 + // .text:000007FF75A97D90 lea rcx, [rsp+198h+VersionInformation] ; lpVersionInformation + // .text:000007FF75A97D95 mov ebx, 1 <- 0 + // .text:000007FF75A97D9A mov [rsp+198h+VersionInformation.dwOSVersionInfoSize], 11Ch + // .text:000007FF75A97DA2 mov [rdi], ebx + // .text:000007FF75A97DA4 call cs:__imp_GetVersionExW + SignPtr = (PLATFORM_DWORD)(TermSrvBase + 0x17D96); + b = 0; + #else + // Imagebase: 6F2E0000 + // .text:6F2F9E1F lea eax, [ebp+VersionInformation] + // .text:6F2F9E25 inc ebx <- nop + // .text:6F2F9E26 push eax ; lpVersionInformation + // .text:6F2F9E27 mov [ebp+VersionInformation.dwOSVersionInfoSize], 11Ch + // .text:6F2F9E31 mov [esi], ebx + // .text:6F2F9E33 call ds:__imp__GetVersionExW@4 ; GetVersionExW(x) + SignPtr = (PLATFORM_DWORD)(TermSrvBase + 0x19E25); + b = 0x90; + #endif + WriteProcessMemory(GetCurrentProcess(), (LPVOID)SignPtr, &b, sizeof(b), &bw); + + WriteToLog("Patch CDefPolicy::Query\r\n"); + #ifdef _WIN64 + SignPtr = (PLATFORM_DWORD)(TermSrvBase + 0x17AD2); + WriteProcessMemory(GetCurrentProcess(), (LPVOID)SignPtr, &CDefPolicy_Query_eax_rdi, sizeof(CDefPolicy_Query_eax_rdi), &bw); + #else + SignPtr = (PLATFORM_DWORD)(TermSrvBase + 0x196F3); + WriteProcessMemory(GetCurrentProcess(), (LPVOID)SignPtr, &CDefPolicy_Query_eax_esi, sizeof(CDefPolicy_Query_eax_esi), &bw); + #endif + } + if (FV.Release == 7601 && FV.Build == 17514) + { + WriteToLog("Patch CSessionArbitrationHelper::IsSingleSessionPerUserEnabled\r\n"); + #ifdef _WIN64 + // Imagebase: 7FF75A80000 + // .text:000007FF75A980DC lea rcx, [rsp+198h+VersionInformation] ; lpVersionInformation + // .text:000007FF75A980E1 mov ebx, 1 <- 0 + // .text:000007FF75A980E6 mov [rsp+198h+VersionInformation.dwOSVersionInfoSize], 11Ch + // .text:000007FF75A980EE mov [rdi], ebx + // .text:000007FF75A980F0 call cs:__imp_GetVersionExW + SignPtr = (PLATFORM_DWORD)(TermSrvBase + 0x180E2); + b = 0; + #else + // Imagebase: 6F2E0000 + // .text:6F2FA497 lea eax, [ebp+VersionInformation] + // .text:6F2FA49D inc ebx <- nop + // .text:6F2FA49E push eax ; lpVersionInformation + // .text:6F2FA49F mov [ebp+VersionInformation.dwOSVersionInfoSize], 11Ch + // .text:6F2FA4A9 mov [esi], ebx + // .text:6F2FA4AB call ds:__imp__GetVersionExW@4 ; GetVersionExW(x) + SignPtr = (PLATFORM_DWORD)(TermSrvBase + 0x1A49D); + b = 0x90; + #endif + WriteProcessMemory(GetCurrentProcess(), (LPVOID)SignPtr, &b, sizeof(b), &bw); + + WriteToLog("Patch CDefPolicy::Query\r\n"); + #ifdef _WIN64 + SignPtr = (PLATFORM_DWORD)(TermSrvBase + 0x17D8A); + WriteProcessMemory(GetCurrentProcess(), (LPVOID)SignPtr, &CDefPolicy_Query_eax_rdi, sizeof(CDefPolicy_Query_eax_rdi), &bw); + #else + SignPtr = (PLATFORM_DWORD)(TermSrvBase + 0x19D53); + WriteProcessMemory(GetCurrentProcess(), (LPVOID)SignPtr, &CDefPolicy_Query_eax_esi, sizeof(CDefPolicy_Query_eax_esi), &bw); + #endif + } + if (FV.Release == 7601 && FV.Build == 18540) + { + WriteToLog("Patch CSessionArbitrationHelper::IsSingleSessionPerUserEnabled\r\n"); + #ifdef _WIN64 + // Imagebase: 7FF75A80000 + // .text:000007FF75A98000 lea rcx, [rsp+198h+VersionInformation] ; lpVersionInformation + // .text:000007FF75A98005 mov ebx, 1 <- 0 + // .text:000007FF75A9800A mov [rsp+198h+VersionInformation.dwOSVersionInfoSize], 11Ch + // .text:000007FF75A98012 mov [rdi], ebx + // .text:000007FF75A98014 call cs:__imp_GetVersionExW + SignPtr = (PLATFORM_DWORD)(TermSrvBase + 0x18006); + b = 0; + #else + // Imagebase: 6F2E0000 + // .text:6F2FA4DF lea eax, [ebp+VersionInformation] + // .text:6F2FA4E5 inc ebx <- nop + // .text:6F2FA4E6 push eax ; lpVersionInformation + // .text:6F2FA4E7 mov [ebp+VersionInformation.dwOSVersionInfoSize], 11Ch + // .text:6F2FA4F1 mov [esi], ebx + // .text:6F2FA4F3 call ds:__imp__GetVersionExW@4 ; GetVersionExW(x) + SignPtr = (PLATFORM_DWORD)(TermSrvBase + 0x1A4E5); + b = 0x90; + #endif + WriteProcessMemory(GetCurrentProcess(), (LPVOID)SignPtr, &b, sizeof(b), &bw); + + WriteToLog("Patch CDefPolicy::Query\r\n"); + #ifdef _WIN64 + SignPtr = (PLATFORM_DWORD)(TermSrvBase + 0x17C82); + WriteProcessMemory(GetCurrentProcess(), (LPVOID)SignPtr, &CDefPolicy_Query_eax_rdi, sizeof(CDefPolicy_Query_eax_rdi), &bw); + #else + SignPtr = (PLATFORM_DWORD)(TermSrvBase + 0x19D9F); + WriteProcessMemory(GetCurrentProcess(), (LPVOID)SignPtr, &CDefPolicy_Query_eax_esi, sizeof(CDefPolicy_Query_eax_esi), &bw); + #endif + } + if (FV.Release == 7601 && FV.Build == 22750) + { + WriteToLog("Patch CSessionArbitrationHelper::IsSingleSessionPerUserEnabled\r\n"); + #ifdef _WIN64 + // Imagebase: 7FF75A80000 + // .text:000007FF75A97E88 lea rcx, [rsp+198h+VersionInformation] ; lpVersionInformation + // .text:000007FF75A97E8D mov ebx, 1 <- 0 + // .text:000007FF75A97E92 mov [rsp+198h+VersionInformation.dwOSVersionInfoSize], 11Ch + // .text:000007FF75A97E9A mov [rdi], ebx + // .text:000007FF75A97E9C call cs:__imp_GetVersionExW + SignPtr = (PLATFORM_DWORD)(TermSrvBase + 0x17E8E); + b = 0; + #else + // Imagebase: 6F2E0000 + // .text:6F2FA64F lea eax, [ebp+VersionInformation] + // .text:6F2FA655 inc ebx <- nop + // .text:6F2FA656 push eax ; lpVersionInformation + // .text:6F2FA657 mov [ebp+VersionInformation.dwOSVersionInfoSize], 11Ch + // .text:6F2FA661 mov [esi], ebx + // .text:6F2FA663 call ds:__imp__GetVersionExW@4 ; GetVersionExW(x) + SignPtr = (PLATFORM_DWORD)(TermSrvBase + 0x1A655); + b = 0x90; + #endif + WriteProcessMemory(GetCurrentProcess(), (LPVOID)SignPtr, &b, sizeof(b), &bw); + + WriteToLog("Patch CDefPolicy::Query\r\n"); + #ifdef _WIN64 + SignPtr = (PLATFORM_DWORD)(TermSrvBase + 0x17C92); + WriteProcessMemory(GetCurrentProcess(), (LPVOID)SignPtr, &CDefPolicy_Query_eax_rdi, sizeof(CDefPolicy_Query_eax_rdi), &bw); + #else + SignPtr = (PLATFORM_DWORD)(TermSrvBase + 0x19E21); + WriteProcessMemory(GetCurrentProcess(), (LPVOID)SignPtr, &CDefPolicy_Query_eax_esi, sizeof(CDefPolicy_Query_eax_esi), &bw); + #endif + } + } + } + if (Ver == 0x0602) + { + // Windows 8 + // uses SL Policy internal unexported function + + // load slc.dll and get function + // (will be used on intercepting undefined values) + hSLC = LoadLibrary(L"slc.dll"); + _SLGetWindowsInformationDWORD = (SLGETWINDOWSINFORMATIONDWORD)GetProcAddress(hSLC, "SLGetWindowsInformationDWORD"); + + if (GetModuleCodeSectionInfo(hTermSrv, &TermSrvBase, &TermSrvSize)) + { + // Patch functions: + // CSessionArbitrationHelper::IsSingleSessionPerUserEnabled + // CDefPolicy::Query + // Hook function: + // SLGetWindowsInformationDWORDWrapper + + if (FV.Release == 8102 && FV.Build == 0) + { + WriteToLog("Patch CSessionArbitrationHelper::IsSingleSessionPerUserEnabled\r\n"); + #ifdef _WIN64 + // .text:000000018000D83A lea rcx, [rsp+180h+VersionInformation] ; lpVersionInformation + // .text:000000018000D83F mov ebx, 1 <- 0 + // .text:000000018000D844 mov [rsp+180h+VersionInformation.dwOSVersionInfoSize], 11Ch + // .text:000000018000D84C mov [rdi], ebx + // .text:000000018000D84E call cs:__imp_GetVersionExW + SignPtr = (PLATFORM_DWORD)(TermSrvBase + 0xD840); + b = 0; + #else + // .text:1000F7E5 lea eax, [esp+150h+VersionInformation] + // .text:1000F7E9 inc esi <- nop + // .text:1000F7EA push eax ; lpVersionInformation + // .text:1000F7EB mov [esp+154h+VersionInformation.dwOSVersionInfoSize], 11Ch + // .text:1000F7F3 mov [edi], esi + // .text:1000F7F5 call ds:__imp__GetVersionExW@4 ; GetVersionExW(x) + SignPtr = (PLATFORM_DWORD)(TermSrvBase + 0xF7E9); + b = 0x90; + #endif + WriteProcessMemory(GetCurrentProcess(), (LPVOID)SignPtr, &b, sizeof(b), &bw); + + WriteToLog("Patch CDefPolicy::Query\r\n"); + #ifdef _WIN64 + SignPtr = (PLATFORM_DWORD)(TermSrvBase + 0xD3E6); + WriteProcessMemory(GetCurrentProcess(), (LPVOID)SignPtr, &CDefPolicy_Query_eax_rdi, sizeof(CDefPolicy_Query_eax_rdi), &bw); + #else + SignPtr = (PLATFORM_DWORD)(TermSrvBase + 0xE47C); + WriteProcessMemory(GetCurrentProcess(), (LPVOID)SignPtr, &CDefPolicy_Query_eax_esi, sizeof(CDefPolicy_Query_eax_esi), &bw); + #endif + + WriteToLog("Hook SLGetWindowsInformationDWORDWrapper\r\n"); + #ifdef _WIN64 + SignPtr = (PLATFORM_DWORD)(TermSrvBase + 0x1A484); + Jump.MovOp = 0x48; + Jump.MovRegArg = 0xB8; + Jump.MovArg = (PLATFORM_DWORD)New_Win8SL; + Jump.PushRaxOp = 0x50; + Jump.RetOp = 0xC3; + #else + SignPtr = (PLATFORM_DWORD)(TermSrvBase + 0x1B909); + Jump.PushOp = 0x68; + Jump.PushArg = (PLATFORM_DWORD)New_Win8SL; + Jump.RetOp = 0xC3; + #endif + WriteProcessMemory(GetCurrentProcess(), (LPVOID)SignPtr, &Jump, sizeof(FARJMP), &bw); + } + if (FV.Release == 8250 && FV.Build == 0) + { + WriteToLog("Patch CSessionArbitrationHelper::IsSingleSessionPerUserEnabled\r\n"); + #ifdef _WIN64 + // .text:0000000180011E6E lea rcx, [rsp+180h+VersionInformation] ; lpVersionInformation + // .text:0000000180011E73 mov ebx, 1 <- 0 + // .text:0000000180011E78 mov [rsp+180h+VersionInformation.dwOSVersionInfoSize], 11Ch + // .text:0000000180011E80 mov [rdi], ebx + // .text:0000000180011E82 call cs:__imp_GetVersionExW + SignPtr = (PLATFORM_DWORD)(TermSrvBase + 0x11E74); + b = 0; + #else + // .text:100159C5 lea eax, [esp+150h+VersionInformation] + // .text:100159C9 inc esi <- nop + // .text:100159CA push eax ; lpVersionInformation + // .text:100159CB mov [esp+154h+VersionInformation.dwOSVersionInfoSize], 11Ch + // .text:100159D3 mov [edi], esi + // .text:100159D5 call ds:__imp__GetVersionExW@4 ; GetVersionExW(x) + SignPtr = (PLATFORM_DWORD)(TermSrvBase + 0x159C9); + b = 0x90; + #endif + WriteProcessMemory(GetCurrentProcess(), (LPVOID)SignPtr, &b, sizeof(b), &bw); + + WriteToLog("Patch CDefPolicy::Query\r\n"); + #ifdef _WIN64 + SignPtr = (PLATFORM_DWORD)(TermSrvBase + 0x1187A); + WriteProcessMemory(GetCurrentProcess(), (LPVOID)SignPtr, &CDefPolicy_Query_eax_rdi, sizeof(CDefPolicy_Query_eax_rdi), &bw); + #else + SignPtr = (PLATFORM_DWORD)(TermSrvBase + 0x13520); + WriteProcessMemory(GetCurrentProcess(), (LPVOID)SignPtr, &CDefPolicy_Query_eax_esi, sizeof(CDefPolicy_Query_eax_esi), &bw); + #endif + + WriteToLog("Hook SLGetWindowsInformationDWORDWrapper\r\n"); + #ifdef _WIN64 + SignPtr = (PLATFORM_DWORD)(TermSrvBase + 0x18FAC); + Jump.MovOp = 0x48; + Jump.MovRegArg = 0xB8; + Jump.MovArg = (PLATFORM_DWORD)New_Win8SL; + Jump.PushRaxOp = 0x50; + Jump.RetOp = 0xC3; + #else + SignPtr = (PLATFORM_DWORD)(TermSrvBase + 0x1A0A9); + Jump.PushOp = 0x68; + Jump.PushArg = (PLATFORM_DWORD)New_Win8SL_CP; + Jump.RetOp = 0xC3; + #endif + WriteProcessMemory(GetCurrentProcess(), (LPVOID)SignPtr, &Jump, sizeof(FARJMP), &bw); + } + if (FV.Release == 8400 && FV.Build == 0) + { + WriteToLog("Patch CSessionArbitrationHelper::IsSingleSessionPerUserEnabled\r\n"); + #ifdef _WIN64 + // .text:000000018002081E lea rcx, [rsp+180h+VersionInformation] ; lpVersionInformation + // .text:0000000180020823 mov ebx, 1 <- 0 + // .text:0000000180020828 mov [rsp+180h+VersionInformation.dwOSVersionInfoSize], 11Ch + // .text:0000000180020830 mov [rdi], ebx + // .text:0000000180020832 call cs:__imp_GetVersionExW + SignPtr = (PLATFORM_DWORD)(TermSrvBase + 0x20824); + b = 0; + #else + // .text:1001547E lea eax, [esp+150h+VersionInformation] + // .text:10015482 inc esi <- nop + // .text:10015483 push eax ; lpVersionInformation + // .text:10015484 mov [esp+154h+VersionInformation.dwOSVersionInfoSize], 11Ch + // .text:1001548C mov [edi], esi + // .text:1001548E call ds:__imp__GetVersionExW@4 ; GetVersionExW(x) + SignPtr = (PLATFORM_DWORD)(TermSrvBase + 0x15482); + b = 0x90; + #endif + WriteProcessMemory(GetCurrentProcess(), (LPVOID)SignPtr, &b, sizeof(b), &bw); + + WriteToLog("Patch CDefPolicy::Query\r\n"); + #ifdef _WIN64 + SignPtr = (PLATFORM_DWORD)(TermSrvBase + 0x1F102); + WriteProcessMemory(GetCurrentProcess(), (LPVOID)SignPtr, &CDefPolicy_Query_eax_rdi, sizeof(CDefPolicy_Query_eax_rdi), &bw); + #else + SignPtr = (PLATFORM_DWORD)(TermSrvBase + 0x13E48); + WriteProcessMemory(GetCurrentProcess(), (LPVOID)SignPtr, &CDefPolicy_Query_eax_esi, sizeof(CDefPolicy_Query_eax_esi), &bw); + #endif + + WriteToLog("Hook SLGetWindowsInformationDWORDWrapper\r\n"); + #ifdef _WIN64 + SignPtr = (PLATFORM_DWORD)(TermSrvBase + 0x2492C); + Jump.MovOp = 0x48; + Jump.MovRegArg = 0xB8; + Jump.MovArg = (PLATFORM_DWORD)New_Win8SL; + Jump.PushRaxOp = 0x50; + Jump.RetOp = 0xC3; + #else + SignPtr = (PLATFORM_DWORD)(TermSrvBase + 0x19629); + Jump.PushOp = 0x68; + Jump.PushArg = (PLATFORM_DWORD)New_Win8SL; + Jump.RetOp = 0xC3; + #endif + WriteProcessMemory(GetCurrentProcess(), (LPVOID)SignPtr, &Jump, sizeof(FARJMP), &bw); + } + if (FV.Release == 9200 && FV.Build == 16384) + { + WriteToLog("Patch CSessionArbitrationHelper::IsSingleSessionPerUserEnabled\r\n"); + #ifdef _WIN64 + // .text:000000018002BAA2 lea rcx, [rsp+180h+VersionInformation] ; lpVersionInformation + // .text:000000018002BAA7 mov ebx, 1 <- 0 + // .text:000000018002BAAC mov [rsp+180h+VersionInformation.dwOSVersionInfoSize], 11Ch + // .text:000000018002BAB4 mov [rdi], ebx + // .text:000000018002BAB6 call cs:__imp_GetVersionExW + SignPtr = (PLATFORM_DWORD)(TermSrvBase + 0x2BAA8); + b = 0; + #else + // .text:1001554E lea eax, [esp+150h+VersionInformation] + // .text:10015552 inc esi <- nop + // .text:10015553 push eax ; lpVersionInformation + // .text:10015554 mov [esp+154h+VersionInformation.dwOSVersionInfoSize], 11Ch + // .text:1001555C mov [edi], esi + // .text:1001555E call ds:__imp__GetVersionExW@4 ; GetVersionExW(x) + SignPtr = (PLATFORM_DWORD)(TermSrvBase + 0x15552); + b = 0x90; + #endif + /* __ARM_ARCH_7 + SignPtr = (PLATFORM_DWORD)(TermSrvBase + 0x?); // unknown + */ + WriteProcessMemory(GetCurrentProcess(), (LPVOID)SignPtr, &b, sizeof(b), &bw); + + WriteToLog("Patch CDefPolicy::Query\r\n"); + #ifdef _WIN64 + SignPtr = (PLATFORM_DWORD)(TermSrvBase + 0x2A31A); + WriteProcessMemory(GetCurrentProcess(), (LPVOID)SignPtr, &CDefPolicy_Query_eax_rdi, sizeof(CDefPolicy_Query_eax_rdi), &bw); + #else + SignPtr = (PLATFORM_DWORD)(TermSrvBase + 0x13F08); + WriteProcessMemory(GetCurrentProcess(), (LPVOID)SignPtr, &CDefPolicy_Query_eax_esi, sizeof(CDefPolicy_Query_eax_esi), &bw); + #endif + /* __ARM_ARCH_7 + SignPtr = (PLATFORM_DWORD)(TermSrvBase + 0x?); // unknown + */ + + WriteToLog("Hook SLGetWindowsInformationDWORDWrapper\r\n"); + #ifdef _WIN64 + SignPtr = (PLATFORM_DWORD)(TermSrvBase + 0x21FA8); + Jump.MovOp = 0x48; + Jump.MovRegArg = 0xB8; + Jump.MovArg = (PLATFORM_DWORD)New_Win8SL; + Jump.PushRaxOp = 0x50; + Jump.RetOp = 0xC3; + #else + SignPtr = (PLATFORM_DWORD)(TermSrvBase + 0x19559); + Jump.PushOp = 0x68; + Jump.PushArg = (PLATFORM_DWORD)New_Win8SL; + Jump.RetOp = 0xC3; + #endif + /* __ARM_ARCH_7 + SignPtr = (PLATFORM_DWORD)(TermSrvBase + 0x5F934); + // hook opcodes? + Don't know how to make far jump on ARM platform + */ + WriteProcessMemory(GetCurrentProcess(), (LPVOID)SignPtr, &Jump, sizeof(FARJMP), &bw); + } + if (FV.Release == 9200 && FV.Build == 17048) + { + WriteToLog("Patch CSessionArbitrationHelper::IsSingleSessionPerUserEnabled\r\n"); + #ifdef _WIN64 + // .text:0000000180020942 lea rcx, [rsp+180h+VersionInformation] ; lpVersionInformation + // .text:0000000180020947 mov ebx, 1 <- 0 + // .text:000000018002094C mov [rsp+180h+VersionInformation.dwOSVersionInfoSize], 11Ch + // .text:0000000180020954 mov [rdi], ebx + // .text:0000000180020956 call cs:__imp_GetVersionExW + SignPtr = (PLATFORM_DWORD)(TermSrvBase + 0x20948); + b = 0; + #else + // .text:1002058E lea eax, [esp+150h+VersionInformation] + // .text:10020592 inc esi <- nop + // .text:10020593 push eax ; lpVersionInformation + // .text:10020594 mov [esp+154h+VersionInformation.dwOSVersionInfoSize], 11Ch + // .text:1002059C mov [edi], esi + // .text:1002059E call ds:__imp__GetVersionExW@4 ; GetVersionExW(x) + SignPtr = (PLATFORM_DWORD)(TermSrvBase + 0x20592); + b = 0x90; + #endif + WriteProcessMemory(GetCurrentProcess(), (LPVOID)SignPtr, &b, sizeof(b), &bw); + + WriteToLog("Patch CDefPolicy::Query\r\n"); + #ifdef _WIN64 + SignPtr = (PLATFORM_DWORD)(TermSrvBase + 0x1F206); + WriteProcessMemory(GetCurrentProcess(), (LPVOID)SignPtr, &CDefPolicy_Query_eax_rdi, sizeof(CDefPolicy_Query_eax_rdi), &bw); + #else + SignPtr = (PLATFORM_DWORD)(TermSrvBase + 0x1F408); + WriteProcessMemory(GetCurrentProcess(), (LPVOID)SignPtr, &CDefPolicy_Query_eax_esi, sizeof(CDefPolicy_Query_eax_esi), &bw); + #endif + + WriteToLog("Hook SLGetWindowsInformationDWORDWrapper\r\n"); + #ifdef _WIN64 + SignPtr = (PLATFORM_DWORD)(TermSrvBase + 0x24570); + Jump.MovOp = 0x48; + Jump.MovRegArg = 0xB8; + Jump.MovArg = (PLATFORM_DWORD)New_Win8SL; + Jump.PushRaxOp = 0x50; + Jump.RetOp = 0xC3; + #else + SignPtr = (PLATFORM_DWORD)(TermSrvBase + 0x17059); + Jump.PushOp = 0x68; + Jump.PushArg = (PLATFORM_DWORD)New_Win8SL; + Jump.RetOp = 0xC3; + #endif + WriteProcessMemory(GetCurrentProcess(), (LPVOID)SignPtr, &Jump, sizeof(FARJMP), &bw); + } + if (FV.Release == 9200 && FV.Build == 21166) + { + WriteToLog("Patch CSessionArbitrationHelper::IsSingleSessionPerUserEnabled\r\n"); + #ifdef _WIN64 + // .text:000000018002BAF2 lea rcx, [rsp+180h+VersionInformation] ; lpVersionInformation + // .text:000000018002BAF7 mov ebx, 1 <- 0 + // .text:000000018002BAFC mov [rsp+180h+VersionInformation.dwOSVersionInfoSize], 11Ch + // .text:000000018002BB04 mov [rdi], ebx + // .text:000000018002BB06 call cs:__imp_GetVersionExW + SignPtr = (PLATFORM_DWORD)(TermSrvBase + 0x2BAF8); + b = 0; + #else + // .text:10015576 lea eax, [esp+150h+VersionInformation] + // .text:1001557A inc esi <- nop + // .text:1001557B push eax ; lpVersionInformation + // .text:1001557C mov [esp+154h+VersionInformation.dwOSVersionInfoSize], 11Ch + // .text:10015584 mov [edi], esi + // .text:10015586 call ds:__imp__GetVersionExW@4 ; GetVersionExW(x) + SignPtr = (PLATFORM_DWORD)(TermSrvBase + 0x1557A); + b = 0x90; + #endif + WriteProcessMemory(GetCurrentProcess(), (LPVOID)SignPtr, &b, sizeof(b), &bw); + + WriteToLog("Patch CDefPolicy::Query\r\n"); + #ifdef _WIN64 + SignPtr = (PLATFORM_DWORD)(TermSrvBase + 0x2A3B6); + WriteProcessMemory(GetCurrentProcess(), (LPVOID)SignPtr, &CDefPolicy_Query_eax_rdi, sizeof(CDefPolicy_Query_eax_rdi), &bw); + #else + SignPtr = (PLATFORM_DWORD)(TermSrvBase + 0x13F30); + WriteProcessMemory(GetCurrentProcess(), (LPVOID)SignPtr, &CDefPolicy_Query_eax_esi, sizeof(CDefPolicy_Query_eax_esi), &bw); + #endif + + WriteToLog("Hook SLGetWindowsInformationDWORDWrapper\r\n"); + #ifdef _WIN64 + SignPtr = (PLATFORM_DWORD)(TermSrvBase + 0x21FD0); + Jump.MovOp = 0x48; + Jump.MovRegArg = 0xB8; + Jump.MovArg = (PLATFORM_DWORD)New_Win8SL; + Jump.PushRaxOp = 0x50; + Jump.RetOp = 0xC3; + #else + SignPtr = (PLATFORM_DWORD)(TermSrvBase + 0x19581); + Jump.PushOp = 0x68; + Jump.PushArg = (PLATFORM_DWORD)New_Win8SL; + Jump.RetOp = 0xC3; + #endif + WriteProcessMemory(GetCurrentProcess(), (LPVOID)SignPtr, &Jump, sizeof(FARJMP), &bw); + } + } + } + if (Ver == 0x0603) + { + // Windows 8.1 + // uses SL Policy internal inline code + + if (GetModuleCodeSectionInfo(hTermSrv, &TermSrvBase, &TermSrvSize)) + { + // Patch functions: + // CEnforcementCore::GetInstanceOfTSLicense + // CSessionArbitrationHelper::IsSingleSessionPerUserEnabled + // CDefPolicy::Query + // Hook function: + // CSLQuery::Initialize + + if (FV.Release == 9431 && FV.Build == 0) + { + WriteToLog("Patch CEnforcementCore::GetInstanceOfTSLicense\r\n"); + #ifdef _WIN64 + // .text:000000018009F713 call ?IsLicenseTypeLocalOnly@CSLQuery@@SAJAEAU_GUID@@PEAH@Z ; CSLQuery::IsLicenseTypeLocalOnly(_GUID &,int *) + // .text:000000018009F718 test eax, eax + // .text:000000018009F71A js short loc_18009F73B + // .text:000000018009F71C cmp [rsp+48h+arg_18], 0 + // .text:000000018009F721 jz short loc_18009F73B <- jmp + SignPtr = (PLATFORM_DWORD)(TermSrvBase + 0x9F721); + #else + // .text:1008A604 call ?IsLicenseTypeLocalOnly@CSLQuery@@SGJAAU_GUID@@PAH@Z ; CSLQuery::IsLicenseTypeLocalOnly(_GUID &,int *) + // .text:1008A609 test eax, eax + // .text:1008A60B js short loc_1008A628 + // .text:1008A60D cmp [ebp+var_8], 0 + // .text:1008A611 jz short loc_1008A628 <- jmp + SignPtr = (PLATFORM_DWORD)(TermSrvBase + 0x8A611); + #endif + b = 0xEB; + WriteProcessMemory(GetCurrentProcess(), (LPVOID)SignPtr, &b, sizeof(b), &bw); + + WriteToLog("Patch CSessionArbitrationHelper::IsSingleSessionPerUserEnabled\r\n"); + #ifdef _WIN64 + // .text:00000001800367F3 lea rcx, [rsp+190h+VersionInformation] ; lpVersionInformation + // .text:00000001800367F8 mov ebx, 1 <- 0 + // .text:00000001800367FD mov [rsp+190h+VersionInformation.dwOSVersionInfoSize], 11Ch + // .text:0000000180036805 mov [rdi], ebx + // .text:0000000180036807 call cs:__imp_GetVersionExW + SignPtr = (PLATFORM_DWORD)(TermSrvBase + 0x367F9); + b = 0; + #else + // .text:100306A4 lea eax, [esp+150h+VersionInformation] + // .text:100306A8 inc ebx <- nop + // .text:100306A9 mov [edi], ebx + // .text:100306AB push eax ; lpVersionInformation + // .text:100306AC call ds:__imp__GetVersionExW@4 ; GetVersionExW(x) + SignPtr = (PLATFORM_DWORD)(TermSrvBase + 0x306A8); + b = 0x90; + #endif + WriteProcessMemory(GetCurrentProcess(), (LPVOID)SignPtr, &b, sizeof(b), &bw); + + WriteToLog("Patch CDefPolicy::Query\r\n"); + #ifdef _WIN64 + SignPtr = (PLATFORM_DWORD)(TermSrvBase + 0x350FD); + WriteProcessMemory(GetCurrentProcess(), (LPVOID)SignPtr, &CDefPolicy_Query_eax_rcx, sizeof(CDefPolicy_Query_eax_rcx), &bw); + #else + SignPtr = (PLATFORM_DWORD)(TermSrvBase + 0x2EA25); + WriteProcessMemory(GetCurrentProcess(), (LPVOID)SignPtr, &CDefPolicy_Query_eax_ecx, sizeof(CDefPolicy_Query_eax_ecx), &bw); + #endif + + WriteToLog("Hook CSLQuery::Initialize\r\n"); + #ifdef _WIN64 + SignPtr = (PLATFORM_DWORD)(TermSrvBase + 0x2F9C0); + Jump.MovOp = 0x48; + Jump.MovRegArg = 0xB8; + Jump.MovArg = (PLATFORM_DWORD)New_CSLQuery_Initialize; + Jump.PushRaxOp = 0x50; + Jump.RetOp = 0xC3; + #else + SignPtr = (PLATFORM_DWORD)(TermSrvBase + 0x196B0); + Jump.PushOp = 0x68; + Jump.PushArg = (PLATFORM_DWORD)New_CSLQuery_Initialize; + Jump.RetOp = 0xC3; + #endif + WriteProcessMemory(GetCurrentProcess(), (LPVOID)SignPtr, &Jump, sizeof(FARJMP), &bw); + } + if (FV.Release == 9600 && FV.Build == 16384) + { + WriteToLog("Patch CEnforcementCore::GetInstanceOfTSLicense\r\n"); + #ifdef _WIN64 + // .text:000000018008181F cmp [rsp+48h+arg_18], 0 + // .text:0000000180081824 jz loc_180031DEF <- nop + jmp + SignPtr = (PLATFORM_DWORD)(TermSrvBase + 0x81824); + b = 0x90; + WriteProcessMemory(GetCurrentProcess(), (LPVOID)SignPtr, &b, sizeof(b), &bw); + SignPtr = (PLATFORM_DWORD)(TermSrvBase + 0x81825); + b = 0xE9; + WriteProcessMemory(GetCurrentProcess(), (LPVOID)SignPtr, &b, sizeof(b), &bw); + #else + // .text:100A271C call ?IsLicenseTypeLocalOnly@CSLQuery@@SGJAAU_GUID@@PAH@Z ; CSLQuery::IsLicenseTypeLocalOnly(_GUID &,int *) + // .text:100A2721 test eax, eax + // .text:100A2723 js short loc_100A2740 + // .text:100A2725 cmp [ebp+var_8], 0 + // .text:100A2729 jz short loc_100A2740 <- jmp + SignPtr = (PLATFORM_DWORD)(TermSrvBase + 0xA2729); + b = 0xEB; + WriteProcessMemory(GetCurrentProcess(), (LPVOID)SignPtr, &b, sizeof(b), &bw); + #endif + + WriteToLog("Patch CSessionArbitrationHelper::IsSingleSessionPerUserEnabled\r\n"); + #ifdef _WIN64 + // .text:000000018002023B lea rcx, [rsp+190h+VersionInformation] ; lpVersionInformation + // .text:0000000180020240 mov ebx, 1 <- 0 + // .text:0000000180020245 mov [rsp+190h+VersionInformation.dwOSVersionInfoSize], 11Ch + // .text:000000018002024D mov [rdi], ebx + // .text:000000018002024F call cs:__imp_GetVersionExW + SignPtr = (PLATFORM_DWORD)(TermSrvBase + 0x20241); + b = 0; + #else + // .text:10018024 lea eax, [esp+150h+VersionInformation] + // .text:10018028 inc ebx <- nop + // .text:10018029 mov [edi], ebx + // .text:1001802B push eax ; lpVersionInformation + // .text:1001802C call ds:__imp__GetVersionExW@4 ; GetVersionExW(x) + SignPtr = (PLATFORM_DWORD)(TermSrvBase + 0x18028); + b = 0x90; + #endif + WriteProcessMemory(GetCurrentProcess(), (LPVOID)SignPtr, &b, sizeof(b), &bw); + + WriteToLog("Patch CDefPolicy::Query\r\n"); + #ifdef _WIN64 + SignPtr = (PLATFORM_DWORD)(TermSrvBase + 0x57829); + WriteProcessMemory(GetCurrentProcess(), (LPVOID)SignPtr, &CDefPolicy_Query_eax_rcx, sizeof(CDefPolicy_Query_eax_rcx), &bw); + #else + SignPtr = (PLATFORM_DWORD)(TermSrvBase + 0x16115); + WriteProcessMemory(GetCurrentProcess(), (LPVOID)SignPtr, &CDefPolicy_Query_eax_ecx, sizeof(CDefPolicy_Query_eax_ecx), &bw); + #endif + + WriteToLog("Hook CSLQuery::Initialize\r\n"); + #ifdef _WIN64 + SignPtr = (PLATFORM_DWORD)(TermSrvBase + 0x554C0); + Jump.MovOp = 0x48; + Jump.MovRegArg = 0xB8; + Jump.MovArg = (PLATFORM_DWORD)New_CSLQuery_Initialize; + Jump.PushRaxOp = 0x50; + Jump.RetOp = 0xC3; + #else + SignPtr = (PLATFORM_DWORD)(TermSrvBase + 0x1CEB0); + Jump.PushOp = 0x68; + Jump.PushArg = (PLATFORM_DWORD)New_CSLQuery_Initialize; + Jump.RetOp = 0xC3; + #endif + WriteProcessMemory(GetCurrentProcess(), (LPVOID)SignPtr, &Jump, sizeof(FARJMP), &bw); + } + if (FV.Release == 9600 && FV.Build == 17095) + { + WriteToLog("Patch CEnforcementCore::GetInstanceOfTSLicense\r\n"); + #ifdef _WIN64 + // .text:00000001800B914B call ?IsLicenseTypeLocalOnly@CSLQuery@@SAJAEAU_GUID@@PEAH@Z ; CSLQuery::IsLicenseTypeLocalOnly(_GUID &,int *) + // .text:00000001800B9150 test eax, eax + // .text:00000001800B9152 js short loc_1800B9173 + // .text:00000001800B9154 cmp [rsp+48h+arg_18], 0 + // .text:00000001800B9159 jz short loc_1800B9173 <- jmp + SignPtr = (PLATFORM_DWORD)(TermSrvBase + 0xB9159); + #else + // .text:100A36C4 call ?IsLicenseTypeLocalOnly@CSLQuery@@SGJAAU_GUID@@PAH@Z ; CSLQuery::IsLicenseTypeLocalOnly(_GUID &,int *) + // .text:100A36C9 test eax, eax + // .text:100A36CB js short loc_100A36E8 + // .text:100A36CD cmp [ebp+var_8], 0 + // .text:100A36D1 jz short loc_100A36E8 <- jmp + SignPtr = (PLATFORM_DWORD)(TermSrvBase + 0xA36D1); + #endif + b = 0xEB; + WriteProcessMemory(GetCurrentProcess(), (LPVOID)SignPtr, &b, sizeof(b), &bw); + + WriteToLog("Patch CSessionArbitrationHelper::IsSingleSessionPerUserEnabled\r\n"); + #ifdef _WIN64 + // .text:0000000180021823 lea rcx, [rsp+190h+VersionInformation] ; lpVersionInformation + // .text:0000000180021828 mov ebx, 1 <- 0 + // .text:000000018002182D mov [rsp+190h+VersionInformation.dwOSVersionInfoSize], 11Ch + // .text:0000000180021835 mov [rdi], ebx + // .text:0000000180021837 call cs:__imp_GetVersionExW + SignPtr = (PLATFORM_DWORD)(TermSrvBase + 0x21829); + b = 0; + #else + // .text:10036BA5 lea eax, [esp+150h+VersionInformation] + // .text:10036BA9 inc ebx <- nop + // .text:10036BAA mov [edi], ebx + // .text:10036BAC push eax ; lpVersionInformation + // .text:10036BAD call ds:__imp__GetVersionExW@4 ; GetVersionExW(x) + SignPtr = (PLATFORM_DWORD)(TermSrvBase + 0x36BA9); + b = 0x90; + #endif + WriteProcessMemory(GetCurrentProcess(), (LPVOID)SignPtr, &b, sizeof(b), &bw); + + WriteToLog("Patch CDefPolicy::Query\r\n"); + #ifdef _WIN64 + SignPtr = (PLATFORM_DWORD)(TermSrvBase + 0x1F6A1); + WriteProcessMemory(GetCurrentProcess(), (LPVOID)SignPtr, &CDefPolicy_Query_eax_rcx, sizeof(CDefPolicy_Query_eax_rcx), &bw); + #else + SignPtr = (PLATFORM_DWORD)(TermSrvBase + 0x16115); + WriteProcessMemory(GetCurrentProcess(), (LPVOID)SignPtr, &CDefPolicy_Query_eax_ecx, sizeof(CDefPolicy_Query_eax_ecx), &bw); + #endif + + WriteToLog("Hook CSLQuery::Initialize\r\n"); + #ifdef _WIN64 + SignPtr = (PLATFORM_DWORD)(TermSrvBase + 0x3B110); + Jump.MovOp = 0x48; + Jump.MovRegArg = 0xB8; + Jump.MovArg = (PLATFORM_DWORD)New_CSLQuery_Initialize; + Jump.PushRaxOp = 0x50; + Jump.RetOp = 0xC3; + #else + SignPtr = (PLATFORM_DWORD)(TermSrvBase + 0x117F1); + Jump.PushOp = 0x68; + Jump.PushArg = (PLATFORM_DWORD)New_CSLQuery_Initialize; + Jump.RetOp = 0xC3; + #endif + WriteProcessMemory(GetCurrentProcess(), (LPVOID)SignPtr, &Jump, sizeof(FARJMP), &bw); + } + } + } + if (Ver == 0x0604) + { + // Windows 10 + // uses SL Policy internal inline code + + if (GetModuleCodeSectionInfo(hTermSrv, &TermSrvBase, &TermSrvSize)) + { + // Patch functions: + // CEnforcementCore::GetInstanceOfTSLicense + // CSessionArbitrationHelper::IsSingleSessionPerUserEnabled + // CDefPolicy::Query + // Hook function: + // CSLQuery::Initialize + + if (FV.Release == 9841 && FV.Build == 0) + { + WriteToLog("Patch CEnforcementCore::GetInstanceOfTSLicense\r\n"); + #ifdef _WIN64 + // .text:0000000180081133 call sub_1800A9048 + // .text:0000000180081138 test eax, eax + // .text:000000018008113A js short loc_18008115B + // .text:000000018008113C cmp [rsp+58h+arg_18], 0 + // .text:0000000180081141 jz short loc_18008115B <- jmp + SignPtr = (PLATFORM_DWORD)(TermSrvBase + 0x81141); + #else + // .text:1009569B call sub_100B7EE5 + // .text:100956A0 test eax, eax + // .text:100956A2 js short loc_100956BF + // .text:100956A4 cmp [ebp+var_C], 0 + // .text:100956A8 jz short loc_100956BF <- jmp + SignPtr = (PLATFORM_DWORD)(TermSrvBase + 0x956A8); + #endif + b = 0xEB; + WriteProcessMemory(GetCurrentProcess(), (LPVOID)SignPtr, &b, sizeof(b), &bw); + + WriteToLog("Patch CSessionArbitrationHelper::IsSingleSessionPerUserEnabled\r\n"); + #ifdef _WIN64 + // .text:0000000180012153 lea rcx, [rsp+190h+VersionInformation] ; lpVersionInformation + // .text:0000000180012158 mov ebx, 1 <- 0 + // .text:000000018001215D mov [rsp+190h+VersionInformation.dwOSVersionInfoSize], 11Ch + // .text:0000000180012165 mov [rdi], ebx + // .text:0000000180012167 call cs:GetVersionExW + SignPtr = (PLATFORM_DWORD)(TermSrvBase + 0x12159); + b = 0; + #else + // .text:10030121 lea eax, [esp+150h+VersionInformation] + // .text:10030125 inc ebx <- nop + // .text:10030126 mov [edi], ebx + // .text:10030128 push eax ; lpVersionInformation + // .text:10030129 call ds:GetVersionExW + SignPtr = (PLATFORM_DWORD)(TermSrvBase + 0x30125); + b = 0x90; + #endif + WriteProcessMemory(GetCurrentProcess(), (LPVOID)SignPtr, &b, sizeof(b), &bw); + + WriteToLog("Patch CDefPolicy::Query\r\n"); + #ifdef _WIN64 + SignPtr = (PLATFORM_DWORD)(TermSrvBase + 0xC125); + WriteProcessMemory(GetCurrentProcess(), (LPVOID)SignPtr, &CDefPolicy_Query_eax_rcx, sizeof(CDefPolicy_Query_eax_rcx), &bw); + #else + SignPtr = (PLATFORM_DWORD)(TermSrvBase + 0x3B989); + WriteProcessMemory(GetCurrentProcess(), (LPVOID)SignPtr, &CDefPolicy_Query_eax_ecx, sizeof(CDefPolicy_Query_eax_ecx), &bw); + #endif + + WriteToLog("Hook CSLQuery::Initialize\r\n"); + #ifdef _WIN64 + SignPtr = (PLATFORM_DWORD)(TermSrvBase + 0x1EA50); + Jump.MovOp = 0x48; + Jump.MovRegArg = 0xB8; + Jump.MovArg = (PLATFORM_DWORD)New_CSLQuery_Initialize; + Jump.PushRaxOp = 0x50; + Jump.RetOp = 0xC3; + #else + SignPtr = (PLATFORM_DWORD)(TermSrvBase + 0x46A68); + Jump.PushOp = 0x68; + Jump.PushArg = (PLATFORM_DWORD)New_CSLQuery_Initialize; + Jump.RetOp = 0xC3; + #endif + WriteProcessMemory(GetCurrentProcess(), (LPVOID)SignPtr, &Jump, sizeof(FARJMP), &bw); + } + } + } + WriteToLog("resume\r\n"); + SetThreadsState(true); + return; +} + +void WINAPI ServiceMain(DWORD dwArgc, LPTSTR *lpszArgv) +{ + WriteToLog("> ServiceMain\r\n"); + if (!AlreadyHooked) Hook(); + + if (_ServiceMain != NULL) _ServiceMain(dwArgc, lpszArgv); +} + +void WINAPI SvchostPushServiceGlobals(void *lpGlobalData) +{ + WriteToLog("> SvchostPushServiceGlobals\r\n"); + if (!AlreadyHooked) Hook(); + + if (_SvchostPushServiceGlobals != NULL) _SvchostPushServiceGlobals(lpGlobalData); +} \ No newline at end of file diff --git a/src-x86-x64-Fusix/src/RDPWrap.sln b/src-x86-x64-Fusix/src/RDPWrap.sln new file mode 100644 index 0000000..78a9f56 --- /dev/null +++ b/src-x86-x64-Fusix/src/RDPWrap.sln @@ -0,0 +1,30 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio 2012 +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "RDPWrap", "RDPWrap.vcxproj", "{29E4E73B-EBA6-495B-A76C-FBB462196C64}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Win32 = Debug|Win32 + Debug|x64 = Debug|x64 + Release|Win32 = Release|Win32 + Release|x64 = Release|x64 + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {29E4E73B-EBA6-495B-A76C-FBB462196C64}.Debug|Win32.ActiveCfg = Debug|Win32 + {29E4E73B-EBA6-495B-A76C-FBB462196C64}.Debug|Win32.Build.0 = Debug|Win32 + {29E4E73B-EBA6-495B-A76C-FBB462196C64}.Debug|Win32.Deploy.0 = Debug|Win32 + {29E4E73B-EBA6-495B-A76C-FBB462196C64}.Debug|x64.ActiveCfg = Debug|x64 + {29E4E73B-EBA6-495B-A76C-FBB462196C64}.Debug|x64.Build.0 = Debug|x64 + {29E4E73B-EBA6-495B-A76C-FBB462196C64}.Debug|x64.Deploy.0 = Debug|x64 + {29E4E73B-EBA6-495B-A76C-FBB462196C64}.Release|Win32.ActiveCfg = Release|Win32 + {29E4E73B-EBA6-495B-A76C-FBB462196C64}.Release|Win32.Build.0 = Release|Win32 + {29E4E73B-EBA6-495B-A76C-FBB462196C64}.Release|Win32.Deploy.0 = Release|Win32 + {29E4E73B-EBA6-495B-A76C-FBB462196C64}.Release|x64.ActiveCfg = Release|x64 + {29E4E73B-EBA6-495B-A76C-FBB462196C64}.Release|x64.Build.0 = Release|x64 + {29E4E73B-EBA6-495B-A76C-FBB462196C64}.Release|x64.Deploy.0 = Release|x64 + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection +EndGlobal diff --git a/src-x86-x64-Fusix/src/RDPWrap.v11.suo b/src-x86-x64-Fusix/src/RDPWrap.v11.suo new file mode 100644 index 0000000..ea1220b Binary files /dev/null and b/src-x86-x64-Fusix/src/RDPWrap.v11.suo differ diff --git a/src-x86-x64-Fusix/src/RDPWrap.vcxproj b/src-x86-x64-Fusix/src/RDPWrap.vcxproj new file mode 100644 index 0000000..e7589ec --- /dev/null +++ b/src-x86-x64-Fusix/src/RDPWrap.vcxproj @@ -0,0 +1,195 @@ + + + + + Debug + Win32 + + + Debug + x64 + + + Release + Win32 + + + Release + x64 + + + + {29E4E73B-EBA6-495B-A76C-FBB462196C64} + Win32Proj + RDPWrap + + + + DynamicLibrary + true + v110 + Unicode + + + DynamicLibrary + true + v110 + Unicode + + + DynamicLibrary + false + v110 + true + Unicode + + + DynamicLibrary + false + v110 + true + Unicode + + + + + + + + + + + + + + + + + + + true + + + true + + + false + + + false + + + + Use + Level3 + Disabled + WIN32;_DEBUG;_WINDOWS;_USRDLL;RDPWRAP_EXPORTS;%(PreprocessorDefinitions) + true + + + Windows + true + Export.def + + + + + Use + Level3 + Disabled + WIN32;_DEBUG;_WINDOWS;_USRDLL;RDPWRAP_EXPORTS;%(PreprocessorDefinitions) + true + + + Windows + true + Export.def + + + + + Use + MaxSpeed + true + true + WIN32;NDEBUG;_WINDOWS;_USRDLL;RDPWRAP_EXPORTS;%(PreprocessorDefinitions) + true + true + Level3 + 1Byte + MultiThreaded + + + Windows + false + true + true + Export.def + + + false + true + + + + + Use + MaxSpeed + true + true + WIN32;NDEBUG;_WINDOWS;_USRDLL;RDPWRAP_EXPORTS;%(PreprocessorDefinitions) + true + true + Level3 + 1Byte + MultiThreaded + + + Windows + false + true + true + Export.def + + + false + true + + + + + + + + + + + + false + false + + + + + false + false + + + + + + + + Create + Create + Create + Create + + + + + + + + + \ No newline at end of file diff --git a/src-x86-x64-Fusix/src/RDPWrap.vcxproj.filters b/src-x86-x64-Fusix/src/RDPWrap.vcxproj.filters new file mode 100644 index 0000000..b394450 --- /dev/null +++ b/src-x86-x64-Fusix/src/RDPWrap.vcxproj.filters @@ -0,0 +1,44 @@ + + + + + {4FC737F1-C7A5-4376-A066-2A32D752A2FF} + cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx + + + {93995380-89BD-4b04-88EB-625FBE52EBFB} + h;hpp;hxx;hm;inl;inc;xsd + + + {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} + rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms + + + + + + + + Заголовочные файлы + + + Заголовочные файлы + + + + + Файлы исходного кода + + + Файлы исходного кода + + + Файлы исходного кода + + + + + Файлы исходного кода + + + \ No newline at end of file diff --git a/src-x86-x64-Fusix/src/ReadMe.txt b/src-x86-x64-Fusix/src/ReadMe.txt new file mode 100644 index 0000000..b2aa21f --- /dev/null +++ b/src-x86-x64-Fusix/src/ReadMe.txt @@ -0,0 +1,32 @@ +======================================================================== + БИБЛИОТЕКА ДИНАМИЧЕСКОЙ КОМПОНОВКИ. Обзор проекта RDPWrap +======================================================================== + +Эта библиотека DLL RDPWrap создана автоматически с помощью мастера приложений. + +В этом файле представлена сводка содержимого всех файлов, входящих в состав приложения RDPWrap. + + +RDPWrap.vcxproj + Это основной файл проекта VC++, создаваемый с помощью мастера приложений. Он содержит данные о версии языка Visual C++, использованной для создания файла, а также сведения о платформах, конфигурациях и функциях проекта, выбранных с помощью мастера приложений. + +RDPWrap.vcxproj.filters + Это файл фильтров для проектов VC++, созданный с помощью мастера приложений. Он содержит сведения о сопоставлениях между файлами в вашем проекте и фильтрами. Эти сопоставления используются в среде IDE для группировки файлов с одинаковыми расширениями в одном узле (например CPP-файлы сопоставляются с фильтром "Исходные файлы"). + +RDPWrap.cpp + Основной исходный файл библиотеки DLL. + + При создании этой библиотеки DLL не выполняется экспорт символов. Поэтому при ее построении не создается LIB-файл. Если в этом проекте требуется определить зависимость от другого проекта, необходимо добавить код для экспорта символов из библиотеки DLL, чтобы обеспечить создание библиотеки экспорта, или задать значение «Да» для свойства «Пропустить входную библиотеку» на странице общих свойств папки «Компоновщик» в диалоговом окне «Страницы свойств» проекта. + +///////////////////////////////////////////////////////////////////////////// +Другие стандартные файлы: + +StdAfx.h, StdAfx.cpp + Эти файлы используются для построения файла предкомпилированного заголовка (PCH) с именем RDPWrap.pch и файла предкомпилированных типов с именем StdAfx.obj. + +///////////////////////////////////////////////////////////////////////////// +Прочие примечания. + +С помощью комментариев «TODO:» в мастере приложений обозначаются фрагменты исходного кода, которые необходимо дополнить или изменить. + +///////////////////////////////////////////////////////////////////////////// diff --git a/src-x86-x64-Fusix/src/dllmain.cpp b/src-x86-x64-Fusix/src/dllmain.cpp new file mode 100644 index 0000000..38bf29e --- /dev/null +++ b/src-x86-x64-Fusix/src/dllmain.cpp @@ -0,0 +1,11 @@ +// dllmain.cpp: DLL. +#include "stdafx.h" + +BOOL APIENTRY DllMain( HMODULE hModule, + DWORD ul_reason_for_call, + LPVOID lpReserved + ) +{ + return true; +} + diff --git a/src-x86-x64-Fusix/src/stdafx.cpp b/src-x86-x64-Fusix/src/stdafx.cpp new file mode 100644 index 0000000..33d4909 --- /dev/null +++ b/src-x86-x64-Fusix/src/stdafx.cpp @@ -0,0 +1,8 @@ +// stdafx.cpp: , +// RDPWrap.pch +// stdafx.obj + +#include "stdafx.h" + +// TODO: STDAFX.H +// , diff --git a/src-x86-x64-Fusix/src/stdafx.h b/src-x86-x64-Fusix/src/stdafx.h new file mode 100644 index 0000000..1f8c5cf --- /dev/null +++ b/src-x86-x64-Fusix/src/stdafx.h @@ -0,0 +1,23 @@ +// stdafx.h: +// , , +// +// + +#pragma once + +#include "targetver.h" + +#define WIN32_LEAN_AND_MEAN // Windows +#define _CRT_SECURE_NO_WARNINGS + + +// Windows: +#include +#include + + +// TODO: , + +typedef VOID (WINAPI* SERVICEMAIN)(DWORD, LPTSTR*); +typedef VOID (WINAPI* SVCHOSTPUSHSERVICEGLOBALS)(VOID*); +typedef HRESULT (WINAPI* SLGETWINDOWSINFORMATIONDWORD)(PCWSTR, DWORD*); \ No newline at end of file diff --git a/src-x86-x64-Fusix/src/targetver.h b/src-x86-x64-Fusix/src/targetver.h new file mode 100644 index 0000000..3faa2ab --- /dev/null +++ b/src-x86-x64-Fusix/src/targetver.h @@ -0,0 +1,8 @@ +#pragma once + +// SDKDDKVer.h Windows. + +// Windows, WinSDKVer.h +// _WIN32_WINNT SDKDDKVer.h. + +#include diff --git a/src-x86-x64-Fusix/src/version.bin b/src-x86-x64-Fusix/src/version.bin new file mode 100644 index 0000000..184c65d Binary files /dev/null and b/src-x86-x64-Fusix/src/version.bin differ