Ставлю хук для диалога, который появляется при загрузке Винды. Хук ставится нормально, но при нажатии кнопки ОК в этом диалоге появляется ошибка "Память не может быть written ...".
Хук ставлю по примеру GinaHook из PlatformSDK, заглушки для функций взял из статьи "GINA — это просто".
xgina.cpp
#define UNICODE
#define _UNICODE
#include "stdafx.h"
#include "xgina.h"
static MSWlxDispatchTbl WlxTbl; // таблица функций MSGINA
static HMODULE hGina=NULL; // хэндл предыдущей GINA
static HANDLE hWinlogon=NULL; // хендл винлогона
static PWLX_DISPATCH_VERSION_1_0 pWinlogonDispTbl; // таблица функций винлогона v1.0
#ifdef _UNICODE
#define _tmemset wmemset
#else
#define _tmemset memset
#endif
#ifdef _DEBUG
#define LOG_PATH _T("c:\\xgina.log")
void DEBUG_MSG(const TCHAR *szMsg, ... );
#else
#define DEBUG_MSG
#endif
BOOL APIENTRY DllMain(HANDLE hModule, DWORD ul_reason_for_call, LPVOID lpReserved)
{
switch (ul_reason_for_call)
{
case DLL_PROCESS_ATTACH:
{
DEBUG_MSG(_T("Attach dll"));
hGina=LoadLibrary(MSGINA); // грузим msgina.dll
if (!hGina) return FALSE; // полный облом, терминируемся
// определяем адреса импортируемых функций из предыдущей GINA
PWlxActivateUserShell *pWlxFunc=(PWlxActivateUserShell *)&WlxTbl;
for (int i=0; i<ImportsNumber; i++)
pWlxFunc[i]=(PWlxActivateUserShell)::GetProcAddress(hGina, ImportFunctions[i]); // импортируем все, что сможем
}
break;
case DLL_THREAD_ATTACH:
break;
case DLL_THREAD_DETACH:
break;
case DLL_PROCESS_DETACH:
FreeLibrary(hGina);
break;
}
return TRUE;
}
// собственно функции-обертки
BOOL WINAPI WlxActivateUserShell(PVOID pWlxContext, PWSTR pszDesktopName, PWSTR pszMprLogonScript, PVOID pEnvironment)
{
DEBUG_MSG(_T("%s"), _T(__FUNCTION__));
return WlxTbl.WlxActivateUserShell(pWlxContext, pszDesktopName, pszMprLogonScript, pEnvironment);
}
VOID WINAPI WlxDisplayLockedNotice(PVOID pWlxContext)
{
DEBUG_MSG(_T("%s"), _T(__FUNCTION__));
WlxTbl.WlxDisplayLockedNotice(pWlxContext);
}
VOID WINAPI WlxDisplaySASNotice(PVOID pWlxContext)
{
DEBUG_MSG(_T("%s"), _T(__FUNCTION__));
WlxTbl.WlxDisplaySASNotice(pWlxContext);
}
BOOL WINAPI WlxDisplayStatusMessage(PVOID pWlxContext, HDESK hDesktop, DWORD dwOptions, PWSTR pTitle, PWSTR pMessage)
{
DEBUG_MSG(_T("%s"), _T(__FUNCTION__));
return WlxTbl.WlxDisplayStatusMessage(pWlxContext, hDesktop, dwOptions, pTitle, pMessage);
}
BOOL WINAPI WlxGetStatusMessage(PVOID pWlxContext, DWORD *pdwOptions, PWSTR pMessage, DWORD dwBufferSize)
{
DEBUG_MSG(_T("%s"), _T(__FUNCTION__));
return WlxTbl.WlxGetStatusMessage(pWlxContext, pdwOptions, pMessage, dwBufferSize);
}
// функция инициализации GINA
BOOL WINAPI WlxInitialize(LPWSTR lpWinsta, HANDLE hWlx, PVOID pvReserved, PVOID pWinlogonFunctions, PVOID *pWlxContext)
{
DEBUG_MSG(_T("%s"), _T(__FUNCTION__));
hWinlogon=hWlx; //сохраняем хендл Винлогона для дальнейшего использования
pfWlxDialogBoxParamOld = ((PWLX_DISPATCH_VERSION_1_0)pWinlogonFunctions)->WlxDialogBoxParam;
((PWLX_DISPATCH_VERSION_1_0)pWinlogonFunctions)->WlxDialogBoxParam = (PWLX_DIALOG_BOX_PARAM)WlxDialogBoxParamHook;
pWinlogonDispTbl=(PWLX_DISPATCH_VERSION_1_0)pWinlogonFunctions; //сохраняем указатель на таблицу сервисных функций Винлогона
return WlxTbl.WlxInitialize(lpWinsta,hWlx,pvReserved,pWinlogonFunctions,pWlxContext);
}
BOOL WINAPI WlxIsLockOk(PVOID pWlxContext)
{
DEBUG_MSG(_T("%s"), _T(__FUNCTION__));
return WlxTbl.WlxIsLockOk(pWlxContext);
}
BOOL WINAPI WlxIsLogoffOk(PVOID pWlxContext)
{
DEBUG_MSG(_T("%s"), _T(__FUNCTION__));
return WlxTbl.WlxIsLogoffOk(pWlxContext);
}
int WINAPI WlxLoggedOnSAS(PVOID pWlxContext, DWORD dwSasType, PVOID pReserved)
{
DEBUG_MSG(_T("%s"), _T(__FUNCTION__));
return WlxTbl.WlxLoggedOnSAS(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)
{
DEBUG_MSG(_T("%s"), _T(__FUNCTION__));
return WlxTbl.WlxLoggedOutSAS(pWlxContext, dwSasType, pAuthenticationId, pLogonSid, pdwOptions, phToken, pMprNotifyInfo, pProfile);
}
VOID WINAPI WlxLogoff(PVOID pWlxContext)
{
DEBUG_MSG(_T("%s"), _T(__FUNCTION__));
WlxTbl.WlxLogoff(pWlxContext);
}
BOOL WINAPI WlxNegotiate(DWORD dwWinLogonVersion, PDWORD pdwDllVersion)
{
DEBUG_MSG(_T("%s"), _T(__FUNCTION__));
return WlxTbl.WlxNegotiate(dwWinLogonVersion, pdwDllVersion);
}
BOOL WINAPI WlxNetworkProviderLoad(PVOID pWlxContext, PWLX_MPR_NOTIFY_INFO pMprNotifyInfo)
{
DEBUG_MSG(_T("%s"), _T(__FUNCTION__));
return WlxTbl.WlxNetworkProviderLoad(pWlxContext, pMprNotifyInfo);
}
BOOL WINAPI WlxRemoveStatusMessage(PVOID pWlxContext)
{
DEBUG_MSG(_T("%s"), _T(__FUNCTION__));
return WlxTbl.WlxRemoveStatusMessage(pWlxContext);
}
BOOL WINAPI WlxScreenSaverNotify(PVOID pWlxContext, BOOL *pSecure)
{
DEBUG_MSG(_T("%s"), _T(__FUNCTION__));
return WlxTbl.WlxScreenSaverNotify(pWlxContext,pSecure);
}
VOID WINAPI WlxShutdown(PVOID pWlxContext, DWORD ShutdownType)
{
DEBUG_MSG(_T("%s"), _T(__FUNCTION__));
WlxTbl.WlxShutdown(pWlxContext, ShutdownType);
}
BOOL WINAPI WlxStartApplication(PVOID pWlxContext, PWSTR pszDesktopName, PVOID pEnvironment, PWSTR pszCmdLine)
{
DEBUG_MSG(_T("%s"), _T(__FUNCTION__));
return WlxTbl.WlxStartApplication(pWlxContext, pszDesktopName, pEnvironment, pszCmdLine);
}
int WINAPI WlxWkstaLockedSAS(PVOID pWlxContext, DWORD dwSasType)
{
DEBUG_MSG(_T("%s"), _T(__FUNCTION__));
return WlxTbl.WlxWkstaLockedSAS(pWlxContext, dwSasType);
}
BOOL WINAPI WlxGetConsoleSwitchCredentials (PVOID pWlxContext, PVOID pCredInfo)
{
DEBUG_MSG(_T("%s"), _T(__FUNCTION__));
return WlxTbl.WlxGetConsoleSwitchCredentials(pWlxContext, pCredInfo);
}
VOID WINAPI WlxReconnectNotify(PVOID pWlxContext)
{
DEBUG_MSG(_T("%s"), _T(__FUNCTION__));
WlxTbl.WlxReconnectNotify(pWlxContext);
}
VOID WINAPI WlxDisconnectNotify(PVOID pWlxContext)
{
DEBUG_MSG(_T("%s"), _T(__FUNCTION__));
WlxTbl.WlxDisconnectNotify(pWlxContext);
}
#ifdef _DEBUG
void DEBUG_MSG(const TCHAR *szMsg, ...)
{
FILE *fLog = NULL;
va_list marker;
SYSTEMTIME st;
GetLocalTime(&st);
TCHAR szTmp[1024];
_tmemset(szTmp, 0, 1024);
va_start(marker, szMsg);
_vstprintf(szTmp, szMsg, marker);
va_end(marker);
if ((fLog = _tfopen((TCHAR *)LOG_PATH, _T("a+"))) == NULL)
return;
_ftprintf(fLog, _T("%02d.%02d.%04d-%02d:%02d:%02d * %s\n"), st.wDay, st.wMonth, st.wYear, st.wHour, st.wMinute, st.wSecond, szTmp);
fclose(fLog);
}
#endif
int WlxDialogBoxParamHook(HANDLE hWlx, HANDLE hInst, LPWSTR lpszTemplate, HWND hwndOwner, DLGPROC dlgprc, LPARAM dwInitParam)
{
if (!HIWORD(lpszTemplate))
{
// Hook appropriate dialog boxes as necessary.
switch ((DWORD)lpszTemplate)
{
case IDD_WLXLOGGEDOUTSAS_DIALOG:
{
pfWlxLoggedOutSASDlgProc = dlgprc;
return pfWlxDialogBoxParamOld(hWlx, hInst, lpszTemplate, hwndOwner, MyWlxLoggedOutSASDlgProc, dwInitParam);
}
/*case IDD_WLXWKSTALOCKEDSAS_DIALOG:
{
pfWlxWkstaLockedSASDlgProc = dlgprc;
return pfWlxDialogBoxParam(hWlx, hInst, lpszTemplate, hwndOwner, MyWlxWkstaLockedSASDlgProc, dwInitParam);
}
case IDD_CHANGE_PASSWORD_DIALOG:
{
pfChangePasswordDlgProc = dlgprc;
return pfWlxDialogBoxParam(hWlx, hInst, lpszTemplate, hwndOwner, MyChangePasswordDlgProc, dwInitParam);
}*/
}
}
// The rest will not be redirected.
return pfWlxDialogBoxParamOld(hWlx, hInst, lpszTemplate, hwndOwner, dlgprc, dwInitParam);
}
BOOL CALLBACK MyWlxLoggedOutSASDlgProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
BOOL bResult;
// Pass on to MSGINA first.
bResult = pfWlxLoggedOutSASDlgProc(hwndDlg, uMsg, wParam, lParam);
switch (uMsg)
{
case WM_INITDIALOG:
DEBUG_MSG(_T("WM_INITDIALOG"));
break;
case WM_CLOSE:
DEBUG_MSG(_T("WM_CLOSE"));
break;
}
return bResult;
}
xgina.h
#define ImportsNumber 21 //число импортируемых функций
#define MSGINA _T("msgina.dll")
#define USERINIT _T("Userinit.exe")
static char *ImportFunctions[]=
{
"WlxActivateUserShell",
"WlxDisplayLockedNotice",
"WlxDisplaySASNotice",
"WlxDisplayStatusMessage",
"WlxGetStatusMessage",
"WlxInitialize",
"WlxIsLockOk",
"WlxIsLogoffOk",
"WlxLoggedOnSAS",
"WlxLoggedOutSAS",
"WlxLogoff",
"WlxNegotiate",
"WlxNetworkProviderLoad",
"WlxRemoveStatusMessage",
"WlxScreenSaverNotify",
"WlxShutdown",
"WlxStartApplication",
"WlxWkstaLockedSAS",
"WlxGetConsoleSwitchCredentials",
"WlxReconnectNotify",
"WlxDisconnectNotify"
}; //список импортируемых функций
// сигнатуры
typedef BOOL (WINAPI *PWlxActivateUserShell)(PVOID pWlxContext, PWSTR pszDesktopName, PWSTR pszMprLogonScript, PVOID pEnvironment);
typedef VOID (WINAPI *PWlxDisplayLockedNotice)(PVOID pWlxContext);
typedef VOID (WINAPI *PWlxDisplaySASNotice)(PVOID pWlxContext);
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 *PWlxInitialize)(LPWSTR lpWinsta, HANDLE hWlx, PVOID pvReserved, PVOID pWinlogonFunctions, PVOID *pWlxContext);
typedef BOOL (WINAPI *PWlxIsLockOk)(PVOID pWlxContext);
typedef BOOL (WINAPI *PWlxIsLogoffOk)(PVOID pWlxContext);
typedef int (WINAPI *PWlxLoggedOnSAS)(PVOID pWlxContext, DWORD dwSasType, PVOID pReserved);
typedef int (WINAPI *PWlxLoggedOutSAS)(PVOID pWlxContext, DWORD dwSasType, PLUID pAuthenticationId, PSID pLogonSid, PDWORD pdwOptions, PHANDLE phToken, PWLX_MPR_NOTIFY_INFO pMprNotifyInfo, PVOID *pProfile);
typedef VOID (WINAPI *PWlxLogoff)(PVOID pWlxContext);
typedef BOOL (WINAPI *PWlxNegotiate)(DWORD dwWinLogonVersion, PDWORD pdwDllVersion);
typedef BOOL (WINAPI *PWlxNetworkProviderLoad)(PVOID pWlxContext, PWLX_MPR_NOTIFY_INFO pMprNotifyInfo);
typedef BOOL (WINAPI *PWlxRemoveStatusMessage)(PVOID pWlxContext);
typedef BOOL (WINAPI *PWlxScreenSaverNotify)(PVOID pWlxContext, BOOL *pSecure);
typedef VOID (WINAPI *PWlxShutdown)(PVOID pWlxContext, DWORD ShutdownType);
typedef BOOL (WINAPI *PWlxStartApplication)(PVOID pWlxContext, PWSTR pszDesktopName, PVOID pEnvironment, PWSTR pszCmdLine);
typedef int (WINAPI *PWlxWkstaLockedSAS)(PVOID pWlxContext, DWORD dwSasType);
typedef BOOL (WINAPI *PWlxGetConsoleSwitchCredentials)(PVOID pWlxContext, PVOID pCredInfo);
typedef VOID (WINAPI *PWlxReconnectNotify)(PVOID pWlxContext);
typedef VOID (WINAPI *PWlxDisconnectNotify)(PVOID pWlxContext);
// таблица указателей на импортируемые функции
typedef struct _MSWlxDispatchTbl
{
PWlxActivateUserShell WlxActivateUserShell;
PWlxDisplayLockedNotice WlxDisplayLockedNotice;
PWlxDisplaySASNotice WlxDisplaySASNotice;
PWlxDisplayStatusMessage WlxDisplayStatusMessage;
PWlxGetStatusMessage WlxGetStatusMessage;
PWlxInitialize WlxInitialize;
PWlxIsLockOk WlxIsLockOk;
PWlxIsLogoffOk WlxIsLogoffOk;
PWlxLoggedOnSAS WlxLoggedOnSAS;
PWlxLoggedOutSAS WlxLoggedOutSAS;
PWlxLogoff WlxLogoff;
PWlxNegotiate WlxNegotiate;
PWlxNetworkProviderLoad WlxNetworkProviderLoad;
PWlxRemoveStatusMessage WlxRemoveStatusMessage;
PWlxScreenSaverNotify WlxScreenSaverNotify;
PWlxShutdown WlxShutdown;
PWlxStartApplication WlxStartApplication;
PWlxWkstaLockedSAS WlxWkstaLockedSAS;
PWlxGetConsoleSwitchCredentials WlxGetConsoleSwitchCredentials;
PWlxReconnectNotify WlxReconnectNotify;
PWlxDisconnectNotify WlxDisconnectNotify;
} MSWlxDispatchTbl;
int WlxDialogBoxParamHook(HANDLE hWlx, HANDLE hInst, LPWSTR lpszTemplate, HWND hwndOwner, DLGPROC dlgprc, LPARAM dwInitParam);
static PWLX_DIALOG_BOX_PARAM pfWlxDialogBoxParamOld = NULL;
BOOL CALLBACK MyWlxLoggedOutSASDlgProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam);
static DLGPROC pfWlxLoggedOutSASDlgProc = NULL;
static DLGPROC pfWlxWkstaLockedSASDlgProc = NULL;
static DLGPROC pfChangePasswordDlgProc = NULL;
// MSGINA dialog box IDs.
#define IDD_WLXDIAPLAYSASNOTICE_DIALOG 1400
#define IDD_WLXLOGGEDOUTSAS_DIALOG 1500
#define IDD_CHANGE_PASSWORD_DIALOG 1550
#define IDD_WLXLOGGEDONSAS_DIALOG 1650
#define IDD_WLXWKSTALOCKEDSAS_DIALOG 1850
// MSGINA control IDs
#define IDC_WLXLOGGEDOUTSAS_USERNAME 1502
#define IDC_WLXLOGGEDOUTSAS_PASSWORD 1503
#define IDC_WLXLOGGEDOUTSAS_DOMAIN 1504
#define IDC_WLXLOGGEDOUTSAS_OK 1