llccd / RDPWrapOffsetFinder

Automatically find rdpwrap offsets
83 stars 8 forks source link

Single sessions per user do not follow the registry #10

Closed loyejaotdiqr47123 closed 1 month ago

loyejaotdiqr47123 commented 5 months ago

See https://github.com/sebaxakerhtc/rdpwrap.ini/issues/380 and https://github.com/stascorp/rdpwrap/issues/2590

llccd commented 5 months ago

After the patch, single session per user is always turned off for client edition, and the option in GUI does not work. To make this option work, we need to introduce new patchcodes and change SingleUserOffset.

New session created every time is actually a bug in winlogon, and it can be workarounded by disabling the lockscreen: setting registry HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Winlogon\DisableLockWorkstation to DWORD 1. Also, user can disable the SingleUser patch by setting SingleUserPatch.x86/x64 to 0.

loyejaotdiqr47123 commented 4 months ago

That means no new patchcodes have been found yet?

adream100 commented 4 months ago

It's an interesting question, why does it happen to someone and not me? Is it related to the version of Windows 10? I tested Enterprise, Professional, and Workstation versions, 10.0.19041.4474, without this problem.

llccd commented 4 months ago

The following SingleUser patch strategy should work as expected:

search for call VerifyVersionInfoW in the IsSingleSessionPerUser function, replace it with mov eax, 1

For older versions which use GetVersionExW, search for cmp [rbp(rsp)+XXXh+var_XX], 1, replace it with nop

see: https://github.com/llccd/TermWrap/blob/v0.2/TermWrap/Patch.cpp#L321 examples:

[PatchCodes]
nop_3=909090
nop_7=90909090909090
mov_eax_1_nop_1=B80100000090
mov_eax_1_nop_2=B8010000009090

[6.1.7601.17514]
SingleUserPatch.x64=1
SingleUserOffset.x64=180FC
SingleUserCode.x64=nop_7

[6.2.9200.16384]
SingleUserPatch.x64=1
SingleUserOffset.x64=2BAC2
SingleUserCode.x64=nop_3

[10.0.14393.0]
SingleUserPatch.x64=1
SingleUserOffset.x64=299C3
SingleUserCode.x64=nop_3

[10.0.17134.1]
SingleUserPatch.x64=1
SingleUserOffset.x64=3181A
SingleUserCode.x64=mov_eax_1_nop_1

[10.0.17763.1]
SingleUserPatch.x64=1
SingleUserOffset.x64=C5E6
SingleUserCode.x64=mov_eax_1_nop_1

[10.0.22000.1]
SingleUserPatch.x64=1
SingleUserOffset.x64=16CEF
SingleUserCode.x64=mov_eax_1_nop_2

[10.0.26100.1]
SingleUserPatch.x64=1
SingleUserOffset.x64=9764B
SingleUserCode.x64=mov_eax_1_nop_2
loyejaotdiqr47123 commented 4 months ago

@llccd When can RDPWrapOffsetFinder support searching for these new patch codes?

llccd commented 4 months ago

Searching for new patchcodes is now implemented in release v0.6 For x86, it uses different patchcodes

nop_4=90909090
pop_eax_add_esp_12_nop_2=5883C40C9090
loyejaotdiqr47123 commented 4 months ago

See https://github.com/loyejaotdiqr47123/rdpwrap/issues/21 My users can't reproduce the problem, please ask if the winlogin bug is just happening by chance!

loyejaotdiqr47123 commented 2 months ago

@llccd See https://github.com/stascorp/rdpwrap/issues/3258 I tested it locally and this version it still doesn't follow the registry

loyejaotdiqr47123 commented 2 months ago
  RegDWord = CRegistry::OpenKey(
               (CRegistry *)v17,
               HKEY_LOCAL_MACHINE,
               L"Software\\Policies\\Microsoft\\Windows NT\\Terminal Services",
               0x20019u,
               v10);
  v6 = RegDWord <= 0;
  if ( !RegDWord )
  {
    RegDWord = CRegistry::ReadRegDWord((CRegistry *)v17, L"fSingleSessionPerUser", v13);
    v6 = RegDWord <= 0;
  }
  if ( !v6 )
    RegDWord = (unsigned __int16)RegDWord | 0x80070000;
  if ( RegDWord >= 0 )
    goto LABEL_21;
  v7 = CRegistry::OpenKey(
         (CRegistry *)v17,
         HKEY_LOCAL_MACHINE,
         L"System\\CurrentControlSet\\Control\\Terminal Server",
         0x20019u,
         v11);
  v3 = v7;
  if ( v7 > 0 )
    v3 = (unsigned __int16)v7 | 0x80070000;
  if ( v3 < 0 )
  {
    if ( (unsigned int)dword_18012D030 <= 3 )
      goto LABEL_2;
    v14 = "IsSingleSessionPerUser";
    v15 = (__int64)"Registry.OpenKey";
    v16 = (__int64)"Warning HResult failed";
    v12 = (__int64 *)&v14;
    v8 = &v16;
    goto LABEL_15;
  }
  v9 = CRegistry::ReadRegDWord((CRegistry *)v17, L"fSingleSessionPerUser", v13);
  v3 = v9;

After patch,there doesn't seem to be a problem.

loyejaotdiqr47123 commented 2 months ago

@llccd

llccd commented 2 months ago

Strangely, on all my devices (22621.4037 Enterprise edition) it does follow the registry. Please use Process Monitor to check whether those values are checked in your system when receiving new RDP connections. Untitled

loyejaotdiqr47123 commented 2 months ago

Using termwrap, it checks the registry and follows the registry Using rdpwrap, no checks, no registry

loyejaotdiqr47123 commented 2 months ago

image .....