Winlogon原理

自己写Winlogon必须实现以下技术细节:

1.首先建立WindowStation,名字必须为Winsta0;因为某内核模式的程序里有对Winsta0的引用
2.建立三个桌面;首先必须建立winlogon名字的桌面,因为win32k.sys里有对winlogon名字桌面
的引用;接着建立default桌面,因为explorer必须运行在default桌面上,如果在winlogon桌面上,
会内存泄露,时间长了,有时会莫名其妙的挂起(这个我没有深究,估计"Default"桌面也在哪个
系统库里,显式的引用了)
3.对winlogn桌面进行安全设置(可不进行) Enable必须的特权,
4.启动services.exe;services.exe首先创建一个同步对象,然后WaitForSingleObject挂起等待它
5.启动lsass.exe;lsass用NtConnetPort到winlgon。NtConnectPort失败的话就挂起,这样整个
winlogon也就挂起不继续了,等效于死机了,然后lsass把services.exe建的同步对象状态设置成激活,
这样service.exe得到lsass启动的信号,就resume了.
所以这里必须创建lsass连接到winlogon的对象 这个对象暂时我还没有研究出来,但lsass.exe创建udp
500端口 可能为Ntcreateport创建端口 这个正在研究中

 

 

MS的winlogon首先建立WindowStation,即Winsta0,自己实现的话,
WindowStation的名字也必须是winsta0,否则...,然后建立三个桌面,
自己实现的话,必须建立名字叫winlogon的桌面,不能随便命名,因为
win32k.sys里面有对叫winlogon名字的桌面的引用。同时,应用程序explorer.exe
必须运行在default桌面上,如果在winlogon桌面上,会内存泄露,时间长了
有时会莫名其妙的挂起(这个我没有深究,估计"Default"桌面也在哪个系统库里
显式的引用了),所以这两个桌面是必须筹建的。至于screensaver桌面,我没有
建立他,因为我不用屏幕保护。有兴趣的人可以自己试验不建立它运行瓶保会
非法操作还是蓝屏。

建立桌面并对winlogn桌面进行安全设置后,启动services.exe。services.exe首先
创建一个同步对象,然后WaitForSingleObject挂起等待它。紧接着winlogon启动
lsass,lsass用NtConnetPort到winlgon。NtConnectPort失败的话就挂起,这样整个
winlogon也就挂起不继续了,等效于死机了。然后lsass把services.exe建的同步对象状
态设置成激活,这样service.exe得到lsass启动的信号,就resume了。所以仅仅替换
winlogon的话,由于
没有了lsass,services.exe就挂起了,因此它也不会去执行rpc了,这样Explorer也就
不会出桌面了。

所以需要修改services.exe。直接把WaitForSingleObject调用给nop掉即可。
至于services.exe为什么要等待lsass呢,请看续篇

(待续)
windows的设备管理器中装驱动、卸驱动和禁用启用某个设备的本质是mmc
用RPC call services.exe来实现的。要干这活,services.exe必须有
SeLoadDriverPrivilege和SeUndockPrivilege。这两权限在Administrator
用户中是default disabled,services.exe是用LookupPrivileges和
AdjustTokenPrivileges这两个advapi32.dll函数实现的,很变态的是
advapi32.dll啥活也不干,直接RPC call一下lsass.exe,让它干。
改权限的话,本质上用RtlAdjustPrivilege一个native函数就可以了,
MS却变态的要经过极其没有效率的三重掉用...

因此,没有lsass的话,我们必须:
1. 在winlogon里用RtlAdjustPrivilege enalbe所有你可能要用到的权限,
因为权限是继承的,而所有桌面程序都是由winlogon的进程树。
2. 修改advapi32.dll,把LookupPrivilegeValue和AdjustTokenPrivileges的
入口点改成return TRUE,不然应用程序有了权限还会认为它没有权限。
3. services.exe链接的umpnpmgr.dll很变态,它还会检查LookupPrivilegeValue
返回的参数是否为0,它调用2次LookupPrivilegeValue,查询SeLoadDriverPrivilege
和SeUndockPrivilege的值。所以只需要把这两处
LookupPrivilegeValue(lpSysName, lpName, PLUID)改成 *PUID = 10和
*PUID = 25(对应这两privilege的值),再xor eax, eax, inc eax就可以

需要patch的文件基本上就是services.exe相关的这2个文件。
另外还有一个是aclui.dll,没有了lsass后,aclui.dll不patch一下的话
在regedit.exe里设置键的安全属性对话筐的“高级”按纽就点不开。
其他的不需要patch任何文件了。

另外,没有了lsass后需要自己编写一个msgina.dll,因为开始彩旦的关机
调用了msgina.dll的ShellShutdownDialog来显示关机对话筐。这个比较简单。
只需要一句:
extern "C" DWORD WINAPI ShellShutdownDialog(HWND hParent, WCHAR *Username,
BOOL bHideLogoff)
{

        return DialogBox(MyDllHandle, MAKEINTRESOURCE(IDD_SHUTDOWNDLG),
hParent, DialogProc); 

}
BOOL CALLBACK DialogProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM
lParam)
{
...
}
然后在def文件里
LIBRARY MSGINA
EXPORTS
ShellShutdownDialog
就可以了,至于你想把关机做成什么样子随你代码的便
(待续)
这几天准备做一个patch的exe,能针对不同版本的2k和xp进行对
services.exe和他连接的umPnpMgr.dll patch以及恢复以前设置,这样
大家可以对比下前后的开机速度和内存占用,也可以自己DIY自己的
winlogon,添加一些特殊的功能(用ms的gina替代功能限制太大)

 

你可能感兴趣的:(Winlogon原理)