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。
html

WinLogon初始化時會建立3個桌面:
(1) winlogon桌面:主要顯示Windows 安全等界面,如你按下CTRL+ALT+DEL,登錄的界面等
(2) 應用程序桌面:咱們平時見到的那個有個人電腦的界面
(3) 屏幕保護桌面:屏幕保護顯示界面。安全

在默認狀況下,GINA顯示登錄對話框,用戶輸入用戶名及密碼 。因此要得到用戶名和密碼 ,則能夠寫一個新的GINA DLL,其中提供接口調用msgina.dll的函數WlxLoggedOutSAS。網絡

2.Gina DLL導出函數ide

在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登陸身份認證。spa

// 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. 結語htm

以上,Gina DLL就完成,重啓以後就能夠看到,儘管這個原型調用的是Windows的msgina.dll裏面的函數,可是事實上全部的函數已經被咱們Hook了,在調用系統函數以前必然會通過咱們的函數。如下是與本主題相關信息:
(1)能夠經過WlxLoggedOnSAS來屏蔽Windows操做系統下的Ctrl+Alt+Del。
(2)能夠在WlxLoggedOutSAS中截獲用戶登陸的用戶名以及密碼。
(3)經過此原型,能夠實現一些個性化的開機認證,包括用指紋(例如ThinkPad筆記本電腦),以及特定的USB才能登陸等等。blog

 
轉載:http://www.sizeof.cn/html/2009/46.html
相關文章
相關標籤/搜索