在Windows Vista中,系统提供了一个名为"远程协助"的功能,允许用户通过帮助和支持中心请求远程帮助。但是,许多用户(包括)仍然在使用Windows XP,而该功能在XP中并不直接可用。因此,创建了一个名为"Turbo Remote"的实验项目,当检测到的操作系统版本低于Windows Vista时,该项目将使用一种技术来建立远程协助会话。
要使用此方法,您需要满足以下条件:
以下是实现远程协助会话的步骤:
需要创建"监听"会话的应用程序必须检查"终端服务"服务是否正在运行。如果该服务未运行,则必须启动它,否则其他操作将无法进行。应用程序在服务器关闭后必须将服务恢复到原始状态。这在代码中通过EnableTSS(bool)
和IsTSSEnabled()
实现(这些尚未实现!)。
使用NetUserEnum
和NetUserSetInfo
函数启用HelpAssistant账户。如果该账户最初被禁用,则应用程序必须在完成后禁用该账户。这通过EnableHA(bool)
和IsHAEnabled()
实现。
通过设置HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Terminal Server
中的fAllowToGetHelp
为1来启用远程协助。这在SetRARunning(bool)
和IsRARunning()
中实现。
如果之前禁用了组策略,则需要恢复这些键。这在GetTicket()
中完成。具体步骤如下:
Software\Microsoft\Windows\CurrentVersion\Group Policy Objects\\Software\policies\Microsoft\Windows NT\Terminal Services
中将fAllowUnsolicited
、fAllowUnsolicitedFullControl
、fAllowToGetHelp
设置为1(DWORD)。RAUnsolicit
,并添加一个名称和值等于您的用户名的值,例如,Administrator。导入HelpServiceInterfaces.tlb
以获取帮助接口。
#import "HelpServiceInterfaces.tlb" rename_namespace("HSITLB") named_guids\
rename("EOF", "XX_EOF")\
rename("GetUserName", "GetUserName_Renamed")\
rename("EncryptFile", "EncryptFile_Renamed")\
rename("DecryptFile", "DecryptFile_Renamed")\
rename("ULONG_PTR", "ULONG_PTR1")
创建IPCHService*实例。
CoCreateInstance(HSITLB::CLSID_PCHService, NULL, CLSCTX_LOCAL_SERVER, __uuidof(HSITLB::IPCHService), (void**)&p);
注意使用CLSCTX_LOCAL_SERVER。
调用IPCHService::raw_RemoteConnectionParms(),提供用户名、计算机名称、终端服务会话ID(WTSGetActiveConsoleSessionId()
)和blob请求,格式如下:
"13;UNSOLICITED=1;ID=\\";
将<PCName>
和<Username>
替换为所需的值,将<X>
替换为<X>
之后所有内容的字符串长度。例如:"13;UNSOLICITED=122;ID=GATOR\\Administrator"。PC名称是GATOR,用户名是Administrator,字符串"ID=GATOR\Administrator"的总长度是22。
接下来,您需要检查票据(类似于以下内容):
65538,1,192.168.1.21:3389;laptop:3389,*, KwRrNVpWH2g1vKfVlQUrJHKcpi8N1XA++9tQ+wnAXyE=,*,*,sdP7Lk3SFAXXcIrKpvLW6IJ8fg=
将端口3389(总是放在那里!)替换为终端服务服务器实际运行的端口。这个端口位于HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\TerminalServer\WinStations\RDP-Tcp
中的"PortNumber"。
这是一个Unicode文件(必须包含BOM头\xFE\xFF
),格式如下:
XML
<?
xml
version
=
"1.0"
encoding
=
"Unicode"
?
>
<
UPLOADINFO
TYPE
=
"Escalated"
>
<
UPLOADDATA
USERNAME
=
"Administrator"
RCTICKET
=
"<ticket>"
RCTICKETENCRYPTED
=
"0"
DtStart
=
"X"
DtLength
=
"Y"
L
=
"0"
/
>
<
/UPLOADINFO
>
X
是票据创建的时间(标准UNIX格式,使用
time()
),Y
是这个时间 + 票据的长度。还没有找到支持加密票据的方法。
有了这个文件后,您可以通过TCP/IP或其他方法将其发送给客户端。