2:10, ha, now is the New Year, UTY gives you a New Year! Msgina.dll seems to be very complicated, the light imported function is very much, the MSDN's two SAMPLE, one is completely displayed Msgina. DLL's export function, remember that D8 has a back door to open a port during this process. In fact, I always feel that it seems to be a gina back door, and another Sample hasn't seen it yet: - | in Private / Windows / GINA / Winlogon / ginamgr.c // ***************************************************** ******************* //// Loadginadll () //// Purpose: Loads the gina DLL and Negotiates The Version Number //// Parameters: Pterm - Terminal To load the gina for // lpginaname - Gina DLL Name //// Return: True if successful // False if an error occurs //// ****************************** *************************************************
Bool Loadginadll (Pterminal Pterm, LPWSTR LPGINANAME) {DWORD DWGINALEVEL = 0; BOOL BRESULT; HKY KEY; int Err; PVOID P;
/// // load the dll. If this is not The default msgina, poke the dispatch table // 通 t The registry. IT IS, Delete the key (if present) //
Err = regopenkeyex (HKEY_LOCAL_MACHINE, WINLOGON_KEY, 0, KEY_READ | Key_Write, & Key);
IF (Err! = 0) {RETURN FALSE;
IF ((_WCSICMP (LPGINANAME, TEXT ("Msgina.dll"))! = 0) && (! PTERM-> SafeMode) {P = & WLXDISPATCHTABLE;
RegSetValueex (Key, Text ("Key"), 0, Reg_binary, (Puchar) & P, Sizeof (PVOID));
} Else {regdeletevalue (key, text ("key"));
PTERM-> Gina.hinstance = loadinglibraryw (lpginaname);
IF (! PTERM-> Gina.hinstance) {Debuglog ((Deb_ERROR, "Error% D loading Gina DLL% WS / N", getLastError (), LPGINANAME)); goto loadgina_errorreturn;} // // Get the function Pointers / /
pTerm-> Gina.pWlxNegotiate = (PWLX_NEGOTIATE) GetProcAddress (pTerm-> Gina.hInstance, WLX_NEGOTIATE_NAME); if (pTerm-> Gina.pWlxNegotiate!) {DebugLog ((DEB_ERROR, "Could not find WlxNegotiate entry point / n")) Goto loadgina_errorreturn;}
pTerm-> Gina.pWlxInitialize = (PWLX_INITIALIZE) GetProcAddress (pTerm-> Gina.hInstance, WLX_INITIALIZE_NAME); if (pTerm-> Gina.pWlxInitialize!) {DebugLog ((DEB_ERROR, "Could not find WlxInitialize entry point / n")) Goto loadgina_errorreturn;
}
pTerm-> Gina.pWlxDisplaySASNotice = (PWLX_DISPLAYSASNOTICE) GetProcAddress (pTerm-> Gina.hInstance, WLX_DISPLAYSASNOTICE_NAME); if (pTerm-> Gina.pWlxDisplaySASNotice!) {DebugLog ((DEB_ERROR, "Could not find WlxDisplaySASNotice entry point / n")) Goto loadgina_errorreturn;}
pTerm-> Gina.pWlxLoggedOutSAS = (PWLX_LOGGEDOUTSAS) GetProcAddress (pTerm-> Gina.hInstance, WLX_LOGGEDOUTSAS_NAME); if (! pTerm-> Gina.pWlxLoggedOutSAS) {DebugLog ((DEB_ERROR, "Could not find WlxLoggedOutSAS entry point / n")) Goto loadgina_errorreturn;}
pTerm-> Gina.pWlxActivateUserShell = (PWLX_ACTIVATEUSERSHELL) GetProcAddress (pTerm-> Gina.hInstance, WLX_ACTIVATEUSERSHELL_NAME); if (! pTerm-> Gina.pWlxActivateUserShell) {DebugLog ((DEB_ERROR, "Could not find WlxActivateUserShell entry point / n")) Goto loadgina_errorreturn;}
pTerm-> Gina.pWlxLoggedOnSAS = (PWLX_LOGGEDONSAS) GetProcAddress (pTerm-> Gina.hInstance, WLX_LOGGEDONSAS_NAME); if (! pTerm-> Gina.pWlxLoggedOnSAS) {DebugLog ((DEB_ERROR, "Could not find WlxLoggedOnSAS entry point / n")) ; goto LoadGina_ErrorReturn;} pTerm-> Gina.pWlxDisplayLockedNotice = (PWLX_DISPLAYLOCKEDNOTICE) GetProcAddress (pTerm-> Gina.hInstance, WLX_DISPLAYLOCKED_NAME); if (! pTerm-> Gina.pWlxDisplayLockedNotice) {DebugLog ((DEB_ERROR, "Could not find WlxDisplayLockedNotice / n ")); Goto loadgina_errorreturn;}
pTerm-> Gina.pWlxWkstaLockedSAS = (PWLX_WKSTALOCKEDSAS) GetProcAddress (pTerm-> Gina.hInstance, WLX_WKSTALOCKEDSAS_NAME); if (! pTerm-> Gina.pWlxWkstaLockedSAS) {DebugLog ((DEB_ERROR, "Could not find WlxWkstaLockedSAS entry point / n")) Goto loadgina_errorreturn;}
pTerm-> Gina.pWlxIsLockOk = (PWLX_ISLOCKOK) GetProcAddress (pTerm-> Gina.hInstance, WLX_ISLOCKOK_NAME); if {DebugLog ((DEB_ERROR, "Could not find WlxIsLockOk entry point")) (pTerm-> Gina.pWlxIsLockOk!); goto Loadgina_errorreturn;} islockokfn = pterm-> gina.pwlxislockok;
pTerm-> Gina.pWlxIsLogoffOk = (PWLX_ISLOGOFFOK) GetProcAddress (pTerm-> Gina.hInstance, WLX_ISLOGOFFOK_NAME); if {DebugLog ((DEB_ERROR, "Could not find WlxIsLogoffOk entry point")) (pTerm-> Gina.pWlxIsLogoffOk!); goto LOADGINA_ERRORRRETURN;}
pTerm-> Gina.pWlxLogoff = (PWLX_LOGOFF) GetProcAddress (pTerm-> Gina.hInstance, WLX_LOGOFF_NAME); if (! pTerm-> Gina.pWlxLogoff) {DebugLog ((DEB_ERROR, "Could not find WlxLogoff entry point / n")) ; goto LoadGina_ErrorReturn;} pTerm-> Gina.pWlxShutdown = (PWLX_SHUTDOWN) GetProcAddress (pTerm-> Gina.hInstance, WLX_SHUTDOWN_NAME); if (! pTerm-> Gina.pWlxShutdown) {DebugLog ((DEB_ERROR, "Could not find WlxShutdown entry point / N ")); goto loadgina_errorreturn;}
/// NEW interfaces for NT 4.0 //
pTerm-> Gina.pWlxStartApplication = (PWLX_STARTAPPLICATION) GetProcAddress (pTerm-> Gina.hInstance, WLX_STARTAPPLICATION_NAME); if (! pTerm-> Gina.pWlxStartApplication) {DebugLog ((DEB_TRACE, "Could not find WlxStartApplication entry point / n")) ; Pterm-> gina.pwlxstartApplication = WLXStartApplication;
pTerm-> Gina.pWlxScreenSaverNotify = (PWLX_SSNOTIFY) GetProcAddress (pTerm-> Gina.hInstance, WLX_SSNOTIFY_NAME); if {pTerm-> Gina.pWlxScreenSaverNotify = DummyWlxScreenSaverNotify;} (pTerm-> Gina.pWlxScreenSaverNotify!)
/// NEW interfaces for NT 5.0 //
pTerm-> Gina.pWlxNetworkProviderLoad = (PWLX_NPLOAD) GetProcAddress (pTerm-> Gina.hInstance, WLX_NPLOAD_NAME); if {pTerm-> Gina.pWlxNetworkProviderLoad = DummyWlxNetworkProviderLoad;} (pTerm-> Gina.pWlxNetworkProviderLoad!)
pTerm-> Gina.pWlxDisplayStatusMessage = (PWLX_DISPLAYSTATUSMESSAGE) GetProcAddress (pTerm-> Gina.hInstance, WLX_DISPLAYSTATUSMESSAGE_NAME); if {pTerm-> Gina.pWlxDisplayStatusMessage = DummyWlxDisplayStatusMessage;} (pTerm-> Gina.pWlxDisplayStatusMessage!) pTerm-> Gina.pWlxGetStatusMessage = (PWLX_GETSTATUSMESSAGE) GetProcAddress (pTerm-> Gina.hInstance, WLX_GETSTATUSMESSAGE_NAME); if (! pTerm-> Gina.pWlxGetStatusMessage) {pTerm-> Gina.pWlxGetStatusMessage = DummyWlxGetStatusMessage;}
pTerm-> Gina.pWlxRemoveStatusMessage = (PWLX_REMOVESTATUSMESSAGE) GetProcAddress (pTerm-> Gina.hInstance, WLX_REMOVESTATUSMESSAGE_NAME); if (! pTerm-> Gina.pWlxRemoveStatusMessage) {pTerm-> Gina.pWlxRemoveStatusMessage = DummyWlxRemoveStatusMessage;}
/// NEGOTIATE a Version Number with the gina //
BRESULT = PTERM-> Gina.pwlxnegotiate (WLX_Current_Version, & Dwginalevel);
If (! BRESULT) {DEBUGLOG (deb_ERROR, "% ws failed the wlxnegotiate call / n", lpginaname); goto loadgina_errorreturn;}
IF (dwginalevel> WLX_CURRENT_VERSION) {DEBUGLOG (debuglog (debuglog, "% ws is at version% d, can't support / n", lpginaname, dwginalevel); goto loadgina_errorreturn;}
Return True;
Loadgina_errorreturn:
/// Freelibrary the dll if it is loaded ////
IF (PTERM-> Gina.hinstance) Freelibrary (PTERM-> Gina.hinstance);
/// RESET the GINA STRUCTURE TO NULL IN CASE ANY OF THE // GetProcaddress Calls Above Succeed. //
ZeromeMory (& PTERM-> Gina, Sizeof (ginasession));
// // setup to use the dummy bad gina functions //
Initbadgina (PTERM);
Return True;} All the address of the export function of Msgina.dll exists in the Terminal structure, and call WLXnegotiate, which is Winlogon's work.
Structure: in Private / NTOS / W32 / NTUSER / KERNEL / Userk.h / * * Terminal Structure. * * This structure is only viewable from the kernel. * /
#define TEST_GTERMF (f) TEST_FLAG (gdwGTERMFlags, f) #define TEST_BOOL_GTERMF (f) TEST_BOOL_FLAG (gdwGTERMFlags, f) #define SET_GTERMF (f) SET_FLAG (gdwGTERMFlags, f) #define CLEAR_GTERMF (f) CLEAR_FLAG (gdwGTERMFlags, f) #define SET_OR_CLEAR_GTERMF (F, Fset) set_or_clear_flag (gdwgtermflags, f, fset) #define Toggle_gTermf (f) Toggle_Flag (GDWGTERMFLAGS, F)
#define GTERMF_MOUSE 0x00000001
#define TERMF_INITIALIZED 0x00000001 # define TERMF_NOIO 0x00000002 # define TERMF_STOPINPUT 0x00000004 # define TERMF_DTINITSUCCESS 0x00000008 # define TERMF_DTINITFAILED 0x00000010 # define TERMF_DTDESTROYED 0x00000020
Typedef struct tagterminal {
DWORD dWTERMF_FLAGS; // Terminal Flags
/ * * System Information * / PWND SPWNDESKTOPOWNER; // Mother Desktop
PthreadInfo ptidesktop; pq pqdesktop;
PKEVENT PEVENTTERMINIT; PKEVENT PEVENTDESTROYDESKTOP; // Used for Destroying Desktops
PDESKTOP RPDESKDESTROY; // Desktop Destroy List.
PKEVENT pEventInputReady; // input ready event This is created in // CreateTerminal RIT and the desktop thread // will wait for it It will be set when the // first desktop in that terminal will be created PKEVENT pEventDTExit....;
} TERMINAL, * PTERMINAL; / * * Windowstation structure * / # define WSF_SWITCHLOCK 0x0001 # define WSF_OPENLOCK 0x0002 # define WSF_NOIO 0x0004 # define WSF_SHUTDOWN 0x0008 # define WSF_DYING 0x0010 # define WSF_REALSHUTDOWN 0x0020
Typedef struct tagwindowstation {pwindowstation rpwinstanext; pdesktop rpdesklist;
Pterminal Pterm; / * * Pointer to the currently active design. * / DWORD DWWSF_FLAGS; Struct Tagkl * SPKLLIST;
/ * * Clipboard variables * / PTHREADINFO ptiClipLock; PTHREADINFO ptiDrawingClipboard; PWND spwndClipOpen; PWND spwndClipViewer; PWND spwndClipOwner; struct tagCLIP * pClipBase; int cNumClipFormats; UINT iClipSerialNumber; UINT iClipSequenceNumber; UINT fClipboardChanged: 1; UINT fInDelayedRendering: 1;
/ * * Global Atom Table * / PVOID PGLOBALATOMTABLE;
Luid LuidEndSession; LUID Luiduser; PSID PSIDUSER; PQ PQDESKTOP;
DWORD DWSESSIONID;
#if dbg pdesktop pdeskcurrent; #ENDIF // DBG
} WindowStation; In Private / Windows / Gina / Winlogon / Winlogon.htypedPedef struct_terminal {
/// Terminal Signature ///////
DWORD CHECKMARK;
///////// NEXT TERMINAL ////
Struct_Terminal * PNext;
// // Winlogon's WINDOW Station //
PWindowStation PWinsTawinlogon;
// // desktop switch switching information //
Pwstr pszdesktop; // name of current desktop. DWORD desktoplength; // length of name./// sas window handle //
HWND HWNDSAS;
/// misc items //
DWORD iniref;
Bool UserLoggedon; DWORD LOGOFFFLAGS; DWORD TICKCOUNT;
Bool ForwardCad; Bool Enablesc; Bool SafeMode; DWORD Sastype; DWORD Lastginaret;
HANDLE hToken; // Machine token HANDLE hGPOEvent; HANDLE hGPOThread; HANDLE hGPONotifyEvent; HANDLE hGPOWaitEvent; HANDLE hAutoEnrollmentHandler; DWORD ErrorMode; DWORD SmartCardTid; PVOID CurrentScEvent; // // These items need to be reviewed //.
// filled in by initializeigurecurity () at Startup Winstastate WinLogonState; WinStaState PreviouswinlogonState
Bool ScreensaVertive; Bool ShutdownStarted;
Bool BignoScreensaverRequest;
WindowMapper MapPers [MAX_WINDOW_MAPPERS]; DWORD CACTIVEWINDOW; DWORD PENDINGSSEVENTS [MAX_WINDOW_MAPPERS]; DWORD PENDINGSASHEAD; DWORD PENDINGSASTAIL; BOOL MessageBoxActive;
// // Gina Information ////
Ginasession Gina;
// // Multi-user specificent Part of Winlogon Globals Struct // Muglobals Muglobal
/////. '
Terminal; TypeDef Terminal * Pterminal; TypeDef Struct_WindowStation {
//// Next window station ///////// NEXT WINDOW station
Struct_windowstation * pnext;
/// Handle to the window station Object //
Hwinsta hwinsta; lpwstr lpwinstaname;
//// Desktops //
HDESK hdeskPrevious; HDESK hdeskApplication; HDESK hdeskWinlogon; HDESK hdeskScreenSaver; // screensaver's desktop ActiveDesktops ActiveDesktop; // Current, active desktop ActiveDesktops PreviousDesktop; // Previous desktop // // User information //
Handle htokeen; // user's token // pvoid pginacontext; user_process_data userprocessdata; user_profile_info userprofile; luid logonid; pwstr logonscripts; pwstr uthame; pwstr domain;
// Stored ACL PVOID ACL;
WINDOWSTATION; TYPEDEF WINDOWSTATION * PWINDOWSTATION; It may be that the structure with TAG is other in the kernel.