system32下面的mstsc.exe。
今天研究了一下windows远程桌面客户端,就是system32下面的mstsc.exe。
一向讲究易用性的微软在mstsc.exe中提供了一个将主机地址,用户名、密码等连接所需信息保存到缀名为.rdp的文件中,以便将来快速打开的功能 。
现在我想要做的是,如何自己生成这个.rdp文件,让我自己的程序更方便地调用mstsc.exe?
首先需要做的就是分析.rdp文件的格式。
用文本编辑器打开.rdp文件,可以发现rdp文件的内容以是文本形式的,而且大部分都是明文,只有密码这个字段,明显是经过加密的。
所以,自制rdp文件的任务的关键就是要生成这个密码。
查了一下,mstsc.exe使用的加解密算法分别是CryptProtectData和CryptUnProtectData两个windows API。
知道了这个的话就好办了,直接照着MSDN上CryptProtectData的示例改就行了。
下面给出代码:
#include <stdio.h>
#include <windows.h>
#include <Wincrypt.h>
void main()
{
DATA_BLOB DataIn;
DATA_BLOB DataOut;
// mstsc.exe中使用的是unicode,所以必须做宽字符转换
BYTE *pbDataInput =(BYTE *)L"freedom";
DWORD cbDataInput = wcslen(L"freedom")*sizeof(wchar_t);
DataIn.pbData = pbDataInput;
DataIn.cbData = cbDataInput;
FILE *fp;
if(CryptProtectData(
&DataIn,
L"psw", // A description string
// to be included with the
// encrypted data.
NULL, // Optional entropy not used.
NULL, // Reserved.
NULL, // Pass NULL for the
// prompt structure.
0,
&DataOut))
{
printf("The encryption phase worked.\n");
fp = fopen("password.txt","w");
int count=0;
while ( count <= (int)DataOut.cbData ){
// 因为一个unsigned int 占32位
// 转换成成16进制要占两位
// 所以这里需要用%02
fprintf(fp,"%02X",DataOut.pbData[count]);
count++;
}
fclose(fp);
}
else
{
printf("Encryption error using CryptProtectData.\n");
exit(1);
}
}
编译时需要指定连接crypt32.lib库,所以一个最简单的编译命令为
cl rdp.cpp crypt32.lib
意外的是,这个程序生成的加密字符串比mstsc.exe生成的要短很多,后面一部分也不一样。但既然是用CryptProtectData加密的,自然也应该能用CryptUnProtectData来解密。实验了一下,果真如此。回头再想想,微软这么做也是有道理的。因为直接存储CryptProtectData加密过的数据的话,任何人都能使用CryptUnProtectData恢复出明文,加密也就失去了意义。但如果不公开加密算法,那这个rdp文件对于非微软内部的程序员来说,灵活性就变成了0。现在的处理方式既保证了密码的安全性(某种程度上的),也为程序员留下了扩展开发的余地,一个小程序的生命力也由此得到了增强。
为什么微软如此强大?或许从这个小工具中,我们可以找到一些原因。