Hello, I know it is early but is there a way to patch termsrv for Win 11, 22000.51? The patch for 21H1 did not work. thank you
Use task manager to disable 'UmRdpService' and 'TermService' Download the latest rdpwrap.ini file from Github. I cannot post links but Search for sebaxakerhtc/rdpwrap.ini Copy the ini file into C:\Program Files\RDP Wrapper and overwrite the existing file. Go to your RDPWrap-v1.6.2 folder and click 'install.bat' Enable UmRdpService' and 'TermService' Run 'RDPConf.exe' from your RDPWrap-v1.6.2 folder and confirm all installed, running and supported.
Thank you for your answer... it shows me all green and ok, (22000.75 Version Education), but it works only for one connection. Can you reproduce this? Thanks
File version 10.0.22621.3958 find: 39813C0600000F842FB00100 B8 00 01 00 00 89 81 38 06 00 00 90 I edit this when Microsoft changes the file.
RDP Wrapper seems to work partly in Win11 22000.258 After installing RDP Wrapper, RDPConf.exe says Wrapper state: installed Service State: running Listener State: running ver. 10.0.22000.1: [fully supported] However, after a reboot of Win11, Service Starts and Stops within a few seconds. EventLog: Application Error EventID 1000 Faulting application name: svchost.exe_TermService, version: 10.0.22000.1, time stamp: 0x5155ab18 Faulting module name: rdpwrap.dll, version: 1.5.0.0, time stamp: 0x5488aa5a After uninstall and reïnstall RDP Wrapper, same happens again.
I don't know if it's been explained anywhere already, but these patches are easier to do when you understand what is actually going on with them. Looking on the 22000.653 patch, it looks for this pattern: Code: 39 81 3C 06 00 00 0F 84 B9 6C 01 00 Having the `termsrv.dll` file open in IDA, we can search for that and it will take us into this method: `CDefPolicy::Query`. The bytes correspond to these 2 instructions: Code: .text:000000018001BA15 cmp [rcx+63Ch], eax .text:000000018001BA1B jz loc_1800326DA In pseudocode, it looks like this: Code: __int64 __fastcall CDefPolicy::Query(CDefPolicy *this, int *a2) { unsigned int v2; // r8d v2 = 0; *a2 = *((_DWORD *)this + 401); if ( *((_DWORD *)this + 399) == *((_DWORD *)this + 398) ) { _DbgPrintMessage(8, "CDefPolicy::Query FAILED - License not available", 0i64); return (unsigned int)-804650989; } return v2; } The comparison in the `if` statement roughly corresponds to those 2 lines of assembly, or the pattern that we are replacing. The patch takes that out and replaces it with this: Code: B8 00 01 00 00 89 81 38 06 00 00 90 This, as assembly, corresponds to this: Code: .text:000000018001BA15 mov eax, 100h .text:000000018001BA1A mov [rcx+638h], eax .text:000000018001BA20 nop Which as pseudocode is this: Code: __int64 __fastcall CDefPolicy::Query(CDefPolicy *this, int *a2) { *a2 = *((_DWORD *)this + 401); *((_DWORD *)this + 398) = 256; return 0i64; } So, instead of checking `*((_DWORD *)this + 398)` against `*((_DWORD *)this + 399)` and seeing that they are equal in our (unlicensed) case (probably), we instead set `*((_DWORD *)this + 398)` to 256. What is `*((_DWORD *)this + 398)`? I don't know, it probably is some variable (bitmask? 9th bit set) which tells whether this feature is licensed, I think (I haven't studied more in depth how this works). Okay, so what broke for 22000.706? First of all, let's open the new DLL in IDA as well. Unfortunately, symbols for this build are not available, so we cannot easily locate the `CDefPolicy::Query` method, because none of the methods have any meaningful name (they're all `sub...` because IDA can't name them without symbols). Fortunately for us, it is VERY easy to identify that method because we know, from the previous DLL, that originally, when we failed the check, some message is printed ("CDefPolicy::Query FAILED - License not available"). If you search for that (Alt+T), then Ctrl+X on the name to see where it is refereed, choose the single match, Ctrl+X again, choose the single match again, we identify the method (it's called `sub_18001BA00` in this version of the DLL). You can press F5 to view the decompiled code. If you look on the disassembly, it looks similar to the old one, so what changed. Well, the pattern we are trying to match contains a jump, and the respective jump is relative to the current instruction. What happened is that the offset between the current instruction and where we jump has been modified between the old and the new version. That is VERY likely to happen when slightly changed code is recompiled, it's usually the duty of the compiler to automatically layout the code in memory according to criteria like execution speed, space taken etc. The programmer usually establishes such criteria and then lets the compiler decide how it's best to layout the program in order to fulfill these high level requirements, thus, the actual result can vary drastically even for slight changes code wise. Okay, so how do we go about it? Well, same as before. We can observe that it's enough to match only the first instruction (the `cmp` one: `39 81 3C 06 00 00 0F`). This still produces only a single result on the whole file, which is exactly what we are looking for (fortunately, the members of the struct/object we are working with are located at the same places in the struct/object). From the beginning of the match, we still replace by the same pattern as before (`B8 00 01 00 00 89 81 38 06 00 00 90`), overriding whatever was written in the next instruction, that `jmp`. How to identify this in the future? First step is to search for that string and identify that `CDefPolicy::Query` method, I'd say. Then, in there, try to replace the if check with setting either of the operands to 256 and see if it works, that seems to be the idea behind this patch. TL;DR Code: File version 10.0.22000.706 find: 39 81 3C 06 00 00 0F replace: B8 00 01 00 00 89 81 38 06 00 00 90
I'm unable to get this to work on Windows 11 -- Microsoft Windows [Version 10.0.22000.739]. Does anyone have a confirmed hex value that works for multi user support with the termsrv.dll on Windows 11 at this build?
Thank you for the effort, but I'm looking for hex values to patch it myself for security reasons. Specifically for the hex value to allow multi user RDP for Windows 11 with termsrv.dll version 10.0.22000.708
File version 10.0.22621.1 find: 39 81 3C 06 00 00 0F 84 75 7A 01 00 replace : B8 00 01 00 00 89 81 38 06 00 00 90 10.0.22000.1042 find: 39 81 3C 06 00 00 0F 84 79 6A 01 00 replace B8 00 01 00 00 89 81 38 06 00 00 90
Fileversion 10.0.22621.608 39 81 3C 06 00 00 0F 84 75 7A 01 00 replace B8 00 01 00 00 89 81 38 06 00 00 90
Windows 11 termsrv.dll Fileversion 10.0.22000.1641 find 39 81 3C 06 00 00 0F 84 0B 6F 01 00 replace B8 00 01 00 00 89 81 38 06 00 00 90
Windows 11 termsrv.dll Fileversion 10.0.22621.1778A find 39 81 3C 06 00 00 0F 84 E5 7B 01 00 replace B8 00 01 00 00 89 81 38 06 00 00 90
termsrv.dll 10.0.22621.3085 =============================== Search: 39 81 3C 06 00 00 0F 84 6F 8C 01 00 Replace: B8 00 01 00 00 89 81 38 06 00 00 90