Windows开机登录认证与Gina DLL
Windows的开机密码认证模块一般是由Gina DLL完成的。在NT/2000中交互式的登陆支持是由WinLogon调用GINA DLL实现的,GINA DLL提供了一个交互式的界面为用户登陆提供认证请求。
1.Gina原理
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。
2.Gina DLL导出函数
在NT/2000 中交互式的登陆支持是由WinLogon调用GINA DLL实现的,GINA DLL提供了一个交互式的界面为用户登陆提供认证请求。GINA DLL要输出下列函数(Winlogon会调用):
(1) WlxActivateUserShell:激活用户外壳程序。
(2) WlxDisplayLockedNotice:允许GINA DLL显示锁定信息。
(3) WlxDisplaySASNotice:当没有用户登陆时,Winlogon调用此函数。
(4) WlxDisplayStatusMessage:Winlogon用一个状态信息调用此函数进行显示。
(5) WlxGetStatusMessage:Winlogon 调用此函数获取当前状态信息。
(6) WlxInitialize:针对指定的窗口位置进行GINA DLL初始化。
(7) WlxIsLockOk:验证工作站正常锁定。
(8) WlxIslogoffOk:验证注销正常。
(9) WlxLoggedOnSAS:用户已登陆并且工作站没有被加锁,如果此时接收到SAS事件,则Winlogon 调用此函数。
(10) WlxLoggedOutSAS:没有用户登陆,如果此时收到SAS事件,则Winlogon调用此函数。
(11) WlxLogoff:请求注销操作时通知GINA DLL。
(12) WlxNegotiate:表示当前的Winlogon版本是否能使用GINA DLL。
(13) WlxNetworkProviderLoad:在加载网络服务提供程序收集了身份和认证信息后,Winlogon 调用此函数。
(14) WlxRemoveStatusMessage:Winlogon调用此函数告诉GINA DLL停止显示状态信息。
(15) WlxScreensaverNotify:允许GINA与屏幕保护操作交互。
(16) WlxShutdown:在关闭之前Winlogon 调用此函数,允许GINA实现任何关闭任务,例如从读卡器中退出智能卡。
(17) WlxStartApplication:当系统需要在用户的上下文中启动应用程序时调用此函数。
(18) WlxWkstaLockedSAS:当工作站被锁定,如果接收到一个SAS,则Winlogon调用此函数。
我们通过对上述的18个基本函数进行重写,来实现USB身份认证系统的Windows登录身份认证。
// USBGina.cpp : 定义 DLL 应用程序的导出函数。
//
#include "stdafx.h"
#define REALGINA_PATH TEXT("MSGINA.DLL")
// Winlogon函数分配表
PWLX_DISPATCH_VERSION_1_0 g_pWinlogon;
// DLL地址
HINSTANCE hDllInstance;
// Winlogon的句柄
HANDLE hGlobalWlx;
// WLX_VERSION_1_0
PFWLXNEGOTIATE pfWlxNegotiate;
PFWLXINITIALIZE pfWlxInitialize;
PFWLXDISPLAYSASNOTICE pfWlxDisplaySASNotice;
PFWLXLOGGEDOUTSAS pfWlxLoggedOutSAS;
PFWLXACTIVATEUSERSHELL pfWlxActivateUserShell;
PFWLXLOGGEDONSAS pfWlxLoggedOnSAS;
PFWLXDISPLAYLOCKEDNOTICE pfWlxDisplayLockedNotice;
PFWLXWKSTALOCKEDSAS pfWlxWkstaLockedSAS;
PFWLXISLOCKOK pfWlxIsLockOk;
PFWLXISLOGOFFOK pfWlxIsLogoffOk;
PFWLXLOGOFF pfWlxLogoff;
PFWLXSHUTDOWN pfWlxShutdown;
// WLX_VERSION_1_1
PFWLXSTARTAPPLICATION pfWlxStartApplication = NULL;
PFWLXSCREENSAVERNOTIFY pfWlxScreenSaverNotify = NULL;
// WLX_VERSION_1_3
PFWLXNETWORKPROVIDERLOAD pfWlxNetworkProviderLoad = NULL;
PFWLXDISPLAYSTATUSMESSAGE pfWlxDisplayStatusMessage = NULL;
PFWLXGETSTATUSMESSAGE pfWlxGetStatusMessage = NULL;
PFWLXREMOVESTATUSMESSAGE pfWlxRemoveStatusMessage = NULL;
// DLL应用程序入口点
BOOL APIENTRY DllMain(HMODULE hModule, DWORD ul_reason_for_call, LPVOID lpReserved)
{
switch (ul_reason_for_call)
{
case DLL_PROCESS_ATTACH:
hDllInstance = hModule;
case DLL_THREAD_ATTACH:
case DLL_THREAD_DETACH:
case DLL_PROCESS_DETACH:
break;
}
return TRUE;
}
// 系统初始化,在WlxNegotiate中被调用
BOOL MyInitialize(HINSTANCE hDll, DWORD dwWlxVersion)
{
// 系统初始化,从msgina.dll中HOOK WLX_VERSION_1_0中的函数
pfWlxNegotiate = (PFWLXNEGOTIATE) GetProcAddress(hDll, "WlxNegotiate");
if (!pfWlxNegotiate)
{
return FALSE;
}
pfWlxInitialize = (PFWLXINITIALIZE) GetProcAddress(hDll, "WlxInitialize");
if (!pfWlxInitialize)
{
return FALSE;
}
pfWlxDisplaySASNotice = (PFWLXDISPLAYSASNOTICE) GetProcAddress(hDll,
"WlxDisplaySASNotice");
if (!pfWlxDisplaySASNotice)
{
return FALSE;
}
pfWlxLoggedOutSAS = (PFWLXLOGGEDOUTSAS) GetProcAddress(hDll,
"WlxLoggedOutSAS");
if (!pfWlxLoggedOutSAS)
{
return FALSE;
}
pfWlxActivateUserShell = (PFWLXACTIVATEUSERSHELL) GetProcAddress(hDll,
"WlxActivateUserShell");
if (!pfWlxActivateUserShell)
{
return FALSE;
}
pfWlxLoggedOnSAS = (PFWLXLOGGEDONSAS) GetProcAddress(hDll, "WlxLoggedOnSAS");
if (!pfWlxLoggedOnSAS)
{
return FALSE;
}
pfWlxDisplayLockedNotice = (PFWLXDISPLAYLOCKEDNOTICE) GetProcAddress(hDll,
"WlxDisplayLockedNotice");
if (!pfWlxDisplayLockedNotice)
{
return FALSE;
}
pfWlxIsLockOk = (PFWLXISLOCKOK) GetProcAddress(hDll, "WlxIsLockOk");
if (!pfWlxIsLockOk)
{
return FALSE;
}
pfWlxWkstaLockedSAS = (PFWLXWKSTALOCKEDSAS) GetProcAddress(hDll,
"WlxWkstaLockedSAS");
if (!pfWlxWkstaLockedSAS)
{
return FALSE;
}
pfWlxIsLogoffOk = (PFWLXISLOGOFFOK) GetProcAddress(hDll, "WlxIsLogoffOk");
if (!pfWlxIsLogoffOk)
{
return FALSE;
}
pfWlxLogoff = (PFWLXLOGOFF) GetProcAddress(hDll, "WlxLogoff");
if (!pfWlxLogoff)
{
return FALSE;
}
pfWlxShutdown = (PFWLXSHUTDOWN) GetProcAddress(hDll, "WlxShutdown");
if (!pfWlxShutdown)
{
return FALSE;
}
// HOOK WLX_VERSION_1_1版本的新函数。
if (dwWlxVersion > WLX_VERSION_1_0)
{
pfWlxStartApplication = (PFWLXSTARTAPPLICATION) GetProcAddress(hDll,
"WlxStartApplication");
if (!pfWlxStartApplication)
{
return FALSE;
}
pfWlxScreenSaverNotify = (PFWLXSCREENSAVERNOTIFY) GetProcAddress(hDll,
"WlxScreenSaverNotify");
if (!pfWlxScreenSaverNotify)
{
return FALSE;
}
}
// HOOK WLX_VERSION_1_3版本的新函数
if (dwWlxVersion > WLX_VERSION_1_2)
{
pfWlxNetworkProviderLoad = (PFWLXNETWORKPROVIDERLOAD) GetProcAddress(hDll,
"WlxNetworkProviderLoad");
if (!pfWlxNetworkProviderLoad)
{
return FALSE;
}
pfWlxDisplayStatusMessage = (PFWLXDISPLAYSTATUSMESSAGE) GetProcAddress(hDll,
"WlxDisplayStatusMessage");
if (!pfWlxDisplayStatusMessage)
{
return FALSE;
}
pfWlxGetStatusMessage = (PFWLXGETSTATUSMESSAGE) GetProcAddress(hDll,
"WlxGetStatusMessage");
if (!pfWlxGetStatusMessage)
{
return FALSE;
}
pfWlxRemoveStatusMessage = (PFWLXREMOVESTATUSMESSAGE) GetProcAddress(hDll,
"WlxRemoveStatusMessage");
if (!pfWlxRemoveStatusMessage)
{
return FALSE;
}
}
// HOOK新版本的函数
// 所有的HOOK都成功
return TRUE;
}
BOOL WINAPI WlxNegotiate(DWORD dwWinlogonVersion, DWORD * pdwDllVersion)
{
HINSTANCE hDll = NULL;
if (!(hDll = LoadLibrary(REALGINA_PATH)))
{
return FALSE;
}
if(MyInitialize(hDll, dwWinlogonVersion) == TRUE)
{
return pfWlxNegotiate(dwWinlogonVersion, pdwDllVersion);
}
return FALSE;
}
BOOL WINAPI WlxInitialize(LPWSTR lpWinsta, HANDLE hWlx, PVOID pvReserved,
PVOID pWinlogonFunctions, PVOID * pWlxContext)
{
g_pWinlogon = (PWLX_DISPATCH_VERSION_1_0) pWinlogonFunctions;
hGlobalWlx = hWlx;
return pfWlxInitialize(lpWinsta, hWlx, pvReserved, pWinlogonFunctions, pWlxContext);
}
void WINAPI WlxDisplaySASNotice(PVOID pWlxContext)
{
pfWlxDisplaySASNotice(pWlxContext);
g_pWinlogon->WlxDialogBoxParam(hGlobalWlx, hDllInstance, (LPTSTR)
MAKEINTRESOURCE(IDD_LOGON_DLG), NULL, LogonDlgProc, 0);
}
int WINAPI WlxLoggedOutSAS(PVOID pWlxContext, DWORD dwSasType,
PLUID pAuthenticationId, PSID pLogonSid, PDWORD pdwOptions,
PHANDLE phToken, PWLX_MPR_NOTIFY_INFO pMprNotifyInfo, PVOID * pProfile)
{
// 用标准Windows的密码方式登录
return pfWlxLoggedOutSAS(pWlxContext, dwSasType, pAuthenticationId, pLogonSid,
pdwOptions, phToken, pMprNotifyInfo, pProfile);
}
BOOL WINAPI WlxActivateUserShell (PVOID pWlxContext, PWSTR pszDesktopName,
PWSTR pszMprLogonScript, PVOID pEnvironment)
{
// 用标准Windows的密码方式登录,调用MSGINA.DLL中的函数
return pfWlxActivateUserShell(pWlxContext, pszDesktopName, pszMprLogonScript,
pEnvironment);
}
int WINAPI WlxLoggedOnSAS (PVOID pWlxContext, DWORD dwSasType, PVOID pReserved)
{
return pfWlxLoggedOnSAS(pWlxContext, dwSasType, pReserved);
}
void WINAPI WlxDisplayLockedNotice(PVOID pWlxContext)
{
pfWlxDisplayLockedNotice(pWlxContext);
wcscpy(account.strUsername, TEXT(""));
wcscpy(account.strPassword, TEXT(""));
account.bLogonStatus = FALSE;
g_pWinlogon->WlxDialogBoxParam(hGlobalWlx, hDllInstance, (LPTSTR)
MAKEINTRESOURCE(IDD_LOGON_DLG), NULL, LogonDlgProc, 0);
}
BOOL WINAPI WlxIsLockOk(PVOID pWlxContext)
{
return pfWlxIsLockOk(pWlxContext);
}
int WINAPI WlxWkstaLockedSAS(PVOID pWlxContext, DWORD dwSasType)
{
return pfWlxWkstaLockedSAS(pWlxContext, dwSasType);
}
BOOL WINAPI WlxIsLogoffOk(PVOID pWlxContext)
{
return pfWlxIsLogoffOk(pWlxContext);
}
void WINAPI WlxLogoff(PVOID pWlxContext)
{
pfWlxLogoff(pWlxContext);
}
void WINAPI WlxShutdown(PVOID pWlxContext, DWORD ShutdownType)
{
pfWlxShutdown(pWlxContext, ShutdownType);
}
// WLX_VERSION_1_1版
BOOL WINAPI WlxScreenSaverNotify(PVOID pWlxContext, BOOL * pSecure)
{
return pfWlxScreenSaverNotify(pWlxContext, pSecure);
}
BOOL WINAPI WlxStartApplication(PVOID pWlxContext, PWSTR pszDesktopName,
PVOID pEnvironment, PWSTR pszCmdLine)
{
return pfWlxStartApplication(pWlxContext, pszDesktopName, pEnvironment, pszCmdLine);
}
// WLX_VERSION_1_3版
BOOL WINAPI WlxNetworkProviderLoad(PVOID pWlxContext, PWLX_MPR_NOTIFY_INFO
pNprNotifyInfo)
{
return pfWlxNetworkProviderLoad(pWlxContext, pNprNotifyInfo);
}
BOOL WINAPI WlxDisplayStatusMessage (PVOID pWlxContext, HDESK hDesktop,
DWORD dwOptions, PWSTR pTitle, PWSTR pMessage)
{
return pfWlxDisplayStatusMessage(pWlxContext, hDesktop, dwOptions, pTitle, pMessage);
}
BOOL WINAPI WlxGetStatusMessage(PVOID pWlxContext, DWORD * pdwOptions,
PWSTR pMessage, DWORD dwBufferSize)
{
return pfWlxGetStatusMessage(pWlxContext, pdwOptions, pMessage, dwBufferSize);
}
BOOL WINAPI WlxRemoveStatusMessage(PVOID pWlxContext)
{
return pfWlxRemoveStatusMessage(pWlxContext);
}
4. Gina DLL安装
(1) 添加注册表
(2) 键名:HKEY_LOCAL_MACHINE\Software\Microsoft\Windows NT\
(3) CurrentVersion\Winlogon\
(4) 变量名:GinaDLL
(5) 变量类型:[REG_SZ]
(6) 内容:Yourname.dll
(7) 将Gina DLL(Yourname.dll)拷贝到系统目录下(system32)。
(8) 重新启动计算机, Gina DLL(Yourname.dll)就会运行。
5. 结语
以上,Gina DLL就完成,重启之后就可以看到,尽管这个原型调用的是Windows的msgina.dll里面的函数,但是事实上所有的函数已经被我们Hook了,在调用系统函数之前必然会经过我们的函数。以下是与本主题相关信息:
(1)可以通过WlxLoggedOnSAS来屏蔽Windows操作系统下的Ctrl+Alt+Del。
(2)可以在WlxLoggedOutSAS中截获用户登录的用户名以及密码。
(3)通过此原型,可以实现一些个性化的开机认证,包括用指纹(例如ThinkPad笔记本电脑),以及特定的USB才能登录等等。
Windows开机登录认证与Gina DLL的更多相关文章
- windows 开机自动登录,或者说是开机后自动进入桌面
这篇文章,对于XP以及XP以上版本有效,包括Windows Server服务器操作系统. 1.原理 --Windows自动登录的原理是,开始后,自动输入登录所使用的账号的用户名和密码,并且自动进入桌面 ...
- 解决xp突然出现开机登录界面的问题
对系统进行网络相关的设置后,有时会让系统开启时突然冒出登录窗口,即使我们没有对自己的系统设置开机密码,也会冒出这个,需要回车一下才会进入系统:关机时,xp特有的“关机”,“待机”,“重新启动”按钮会变 ...
- SANGFOR AC配置AD域单点登录(二)----AD域侧配置及单点登录认证、注销测试
1.AD域侧配置 1)新建组策略并配置logon登录脚本,以实现用户开机登录域时,自动通过AC认证 AD域服务器"运行"输入gpmc.msc,打开组策略编辑器,如下图. 右建需要 ...
- oracle修改登录认证方式
通过配置sqlnet.ora文件,我们可以修改oracle登录认证方式. SQLNET.AUTHENTICATION_SERVICES=(NTS);基于操作系统的认证 SQLNET.AUTHENTIC ...
- Java 实现 SSH 协议的客户端登录认证方式--转载
背景 在开篇之前,让我们先对 SSH 协议有个宏观的大致了解,这样更有利于我们对本文的加深了解.首先要提到的就是计算机网络协议,所谓计算机网络协议,简单的说就是定义了一套标准和规则,使得不同计算机之间 ...
- 使用crypt配置Basic Auth登录认证
简介 Basic Auth用于服务端简单的登录认证,通常使用服务器Nginx.Apache本身即可完成.比如我们要限定某个域名或者页面必须输入用户名.密码才能登录,但又不想使用后端开发语言,此时Bas ...
- oracle数据库启动流程及登录认证方式详解
转自:https://www.2cto.com/database/201803/726644.html ■ oracle启动流程-windows下 1) lsnrctl start (启动监听) ...
- 有关WINDOWS XP登录密码的几种方法
网上关于破解WINDOWS XP登录密码的几种方法很多,但许多根本不行.我现在总结自己试过几种,这几种方法其实均比较菜的,但可行的.WINDOWS XP登录是由SAM 文件管理的,总体来说“山姆大叔” ...
- oracle改动登录认证方式
通过配置sqlnet.ora文件.我们能够改动oracle登录认证方式. SQLNET.AUTHENTICATION_SERVICES=(NTS);基于操作系统的认证 SQLNET.AUTHENTIC ...
随机推荐
- iOS开展UI一片—简单的浏览器观看节目
iOS开发UI篇-简单的浏览器查看程序 一.程序实现要求 1.要求 2. 界面分析 (1) 须要读取或改动属性的控件须要设置属性 序号标签 图片 图片描写叙述 左边button 右边button (2 ...
- 依赖注入及AOP简述(九)——单例和无状态Scope .
三.依赖注入对象的Scope及其生命周期 在前面的章节我们讲到,依赖注入容器之所以能够区别于以往的ServiceLocator等容器,是在于其不但能够自动构建多层次的.完整的依赖关系图,并且可以管理依 ...
- How debuggers work
做了一个PPT用来和组内的同学交流一下.内容很简单,写得也很简单. 谁知道博客园文章里怎么直接嵌入PPT呢? link: http://www.slideshare.net/ssuserdc412f/ ...
- Hadoop书籍下载链接
Hadoop书籍推荐1:Hadoop实战(结合经典案例全面讲解hadoop整个技术体系)http://www.db2china.net/club/thread-25148-1-1.html2:Hado ...
- 图像、帧、片、NALU概念理解
图像.帧.片.NALU 是学习 H.264 的人常常感到困惑的一些概念. H.264 是一次概念的革新,它打破常规,完全没有 I 帧.P帧.B 帧的概念,也没有 IDR 帧的概念.对于 H.264 中 ...
- C#软件winform程序安装包制作及卸载程序制作
使用vs2010 winform程序开发的软件的人比较多,程序的开发是为了在不同的人不同的机器使用,为了使不同的机器能使用该软件就需要在制作程序安装包,安装包里必须包含该软件运行所选的所有环境,下面就 ...
- 关于offsetTop offsetHeight clientHeight scrollHeight scrollTop的区别研究
我是以chrome浏览器做的研究. 先看一段代码: <script> window.addEventListener('DOMContentLoaded',function(){ var ...
- jQuery Tags Input Plugin 插件的使用
一个jquery开发的标签功能加强插件,可以生成或删除标签,还能对输入重复标签进行检查,和JQuery autocomplete插件配合实现自动完成功能. 官网:http://xoxco.com/pr ...
- 卸载cloudera manager
卸载Cloudera-Manager sudo /usr/share/cmf/uninstall-cloudera-manager.sh 一直选择Yes 就好 卸载完成后,它会问你是否要将databa ...
- 响应式web之媒体查询(一)
HTML4和css2目前支持为不用的媒体类型设定专有的样式,如,一个页面在屏幕上时使用无衬线字体,而在打印时使用衬线字体.screen和print是两种已定义的媒体类型.媒体查询让样式表有更强的针对性 ...