[DISCUSSION] Windows 11 termsrv.dll Patching

Discussion in 'Windows 11' started by Smile2020, Jul 12, 2021.

  1. Smile2020

    Smile2020 MDL Novice

    Mar 11, 2020
    9
    4
    0
    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
     
  2. richwood

    richwood MDL Novice

    Nov 16, 2013
    39
    29
    0

    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.

    upload_2021-7-15_12-21-53.png
     
  3. Smile2020

    Smile2020 MDL Novice

    Mar 11, 2020
    9
    4
    0

    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
     
  4. PYOUMANS

    PYOUMANS MDL Novice

    Jan 22, 2016
    3
    3
    0
    #4 PYOUMANS, Oct 9, 2021
    Last edited: Jul 26, 2024
    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.
     
  5. Jans

    Jans MDL Novice

    Oct 17, 2009
    20
    2
    0
    #5 Jans, Oct 15, 2021
    Last edited: Oct 16, 2021
    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.
     
  6. mohdubai

    mohdubai MDL Novice

    Nov 18, 2011
    4
    1
    0
    #6 mohdubai, May 23, 2022
    Last edited: May 26, 2022


    Patch for new version: 10.0.22000.708 please...
     
  7. vali20

    vali20 MDL Member

    Aug 8, 2012
    126
    64
    10
    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
    
     
  8. My Digital Life Is Analog

    Oct 30, 2021
    10
    3
    0
    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?
     
  9. My Digital Life Is Analog

    Oct 30, 2021
    10
    3
    0
    Does anyone have a hex value for termsrv.dll version 10.0.22000.708 or 10.0.22000.795?
     
  10. My Digital Life Is Analog

    Oct 30, 2021
    10
    3
    0
    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
     
  11. PERSoft

    PERSoft MDL Novice

    Jun 20, 2010
    23
    17
    0
    #13 PERSoft, Oct 3, 2022
    Last edited: Oct 3, 2022
    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
     
  12. PERSoft

    PERSoft MDL Novice

    Jun 20, 2010
    23
    17
    0
    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
     
  13. PERSoft

    PERSoft MDL Novice

    Jun 20, 2010
    23
    17
    0
    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
     
  14. PERSoft

    PERSoft MDL Novice

    Jun 20, 2010
    23
    17
    0
    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
     
  15. SiGi78

    SiGi78 MDL Novice

    Mar 10, 2021
    1
    0
    0
    Hi there. Did anyone figured out hex code for file version 10.0.22621.1928

    Thx
     
  16. pm67310

    pm67310 MDL Guru

    Sep 6, 2011
    3,635
    2,878
    120
    check on github of rdwrap..
     
    Stop hovering to collapse... Click to collapse... Hover to expand... Click to expand...
  17. shweew

    shweew MDL Novice

    Nov 21, 2009
    5
    3
    0
    #20 shweew, Jan 26, 2024
    Last edited: Jan 27, 2024
    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