2:10了,,哈,现在是大年三十了,uty给您拜年了!
msginA.dll似乎很复杂,光导入的函数就特别多,msdn的两个sAmple,一个完全就是显示调用msginA.dll的导出函数,记得D8有一个后门就是在这个过程中开个端口,其实我总觉得这样似乎就不算是GINA后门了,,另一个sAmple还没看呢 :-|
在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;
HKEY Key ;
int err ;
PVOID p;
//
// Load the DLL. If this is not the default MSGINA, poke the dispatch table
// into the registry. If 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 = LoadLibraryW(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 (!pTerm->Gina.pWlxIsLockOk)
{
DebugLog((DEB_ERROR, "Could not find WlxIsLockOk entry point"));
goto LoadGina_ErrorReturn;
}
IsLockOkFn = pTerm->Gina.pWlxIsLockOk;
pTerm->Gina.pWlxIsLogoffOk = (PWLX_ISLOGOFFOK) GetProcAddress(pTerm->Gina.hInstance, WLX_ISLOGOFFOK_NAME);
if (!pTerm->Gina.pWlxIsLogoffOk)
{
DebugLog((DEB_ERROR, "Could not find WlxIsLogoffOk entry point"));
goto LoadGina_ErrorReturn;
}
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)
{
pTerm->Gina.pWlxScreenSaverNotify = DummyWlxScreenSaverNotify;
}
//
// New interfaces for NT 5.0
//
pTerm->Gina.pWlxNetworkProviderLoad = (PWLX_NPLOAD) GetProcAddress( pTerm->Gina.hInstance, WLX_NPLOAD_NAME );
if ( !pTerm->Gina.pWlxNetworkProviderLoad )
{
pTerm->Gina.pWlxNetworkProviderLoad = DummyWlxNetworkProviderLoad ;
}
pTerm->Gina.pWlxDisplayStatusMessage = (PWLX_DISPLAYSTATUSMESSAGE) GetProcAddress( pTerm->Gina.hInstance, WLX_DISPLAYSTATUSMESSAGE_NAME );
if ( !pTerm->Gina.pWlxDisplayStatusMessage )
{
pTerm->Gina.pWlxDisplayStatusMessage = DummyWlxDisplayStatusMessage ;
}
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((DEB_ERROR, "%ws is at version %d, can't support/n", lpGinaName, dwGinaLevel));
goto LoadGina_ErrorReturn;
}
return TRUE;
LoadGina_ErrorReturn:
//
// FreeLibrary the DLL if it was loaded
//
if (pTerm->Gina.hInstance)
FreeLibrary (pTerm->Gina.hInstance);
//
// Reset the gina structure to NULL in case any of the
// GetProcAddress calls above succeeded.
//
ZeroMemory (&pTerm->Gina, sizeof(GINASESSION));
//
// Setup to use the dummy bad gina functions
//
InitBadGina(pTerm);
return TRUE;
}
把 msginA.dll的导出函数的地址全部存在TERMINAL结构中,并调用WlxNegotiate,这是winlogon的工作.
结构:
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 spwndDesktopOwner; // 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 desktop for the window station.
*/
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.h
typedef struct _TERMINAL {
//
// Terminal signature
//
DWORD CheckMark;
//
// Next terminal
//
struct _TERMINAL * pNext;
//
// Winlogon's window station
//
PWINDOWSTATION pWinStaWinlogon;
//
// Desktop 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 InitializeSecurity() at startup
WinstaState WinlogonState;
WinstaState PreviousWinlogonState;
BOOL ScreenSaverActive;
BOOL ShutdownStarted;
BOOL bIgnoreScreenSaverRequest;
WindowMapper Mappers[MAX_WINDOW_MAPPERS];
DWORD cActiveWindow;
DWORD PendingSasEvents[MAX_WINDOW_MAPPERS];
DWORD PendingSasHead;
DWORD PendingSasTail;
BOOL MessageBoxActive ;
//
// Gina information
//
GINASESSION Gina;
//
// Multi-User specific part of winlogon globals struct
//
MUGLOBALS MuGlobals;
//
// used to set the "ignore auto logon" flag when user does a log off
//
BOOL IgnoreAutoLogon;
} TERMINAL;
typedef TERMINAL *PTERMINAL;
typedef struct _WINDOWSTATION {
//
// 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 hToken; // user's token
//PVOID pGinaContext;
USER_PROCESS_DATA UserProcessData;
USER_PROFILE_INFO UserProfile;
LUID LogonId;
PWSTR LogonScripts;
PWSTR UserName;
PWSTR Domain ;
// Stored ACL
PVOID Acl;
} WINDOWSTATION;
typedef WINDOWSTATION *PWINDOWSTATION;
可能是带tAg的是内核里的结构
其他的是用户可见的