The case of Task Manager that does not kill

Quite long time ago, my friend Vadym Stetsiak described a bug of Task Manager, which allows to disallow (!) the killing of a process, if it’s name is lsass.exe. In order to test this bug, you can rename any executable file into lsass.exe, run it, and than try to kill it from Task Manager. You will fail to kill it under XP:

One year passed. Many updates were released by Microsoft. However, this bug is still present, and it still remains in upcoming SP3 for Windows XP. I checked the latest RC for XP SP3, and the same happens. I asked myself – why? In order to answer this question I did the following:

I opened WinDbg. Attached to running instance of Task Manager. In command window of debugger I typed:

0:003> bp user32!MessageBoxW
0:003> bl

0 e 7e46630a     0001 (0001)  0:**** USER32!MessageBoxW

This action sets breakpoint to MessageBoxW – I just want to catch the moment, when I see msgbox saying that lsass.exe is a critical process, that cannot be deleted. I rename some executable into lsass.exe, and run it. Then I try to kill this application via Task Manager. Breakpoint is hit, I see the following code:

0100c169 50                push    eax
0100c16a ff7304           push    dword ptr [ebx+4]
0100c16d ff1528120001 call    dword ptr [taskmgr+0x1228 (01001228)] ds:0023:01001228={USER32!MessageBoxW (7e46630a)}

However, I need to know the previous location which called this chunk of code. To do that, I need to analyze the region of code which is upper the call to MessageBoxW. To do that, I would use IDA.

So, I load into IDA the file C:\Windows\System32\taskmgr.exe. Wait untill the file is parsed. Then I jump to 0100c16d:

Press G and specify 0100c16d:

.text:0100C15C                 lea     eax, [ebp+Caption]
.text:0100C162                 push    eax             ; lpCaption
.text:0100C163                 lea     eax, [ebp+Text]
.text:0100C169                 push    eax             ; lpText
.text:0100C16A                 push    dword ptr [ebx+4] ; hWnd
.text:0100C16D                 call    ds:MessageBoxW

This is exactly what I need. I try to locate the xref to this portion of code. And I see, that this code is called from the following address (the only one xref):

.text:0100C0EE                 push    ds:off_1001F14[edi] ; lpString2
.text:0100C0F4                  push    dword ptr [esi+88h] ; lpString1
.text:0100C0FA                 call    ds:lstrcmpiW                             ; compare name of selected process with some string
.text:0100C100                  test    eax, eax
.text:0100C102                  jz      short loc_100C11D                     ; call MessageBoxW if comparison is OK

As you can see, there is a string comparison which is done using lstrcmpiW function. Let’s see, what data is comparing when this code executes:

0:003> bp 0100C0FA
0:003> g

Trying to kill again fake lsass.exe, the breakpoint hit, I see the following data passed as params to lstrcmpiW: сsrss.exe, winlogon.exe, smss.exe, services.exe and finally, lsass.exe. So, as it logically outcomes from research, these names are hardcoded into Task Manager, and are treated as a special processes, however, the check is buggy: I would rather make a check against process path, not just the process name.



  1. Interesting. Very. How hard will be to patch the taskman to disable this check alltogether anyway?
    I also wondered, for a long time, if the executable OR the parameter / option witch run it, after Ctrl Alt Del press cannot be modified to give it realtime (highest) priority. I once brought this on MSFN network and recieve ban after stating that I did not care that M$ own the code. Hey, I own my Windows 2000, did not I?

Leave a Reply
