$theTitle=wp_title(" - ", false); if($theTitle != "") { ?>
About Virtualization, VDI, SBC, Application Compatibility and anything else I feel like
A while ago I published a patch for Windows 2003 Terminal Server that allows more than 2 concurrent sessions in Remote Administration mode.
Today I publish the same patch but for Windows Server 2003 X64. The patched function (CRAPolicy::Logon) is the same as in the original patch.
The patch was tested with build 5.2.3790.3959, English language.
This patch uses a new patch engine which I described here. If you have tested the patch on a different language and/or build of termsrv.dll please report back if it’s working.
Windows 2003 X64 Terminal Server Patch (4386 downloads)
28 Responses for "Windows 2003 X64 Terminal Server Patch"
I’ve tried to patch, but it shows me that it’s for x86. Is it right?
@Curiosity: Sorry! Seems I accidently uploaded the X86 project file… I replaced the download so it should be ok now!
Will you publish the same patch for Windows XP SP2 x64?
PS I would glad donate you but i haven’t credit card. If you would live in Ukraine i would donate you by some beer or any other way. Hope you understand my meaning. π
@Pasha: it’s ok at least you are providing feedback! Sometimes people are really rude, I have made and sent people some custom patches or extra help and after receiving the files you never hear from them again (no feedback, no thank you, no nothing).
Just because I curious I had a look at the patch patch.
And thought though 31 c0 ugh what’s this? Isn’t that supposed to be 33 c0? So I tried
31 C0 => XOR EAX, EAX and then just for checking
33 C0 => XOR EAX, EAX funny thing man what’s this
then I had some idea : let’s try this:
31 C1 => XOR ECX, EAX
33 C1 => XOR EAX, EAX Haharr! ….so Mr. Watson what do you concluse from this?
When 31 c0 is like that:
31 C0 => XOR eax, EAX While 33 c0 is:
33 C0 => XOR EAX, eax
Nice that Intel even thought of us reverse engineers when creating the x86 operation set.
So on the one hand we’ve 33 C0, which is the standard (xor first, second op ) nearly each compiler uses.
And on the other hand there is 31 C0. the ‘reversed’ compiler standard (xor second, first op).
Cool!
Thanks for pointing me on that.
P.s
Well of course the result of both is the same. It’s just da style what matters.
Ah and there I even got some other idea – you may use this kind of simularities for stegographie(=To scramble hidden messages into data\Watermarking). Like scan da code for all occurence of 31 C0 and 33 C0 and the modify it like this
0 => 33 C0
1 => 31 C0 … but he yes
you’re right that comment is even offtopic enought so I better stop here.
I well now finally the real review on the patch pattern had a look on the patch pattern:
48 83 EC 28 48 89 5C 24 40 48 8B D9
+00 48 83 EC 28 sub rsp, 28h
+04 48 89 5C 24 40 mov [rsp+40h], rbx
+09 48 8B D9 mov rbx, rcx
Beside the fact that a pattern is often much better(flexible) than a fixed offset – on regarding older or further versions that pattern will probably changes just because the compiler ‘was in a other mud and does changes like
*using other Registers (rax,rbx…) or
+00 48 83 EC 28 sub rsp, 28h
+04 48 89 5C 24 40 mov [rsp+40h], rbx
+09 48 8? ?? mov rdx, rcx
^-I did assemble it so I don’t know that exact values – but I these values will change.
*inmediatamente resulting in mo So
+00 48 83 EC 28 sub rsp, 28h
get’s
+00 48 83 ?? 28 00 00 00 sub rsp, 00000028h
^- All of this I’ve already seen ‘in the wild.’ (specially the highly optimising M$ compiler can be very ‘create’ when creating objectcode)
When really good ‘fixed point’ for pattern-patches are contant values. But look on the target function shows – There are none π
signed int __thiscall CRAPolicy__Logon(int Arg0_LicCount, int Arg1_LicData)
{
int lLicCount; // edi@1
int lLicData; // esi@1
signed int result; // eax@3
lLicData = Arg1_LicData;
lLicCount = Arg0_LicCount;
if ( (unsigned __int8)CSession__IsSessionZero() || TSIsSessionHelpSession(*(_DWORD *)lLicData, 0) )
result = 0; // XoR EAX,eax <-That’s what the patch does
else
result = CRAPolicy__UseLicense(lLicCount, lLicData);
return result;
}
As you see the only ‘bad end’ the function could take is:
result = CRAPolicy__UseLicense(arg0_License);
(… imagine CRAPolicy__UseLicense(..); returns 1 or something else that is not equal to 0)
So let’s focus on ‘CRAPolicy::UseLicense(..)’
I remove some C type defs and Casting – but hehe you’re not planing to compile it, do you. Don’t worry this C-Code still look ugly enough(l)
IDA – H:\Installs\Windows 2003\Enterprise
Deutsch.NRMEVOL_DE+SP2\I386\1\termsrv.dll – [Pseudocode]
int CRAPolicy__UseLicense(int this, int LicData)
{
v2 = (this
+ 0xC);
if ( InterlockedIncrement((this
+ 0xC)) > 2 )
{
InterlockedDecrement(v2);
result = 0xC00A0013u; // =
STATUS_CTX_LICENSE_NOT_AVAILABLE
}
else
{
*(*(*LicData + 0x3410) + 0x24) = 1; // MAYBE !!! {LicData.Client.InUse = 1}
result
= 0;
}
return result;
}
Bingo as you see there are a plenty of ‘constants’ which + they have some more unique values like for ex (0x0, 0x1, 0x4, 0xC…).
Especially 0xC00A0013!
And now (please don’t run crying away as ppl something do when I start with asm) we’ll have a look a the asm code.
And please excuse that I’m using 32-bit Asm code here (X64-asm should be simulare)
CRAPolicy__UseLicense
CRAPolicy__UseLicense ; =============== S U B R O U T I N E =======================================
CRAPolicy__UseLicense
CRAPolicy__UseLicense ; unsigned int __thiscall CRAPolicy__UseLicense(int this, int LicData)CRAPolicy__UseLicense
CRAPolicy__UseLicense LicData = dword ptr 8
CRAPolicy__UseLicense
CRAPolicy__UseLicense 8B FF mov edi, edi
CRAPolicy__UseLicense+2 55 push ebp
CRAPolicy__UseLicense+3 8B EC mov ebp, esp
CRAPolicy__UseLicense+5 56 push esi ;
CRAPolicy__UseLicense+5 ;
CRAPolicy__UseLicense+5 ;
CRAPolicy__UseLicense+6 8D 71 0C lea esi, [ecx+0Ch]
CRAPolicy__UseLicense+9 56 push esi ; this
CRAPolicy__UseLicense+A FF 15 BC 12 FD 75 call ds:InterlockedIncrement(x)
CRAPolicy__UseLicense+10 83 F8 02 cmp eax, 2
CRAPolicy__UseLicense+13 7F 16 jg short killThisAndExit ;
CRAPolicy__UseLicense+13 ;
CRAPolicy__UseLicense+15 8B 45 08 mov eax, [ebp+LicData]
CRAPolicy__UseLicense+18 8B 00 mov eax, [eax]
CRAPolicy__UseLicense+1A 8B 80 10 34 00 00 mov eax, [eax+3410h]
CRAPolicy__UseLicense+20 C7 40 24 01 00 00 00 mov dword ptr [eax+24h], 1
CRAPolicy__UseLicense+27 33 C0 xor eax, eax
CRAPolicy__UseLicense+29 EB 0C jmp short Done
CRAPolicy__UseLicense+2B ; —————————————————————————
CRAPolicy__UseLicense+2B
CRAPolicy__UseLicense+2B killThisAndExit: CRAPolicy__UseLicense+2B 56 push esi ; this
CRAPolicy__UseLicense+2C FF 15 C0 12 FD 75 call ds:InterlockedDecrement(x)
CRAPolicy__UseLicense+32 B8 13 00 0A C0 mov eax, 0C00A0013h
CRAPolicy__UseLicense+37CRAPolicy__UseLicense+37 Done:
CRAPolicy__UseLicense+37 5E pop esi
CRAPolicy__UseLicense+38 5D pop ebp
CRAPolicy__UseLicense+39 C2 04 00 retn 4
CRAPolicy__UseLicense+39 CRAPolicy__UseLicense endp
CRAPolicy__UseLicense+39CRAPolicy__UseLicense+39 ; —————————————————————————
So now let’s watch out for a nice patch. Agh I got an Idea: Let’s change
$+32 > B8 13000AC0 MOV EAX, C00A0013 to
$+32 > B8 00000000 MOV EAX, 00000000
Or even more compatible in the mean it will work for 32 and 64 Bit would be to just replace the value C00A0013. In Hex it is 13 00 0A C0.
So Find all
13 00 0A C0 and replace it with
00 00 00 00
Done!.
Discussing/SideEffects: Well in compare to old patch there will be 2 License used – but if the limit of 2 is exceed no new will be used, but also there will be returned no ErrorCode – signaling the caller function no more users allowed.
@cw2k
Could you prepare the patch for Windows XP x64 and publish it in Internet?
Hi, Remko! I’m very happy that you’ve done the x64 patch!
For a month I have been using the patched winlogon.exe and termsrv.dll from SP1. I found them in a small topic of a forum that I don’t remember. The problem with SP1 files was that sometimes the system could hang up in BSOD.
I have just applied your patch to my WinXP x64 SP2. Unfortunately the system denies the second login to itself! π I doubt about the right registry settings, but I didn’t find the exact list of them in your previous records.
Could you help me? Thank you in advance!
@Pol@ris: This patch is SPECIFIC for Server 2003 X64!!!
Even though Windows XP X64 might uses the same binary other things need to be patched.
If you are referrering to setting up a session to localhost: this check is done within the mstsc client (mstscax.dll). The XP patch will also patch this file, as a workaround you can use 127.0.0.2 instead of localhost/127.0.0.1.
@Pasha – please wait until this week-end. Something is going to happen here π
@Remko:
Frankly speaking I haven’t understood. π
The fact is that I used only the patched winlogon.exe and termsrv.exe, and all was ok, I didn’t use the patched version of mstscax.dll.
Please tell me what to do to make the rdp working in the case of WinXP?
@Pol@r1s: You are confusing me! What patch are you using on what os? The patch from this post doesn’t do anything with Winlogon nor is it for Windows XP.
Please read daNIL’s comment…
@Remko:
Finally I’ve found the page with the SP1 patched files again:
http://defcon5.biz/phpBB3/viewtopic.php?f=4&t=500
I think you will be interested in.
@Pol@r1s: tx, never saw that one before. But please hold on until the weekend, I think daNIL’s solution is better.
@Remko:
Of course. I’ll wait for it.
PS: excuse me for being annoying to you! π
So, it is weekend now! Do you have any news?
Please be patient! It’s coming… soon π
aghhhrrr!!! i am so exciting! π i can’t wait so long π
… it seems like it never happened
dear friends, i visit your source every day and hope that magic patch would published, but it still would not …
my girl becomes angry for me, because i promised her personal account in our windows xp x64, but it still not happened … god help me π i am praying that daNIL will publish the patch soonest! :))))
i invite you my dear friend, i have some strong drinks, we will drink it for your happiness, for your successfull work! you’re heartly welcome in my home city Kharkov in Ukraine with Remko!!!!!!beleive me my friends, it is only one way for thank you!
Merry Christmas dear friends!
@Remko:
I have server 2003 R2 enterprise x64 edition SP2
I patched the termsrv.dll build 5.2.3790.3959 according to the procedure you describe above and copy the patched dll to the c:\windows\system32\dllcache in safe mode.
The patched dll is differing from original in these 6 numbers:
48 83 EC
vs
31 C0 C3
However, now, I can connect only 3 concurrent Terminal Server sessions. I do not understand why.
Do you have any idea what I did wrong?
@Afinko: Check your (local) policy with gpedit.msc, check Administrative Templates | Windows Components | Terminal Server | Connections. You need to set Limit number of connections to 999999 and disable restrict users to a single remote Terminal Services session.
Also check registry under HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Terminal Server
EnableConcurrentSessions (1)
fDenyTSConnections (0)
fSingleSessionPerUser (0)
UserSessionLimit (0)
@Remko: Thank you very much, it works now, you’re good, you really good π
However, some setups in gpedit.msc were in another directories. I found them here:
Local Computer Policy | Computer Configuration | Administrative Templates | Windows Components | Terminal services
Restrict Terminal Services users to a single remote session -> DISABLED
Limit number of connections -> ENABLES | TS Maximum Connections allowed 999999
is this patch can use with windows server 2003 64bit on
1and1 company to make able to access unlimited users to
server through remote desktop connection
If yes can you make it to me for $10 please π
@ The Big Boss Remko
I try it but still the maximum 2 users
I Sure from do everything
1- make the patch 2003X64TSPatch.exe
2- Copy the file termserv.dll from C:\WINDOWS\system32\
and paste it with 2003X64TSPatch.exe in the same folder
3- click patch and take the termserv.dll to paste it to
C:\WINDOWS\system32\dllcache\
4-Local Computer Policy | Computer Configuration | Administrative Templates | Windows Components | Terminal services
5-Restrict Terminal Services users to a single remote session -> DISABLED
6-Limit number of connections -> ENABLES | TS Maximum Connections allowed 999999
7-reboot my server
I make all this where is the problem ??
i use server 2003 R2 enterprise x64 edition SP2 termsrv.dll build 5.2.3790.3959, following your described procedure and copy the patched dll to the c:\windows\system32\dllcache in safe mode (difference in hex 3EDE0: patched 31C0C3, original 4883EC). i think, patched correctly.
1. gpedit.msc:
local computer policy/computer configuration/administrative templates/windows components/terminal services
restrict terminal services users to a single remote session: disabled
limit number of connections:
enables
TS maximum connections allowed 999999
2.registry settings
[HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Terminal Server]
“MsgQBadAppSleepTimeInMillisec”=dword:00000001
“NthCountMsgQPeeksSleepBadApp”=dword:00000005
“fWritableTSCCPermTab”=dword:00000001
“DeleteTempDirsOnExit”=dword:00000001
“PerSessionTempDir”=dword:00000001
“fDenyTSConnections”=dword:00000000
“ProductVersion”=”5.2”
“TSAdvertise”=dword:00000000
“IdleWinStationPoolCount”=dword:00000000
“TSAppCompat”=dword:00000000
“TSEnabled”=dword:00000001
“TSUserEnabled”=dword:00000000
“fSingleSessionPerUser”=dword:00000000
“fEnableSalem”=dword:00000000
“fAllowToGetHelp”=dword:00000000
“MaxInstanceCount”=dword:00000100
“EnableConcurrentSessions”=dword:00000001
“UserSessionLimit”=dword:00000000
3. restart server. but still 2 concurrent connections :((((
what’s wrong? do i mistake? please, advice welcome
@smeto: please check the following:
1) are you running in remote administration mode?
2) verify that the termsrv.dll in c:\windows\system32 was not replaced by the original (eg because you have a copy of i386 folder from install media somewhere).
Leave a reply