zoukankan      html  css  js  c++  java
  • 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登录身份认证。

    3. Gina DLL原型代码

    // 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_MACHINESoftwareMicrosoftWindows NT
    (3) CurrentVersionWinlogon
    (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才能登录等等。

  • 相关阅读:
    win10系统设置指定程序开机自启
    PyCharm 2020.1 x64 专业版破解【亲测有效】
    xampp_mysql数据库root登录报错1045-Access denied for user 'root'@'localhost' (using password:YES)
    关于 Tomcat 启动时,解决控制台输出日志乱码问题的方案
    1.css选择器
    5.canvas
    4.音频与视频
    3.form表单
    淘宝店铺设计
    2.html5新布局元素
  • 原文地址:https://www.cnblogs.com/DeeLMind/p/7160292.html
Copyright © 2011-2022 走看看