UTILMAN是什么?
UTILMAN是辅助工具管理器,里面有放大镜,屏幕键盘,据说还有“讲述人”,是M$方便残疾人用的(放大镜是给近视用的?近视的也算残疾了?。。。。)。
为什么要弄它?
说WIN+U也是SYSTEM权限,传说WIN+U能调出UTILMAN。那把CMD命名成UTILMAN替换了不就行了。但是似乎没有这么简单。替换过后,WIN+U似乎没有出现我们想要的界面,但是进程是有的。没有让我们输入的CMD,怎么加用户?那就看看怎么回事吧!
黑盒分析:
正常WIN+U,会发现有两个UTILMAN进程,一个是ADMINISTRATOR用户的,一个是SYSTEM用户的。用Process Explorer查看,发现ADMINISTRATOR用户的父进程是SYSTEM用户的UTILMAN,而SYSTEM用户的UTILMAN的父进程是WINLOGON.可以YY一次啊,WIN+U让Winlogon启动了UTILMAN,然后这个UTILMAN又启动了一个UTILMAN,最终呈现给用户。
分析DEMO:直接把cmd.exe覆盖到system32目录和system32\dllcache目录下的utilman.exe,然后WIN+U。
结论:CMD没有向用户呈现出来,只发现一个UTILMAN进程。
那根据以上的现象,似乎可以判定另外一个UTILMAN就是UTILMAN本身创建的。
逆向分析:IDA+OD上。用IDA加载,OD单步,先是检查是否是PE文件,

代码:
 .text:01004F02                 mov     eax, ds:100003Ch ; 查看文件是否是PE

.text:01004F07                 lea     eax, [eax+1000000h]

.text:01004F0D                 cmp     dword ptr [eax], 4550h
复制代码继续走,发现都是一些初始化的东西,一路跳过,来到 
代码:
.text:0100504B                 push    ecx

.text:0100504C                 push    eax

.text:0100504D                 push    ebx

.text:0100504E                 push    1000000h

.text:01005053                 call    InitialUtilman
终于是真正的东西了。OD步入,IDA跟进。来到这个地方,发现问题了 
代码:
.text:01001B65 SetCurrentWorkStation proc near         ; CODE XREF: InitialUtilman+7Ep
用Process Explorer可以看到,SYSTEM的UTILMAN的WORKSTATION是

而ADMINISTRATOR的UTILMAN是 
有一个STATION不一样,打开ADMINISTRATOR的STATION,在运行CMD,那是不是可以显示出来呢?结果是可以的,后面给出DEMO CODE。
然后继续往下走,终于发现了检查当前用户桌面 
代码:
.text:01001BDD ; int __stdcall CheckDestop(LPWSTR username, int)
里面判断是Default,Winlogon,screen-saver,还是Display.Cpl Desktop,然后给某个变量赋值。但是能力有限,这个变量还不知道在哪用。。。
一路往下走,来到了关键的地方。
代码:
 .text:01004CC8 loc_1004CC8:                            ; CODE XREF: InitialUtilman+CBj

.text:01004CC8                 mov     eax, [ebp+var_228]

.text:01004CCE                 sub     eax, 15h

.text:01004CD1                 jz      short loc_1004CFC

.text:01004CD3                 sub     eax, 4

.text:01004CD6                 jz      short loc_1004CF3

.text:01004CD8                 sub     eax, 0Ch

.text:01004CDB                 jz      short loc_1004CEC

.text:01004CDD                 dec     eax

.text:01004CDE                 jz      short loc_1004CE8

.text:01004CE0                 sub     eax, 3

.text:01004CE3                 jz      short loc_1004CEC

.text:01004CE5                 dec     eax

.text:01004CE6                 jnz     short loc_1004D03
这些判断最终有3个结果,如图  
一个是创建一个utilman的进程,传入参数/start,一个是设置一个事件,然后等待事件的线程唤醒,然后执行某个操作,第三个是加载UMANDLG.DLL
看看第三个。居然把界面放到了这个DLL里面,我们单独调用看看
代码如下
代码:
 #include <windows.h>

typedef int (__stdcall *UMANDLG)(int a,int b,int c);

UMANDLG UManDlg;

int WinMain( IN HINSTANCE hInstance, IN HINSTANCE hPrevInstance, IN LPSTR lpCmdLine, IN int nShowCmd )

{

        HMODULE hMoudule=LoadLibrary("UManDlg.dll");

        if (hMoudule==NULL)

        {

                        MessageBox(NULL,"err","tip",MB_OK);

                        return 1;

        }

        UManDlg=(UMANDLG)GetProcAddress(hMoudule,"UManDlg");

        if (UManDlg==NULL)

        {

                MessageBox(NULL,"err2","tip",MB_OK);

                return 1;

        }

        UManDlg(1,1,2);

        MessageBox(NULL,"test","tip",MB_OK);

        FreeLibrary(hMoudule);

        return 0;

}
发现有时候行,有时候不行。。。正当我向CJWNull大牛诉苦的时候,突然发现,如果之前正常调用UTILMAN,也就是SYSTEM的UTILMAN还在时,调用这个DLL成功出现了对话框,但是里面只有资源,调用放大镜等的功能还是空的。如果SYSTEM的UTILMAN不在时,这个调用无效了。

虽然没有分析完全,但是可以大致猜想整个流程。WIN+U调出了SYSTEM的UTILMAN,这个进程检查了当前的STATION和接收用户输入的STATION,发现不对,然后设置了某个变量,然后在启动一个UTILMAN,这个进程检查到了那个变量,然后将STATION设置为WINSTA0,在设置了DESKTOP,然后顺利将界面呈献给用户。在逆向的过程中还发现了RPC系列函数,那么WINLOGON进程和别的进程通信可能就是用的RPC方式,这个很高级啊很高级。

那我们如何替换才能使WIN+U时出现界面呢?很简单,设置STATION为WINSTA0,然后在设置DESKTOP,然后搞定,代码见附件。

最后的想法,其实可以不用替换UTILMAN.exe,毕竟里面的东西很复杂。可以把UMANDLG.DLL替换掉,它是个空壳子,如果在里面动手脚,效果会怎么样呢?

分析得不是很透彻,意在抛砖引玉。说法不正确的,还望各位高手指出,小弟先谢过了!
Desktop Test.rar