转自:http://blog.csdn.net/xisat/archive/2009/02/23/3926957.aspx
先看看两张图
实现起来并不复杂
常规方法有
1 .替换gina.dll
彻底,但是有数字签名的困惑,个人还是不要用了
2. 在system权限下切换入/winlogon桌面显示窗口
下面要介绍的就是这个
3.注入winlogon.exe
个人觉得这种办法比较好,通过winlogon/notify注入winlogon.exe,默认就是/winlogon桌面,过程简单,做一个窗口过程的win32 dll就可以了,这里不再详细
================================
简单介绍一下第二种方法
三步实现
一 . 获取system权限
方法满多的,这里我做了一个Local System的本地服务Logon Window,不用考虑登陆前的自启动问题,也好
过程略过
二. 切换入/winlogon桌面
要说明一下,服务选项中的“允许服务与桌面交互”只是将服务进程切换到/default桌面,我们需要如下的过程
view plaincopy to clipboardprint?
//切换到winlogon桌面,需要system权限
BOOL CDesktop()
{
HDESK hdeskCurrent;
HDESK hdesk;
HWINSTA hwinstaCurrent;
HWINSTA hwinsta;
//
// Save the current Window station
//
hwinstaCurrent = GetProcessWindowStation();
if (hwinstaCurrent == NULL)
return FALSE;
//
// Save the current desktop
//
hdeskCurrent = GetThreadDesktop(GetCurrentThreadId());
if (hdeskCurrent == NULL)
return FALSE;
//
// Obtain a handle to WinSta0 - service must be running
// in the LocalSystem account
//
hwinsta = OpenWindowStationA("winsta0", FALSE,
WINSTA_ACCESSCLIPBOARD |
WINSTA_ACCESSGLOBALATOMS |
WINSTA_CREATEDESKTOP |
WINSTA_ENUMDESKTOPS |
WINSTA_ENUMERATE |
WINSTA_EXITWINDOWS |
WINSTA_READATTRIBUTES |
WINSTA_READSCREEN |
WINSTA_WRITEATTRIBUTES);
if (hwinsta == NULL)
return FALSE;
//
// Set the windowstation to be winsta0
//
if (!SetProcessWindowStation(hwinsta))
return FALSE;
//
// Get the default desktop on winsta0
//
hdesk = OpenDesktopA("Winlogon", 0, FALSE,
DESKTOP_CREATEMENU |
DESKTOP_CREATEWINDOW |
DESKTOP_ENUMERATE |
DESKTOP_HOOKCONTROL |
DESKTOP_JOURNALPLAYBACK |
DESKTOP_JOURNALRECORD |
DESKTOP_READOBJECTS |
DESKTOP_SWITCHDESKTOP |
DESKTOP_WRITEOBJECTS);
if (hdesk == NULL)
return FALSE;
//
// Set the desktop to be "default"
//
if (!SetThreadDesktop(hdesk))
return FALSE;
/*==================================执行体,显示窗口,做你想做的事情
=============================*/
//ServiceSub();
//
// Reset the Window station and desktop
//
if (!SetProcessWindowStation(hwinstaCurrent))
return FALSE;
if (!SetThreadDesktop(hdeskCurrent))
return FALSE;
//
// Close the windowstation and desktop handles
//
if (!CloseWindowStation(hwinsta))
return FALSE;
if (!CloseDesktop(hdesk))
return FALSE;
return TRUE;
}
//切换到winlogon桌面,需要system权限
BOOL CDesktop()
{
HDESK hdeskCurrent;
HDESK hdesk;
HWINSTA hwinstaCurrent;
HWINSTA hwinsta;
//
// Save the current Window station
//
hwinstaCurrent = GetProcessWindowStation();
if (hwinstaCurrent == NULL)
return FALSE;
//
// Save the current desktop
//
hdeskCurrent = GetThreadDesktop(GetCurrentThreadId());
if (hdeskCurrent == NULL)
return FALSE;
//
// Obtain a handle to WinSta0 - service must be running
// in the LocalSystem account
//
hwinsta = OpenWindowStationA("winsta0", FALSE,
WINSTA_ACCESSCLIPBOARD |
WINSTA_ACCESSGLOBALATOMS |
WINSTA_CREATEDESKTOP |
WINSTA_ENUMDESKTOPS |
WINSTA_ENUMERATE |
WINSTA_EXITWINDOWS |
WINSTA_READATTRIBUTES |
WINSTA_READSCREEN |
WINSTA_WRITEATTRIBUTES);
if (hwinsta == NULL)
return FALSE;
//
// Set the windowstation to be winsta0
//
if (!SetProcessWindowStation(hwinsta))
return FALSE;
//
// Get the default desktop on winsta0
//
hdesk = OpenDesktopA("Winlogon", 0, FALSE,
DESKTOP_CREATEMENU |
DESKTOP_CREATEWINDOW |
DESKTOP_ENUMERATE |
DESKTOP_HOOKCONTROL |
DESKTOP_JOURNALPLAYBACK |
DESKTOP_JOURNALRECORD |
DESKTOP_READOBJECTS |
DESKTOP_SWITCHDESKTOP |
DESKTOP_WRITEOBJECTS);
if (hdesk == NULL)
return FALSE;
//
// Set the desktop to be "default"
//
if (!SetThreadDesktop(hdesk))
return FALSE;
/*==================================执行体,显示窗口,做你想做的事情
=============================*/
//ServiceSub();
//
// Reset the Window station and desktop
//
if (!SetProcessWindowStation(hwinstaCurrent))
return FALSE;
if (!SetThreadDesktop(hdeskCurrent))
return FALSE;
//
// Close the windowstation and desktop handles
//
if (!CloseWindowStation(hwinsta))
return FALSE;
if (!CloseDesktop(hdesk))
return FALSE;
return TRUE;
}
也可以设置CreateProcess STARTUPINFO结构中的 lpDesktop 把独立的窗口过程运行在winlogon桌面
不过还需要把窗口过程建立在外部程序里
三. 创建自己的窗口过程
随意而为啦。窗口美化一下,做到许多流行软件的样子也不难。不过类似指纹扫描登录的那种,需要控制登录过程,有空可以研究下
以上演示源码,可以到我的资源里下 xp测试 vista没环境
http://download.csdn.net/source/1033737
本文来自CSDN博客,转载请标明出处:http://blog.csdn.net/xisat/archive/2009/02/23/3926957.aspx