Chrome the web?

Yesterday Google launched a beta version of its own browser called Chrome. So I gave a try and my first feeling was that it works faster than IE or FireFox. I am among those 20 % of people in the world who are using FireFox all the time (just because it does not bring a new window dialog when you do a search on page :) ) and I can see that Chrome does not bring any extra ordinary new features, it just combines many useful features of FireFox and IE. Will surf more to see if it really faster than competitors. 

Undeletable bug in VS2008?

I see this bug for a quite a long time, starting from VS2005. To illustrate the problem:

1. Go to project properties, open some tab

2. Do not close the property dialog windows simply change the focus by clicking in code editor

Once you click in code editor, you property window is gone, and you see an empty dialog which looks like this:

Did not expect to have it in 2008 Studio as it seems toooo obvious and tooo easy to reproduce ;)

a great achievement of community

For a quite long period of time I heard about the popularity of Ubuntu Operating System so I decided to give a try to see whether I am able to move on it without pain.

My interests in linux were growing for a long time, starting from the moment of my first experience with Vista – it was really bad in terms of performance and stability. The bottleneck for me was performance. I was not able to get more or less good performance in my AMD X2 1.6 MHz notebook with 1 GB of RAM when using Vista. So after using it for a few month, I finally made a downgrade to XP SP2.

Now, when Vista is pushing harder and harder on market and XP becomes deprecated I have a choice to upgrade my hardware and buy Vista, or to find less resource consuming operating system and to achieve:

- the same or better performance than in XP

- money savings because there is no need to buy new hardware

- new experience (well, sometimes I feel myself too microsofized, so I just want some fresh air and new experience)

So, I decided to move on Ubuntu hardy 8.04. For those who have no idea what is Ubuntu, please visit http://www.ubuntu.com/. Just not to loose my original XP installed on laptop I decided to test it at first in virtual machine (unfortunately for me, Microsoft Virtual PC was unable to emulate Ubuntu so I used VmWare) and to my surprise Ubuntu was able to detect XP installation and suggested me to have dual boot. Wonderful. After some tests in virtual machine I crossed my fingers, made a deep breath and installed it on my real machine.

Installation was OK, and I did not loose my XP. It took some time to configure software I use for everyday life at home: skype, icq client, hamachi, media players, gnotifier and finally I am happy linux user now :).

Everything works smoothly when being correctly configured. But even for those who does not want to bother himself with apt-cache search and apt-get install commands, the default installation of Ubuntu installs everything what an ordinary user needs to use. This includes firefox, openoffice, media applications, graphic applications, etc. The question arises: why actually should someone pay money for Windows, if he or she can get the same basic functionality for free ;) ?

Russian translation for all posts is added

I decided to translate posts into Russian language. So starting from now all my posts are translated into two languages: English and Russian. I hope this will be useful for Russian speaking community.

Look to the right, there should be a language selection link.

A case of mysterious BSOD at tcpip!TcpIndicateData+22b

1. The causes

Recently I was observing strange BSODs on my Vista machine quite periodically when dealing with network applications:

2. Investigations

As you can see the BSOD happens because the tcpip.sys is trying to access some wrong address. Luckily, I was able to access the dump file generated during this BSOD. When I try to execute the analyze command, I get the following output:


0: kd> !analyze –v
DRIVER_IRQL_NOT_LESS_OR_EQUAL (d1)
An attempt was made to access a pageable (or completely invalid) address at an
interrupt request level (IRQL) that is too high.  This is usually
caused by drivers using improper addresses.
If kernel debugger is available get stack backtrace.
Arguments:
Arg1: 00000004, memory referenced
Arg2: 00000002, IRQL
Arg3: 00000000, value 0 = read operation, 1 = write operation
Arg4: 8348780f, address which referenced memory

MODULE_NAME: tcpip

FAULTING_MODULE: 8183b000 nt

DEBUG_FLR_IMAGE_TIMESTAMP:  47919120

READ_ADDRESS:  00000004 

CURRENT_IRQL:  2

FAULTING_IP:
tcpip!TcpIndicateData+22b
8348780f 8b4304          mov     eax,dword ptr [ebx+4]

DEFAULT_BUCKET_ID:  WRONG_SYMBOLS

BUGCHECK_STR:  0xD1

LAST_CONTROL_TRANSFER:  from 8348780f to 81895d84

STACK_TEXT:
WARNING: Stack unwind information not available. Following frames may be wrong.
84546998 8348780f badb0d00 00000001 845469d0 nt!Kei386EoiHelper+0x291c
84546a8c 8348746a 00000000 87df0148 84546b08 tcpip!TcpIndicateData+0x22b
84546ad4 834878f4 84547000 00000000 84546b08 tcpip!TcpDeliverDataToClient+0x162
84546af8 83483a17 9b805408 9b8054f4 8c3072f0 tcpip!TcpDeliverReceive+0x71
84546b38 83484444 9b805408 84546b58 84546b8c tcpip!TcpTcbFastDatagram+0x2b9
84546b98 83483f47 86f304d0 00805408 84546bfc tcpip!TcpTcbReceive+0xf8
84546bf0 83483d40 86f304d0 9424d1e0 00000000 tcpip!TcpMatchReceive+0x1ec
84546c38 8348433c 86f304d0 9424d1e0 9424d118 tcpip!TcpPreValidatedReceive+0x2b0
84546c54 8348493f 86f304d0 9424d1e0 84546c90 tcpip!TcpReceive+0x32
84546c64 834af013 84546c78 c000023e 00000000 tcpip!TcpNlClientReceiveDatagrams+0x12
84546c90 834aedd6 83505e50 84546ce4 c000023e tcpip!IppDeliverListToProtocol+0x49
84546cb0 834aecfd 83505c68 00000006 84546ce4 tcpip!IppProcessDeliverList+0x2a
84546d08 834a6187 83505c68 00000006 8193d13c tcpip!IppReceiveHeaderBatch+0x1eb
84546d30 81a5723b 86381598 00505c68 831eb020 tcpip!IppLoopbackTransmit+0x52
84546d44 8187341d 861c4fe0 00000000 831eb020 nt!LpcRequestPort+0x525
84546d7c 81a10a1c 861c4fe0 ed23e69f 00000000 nt!KeQuerySystemTime+0x14d
84546dc0 81869a3e 81873320 00000001 00000000 nt!RtlDestroyAtomTable+0x4fe
00000000 00000000 00000000 00000000 00000000 nt!RtlSubAuthorityCountSid+0x3c4

… which is very strange. The stack contains only Windows native components, no guilty third party driver can be seen here. Let’s try to get more details from the faulting code. Since the function is really big ( you may check this by invoking uf tcpip!TcpIndicateData ) I will concentrate on a near code, which is close to failure address 8348780f:

0: kd> u 834877f6 83487822

tcpip!TcpIndicateData+0x212:
834877f6 e80cceffff      call    tcpip!TcpNetBufferListChainDelay (83484607)
834877fb 8365fc00        and     dword ptr [ebp-4],0
834877ff 8b5dfc          mov     ebx,dword ptr [ebp-4]
83487802 eb60            jmp     tcpip!TcpIndicateData+0x280 (83487864)
83487804 2bca            sub     ecx,edx
83487806 03cf            add     ecx,edi
83487808 8bf3            mov     esi,ebx
8348780a 895d14          mov     dword ptr [ebp+14h],ebx
8348780d 7455            je      tcpip!TcpIndicateData+0x280 (83487864)
8348780f 8b4304          mov     eax,dword ptr [ebx+4]
83487812 8b400c          mov     eax,dword ptr [eax+0Ch]
83487815 3bc8            cmp     ecx,eax
83487817 720f            jb      tcpip!TcpIndicateData+0x244 (83487828)
83487819 2bc8            sub     ecx,eax
8348781b 8b03            mov     eax,dword ptr [ebx]
8348781d 8bf3            mov     esi,ebx
8348781f 8945fc          mov     dword ptr [ebp-4],eax

The line where BSOD occurs is marked as bold. Unfortunately, nothing obvious at this point. TcpIndicateData is undocumented, and even Google does not bring any information about it. OK, I doubt there is a problem with tcpip.sys driver, most likely, the BSOD is caused by some third party driver. However, how can I find it if I am unable to get the relevant stack information from “analyze –v” command?

Well, at this point I can try to take a look at raw stack trace by issuing: dps esp - 3000 esp + 3000 in debugger:

 

0: kd> dps esp - 3000 esp + 3000
84543980  ????????

[...]

845464e0  8b92f065 crashdmp!WriteKernelDump+0x83
845464e4  00000000
845464e8  0003d229
845464ec  00000000
845464f0  00000000
845464f4  8b933270 crashdmp!Context+0x20
845464f8  00000000
845464fc  000089da
84546500  000079b8
84546504  00000004
84546508  84546520
8454650c  8b92f1bd crashdmp!DumpWrite+0x7b
84546510  0003d229

[...]

845465f8  8196a2a0 nt!KiBugCheckData+0x20
845465fc  8348780f tcpip!TcpIndicateData+0x22b
84546600  831eb020

[...]

84546944  00000001
84546948  9b805408
8454694c  8a56ca3a tdx!TdxEventReceiveConnection+0x326
84546950  84546978
84546954  86ec6238
84546958  89c1a0d0
8454695c  00000000
84546960  931a7c70 somedrv+0x1c70
84546964  86f51e70
84546968  00000c20
8454696c  00000001

I removed unnecessary stack data just for the sake of clearance. In this stack trace you see at the top the calls made by system to generate BSOD dump file (crashdmp!WriteKernelDump), then goes a sequence of TcpIndicateData, TdxEventRecieveConnection and finally some call to somedrv+0×1c70. Well, it gives me some hints already.

Now I have suspicious list with two elements, tdx.sys and somedrv.sys. If I try to search at msdn.microsoft.com with keyword tdx.sys I finally find this: “TDI filter drivers are supported on Windows Vista by a compatibility layer called TDX” at http://support.microsoft.com/kb/933049 . So, it seems like I am dealing with TDI staff. Just to prove this idea I am using Ida Pro to analyze suspicious driver named somedrv.sys and I find that this driver filters \Device\Tcp using IoAttachDevice (…) :

.text:00015D8F                 push    eax             ; SourceString
.text:00015D90                 lea     ecx, [ebp+TargetDevice]
.text:00015D93                 push    ecx             ; DestinationString
.text:00015D94                 call    ds:RtlInitUnicodeString
.text:00015D9A                 mov     edx, [ebp+AttachedDevice]
.text:00015D9D                 push    edx             ; AttachedDevice
.text:00015D9E                 lea     eax, [ebp+TargetDevice]
.text:00015DA1                 push    eax             ; TargetDevice
.text:00015DA2                 mov     ecx, [ebp+DeviceObject]
.text:00015DA5                 mov     edx, [ecx]
.text:00015DA7                 push    edx             ; SourceDevice
.text:00015DA8                 call    ds:IoAttachDevice 

Well, I become more and convinced that this problem is caused by the faulty TDI client named “somedrv.sys”. Removing the driver from system finally solves my problem, and I become a happy Vista user which does not experience mysterious bsods … for a while :)

3. Conclusions

The main conclusion is that analyze –v does not always help to resolve the real problem. While being very and very useful for major cases of crashes, analyze –v does not guarantee to provide 100 % useful data about the crash, and in such cases the raw stack analysis can help.

Third time to become MVP

Today I received a really great news: I am MVP for a 3rd time!

This is my third “first of July” which brings me exciting news. This time I receive award in DDK profile, which is something different from what I had before. My first nomination was SDK area (2005 - 2006), second was also SDK (2006 - 2007), and third is DDK (2007 - 2008) area nomination. Well, … what can I tell … : thanks Microsoft :) I'll try to do my best to share my experience and my knowledge with people shedding lights upon Windows programming issues.

This year brings me more advantages of being MVP, and one of many is being able to access Windows source code (as a participant of Microsoft Code Premium Program) which is something great, because it gives a chance to read and understand the code of all currently shipping OS which multiplies the understanding of how things actually work.

Mysterious ExUuidCreate function

I was inspired to write this post after being confused by behaviour of ExUuidCreate function in Windows Vista.

This function is used to generate GUIDs at kernel mode. According to documentation: "ExUuidCreate returns STATUS_SUCCESS if successful; otherwise, if the system is not ready to generate a new UUID, it returns STATUS_RETRY."

Practically, if you call this function say in driver which is loading by boot loader (if the driver has "Start" registry value equal to 0 due to SERVICE_BOOT_START flag set when creating service using CreateService) you can observe strange behaviour, especially in Vista.

Under strange behaviour I mean the following: function fails, but it actually copies the data into buffer. In other words, function creates GUID although it is failing :) To illustrate this problem, I created a small NT driver which is loading by boot loader (i.e., its "Start" value is set to zero). Driver just calling the function multiple time on a separate thread until the call to ExUuidCreate succeeds.

The thread function is implemented as following:


/**   A thread function which is actually calling ExUuidCreate(...) multiple times
    * @param lpParam pointer to user data

    * @return always 0x13
*/
VOID PollingThread(unsigned char * lpParam)
{
	KEVENT WaitEvent			= {0};			///	wait object
	BOOLEAN bIsSucceded			= FALSE;		///	is operation succedded
	unsigned char bGUID[16]		= {0};			///	buffer to hold guid
	LARGE_INTEGER liInterval	= {0};			///	timeout buffer
	liInterval.QuadPart			= -10000000;	/// one second wait

	///	init event object
	KeInitializeEvent(&WaitEvent, SynchronizationEvent, FALSE);

	while (!bIsSucceded)
	{
		///	try to obtain guid value
		bIsSucceded = (ExUuidCreate((UUID*)&bGUID) == STATUS_SUCCESS);

		///	if function has failed ...
		if (bIsSucceded == FALSE)
		{
			KdPrint(("The call to ExUuidCreate(...) failed. "));

			if (IsEmpty(bGUID))
			{
				KdPrint(("All bytes in GUID are zero. \r\n"));
			}
			else
			{
				KdPrint(("GUID is actually generated: "));
				PrintHexValues(bGUID);
			}
		}
		else
		{
			KdPrint(("The call to ExUuidCreate(...) succeded. Bytes: "));
			PrintHexValues(bGUID);
		}

		///	is used to put thread into sleep state for 1 minute
		KeWaitForSingleObject(&WaitEvent, Executive, KernelMode, TRUE, &liInterval);
	}

	///	exit the thread
	PsTerminateSystemThread(0x13);
}

As you can see, the code is very simple. When being executed in Vista under normal conditions, for example, when the OS is already loaded, the code outputs the following results:


00000000	0.00000000	The call to ExUuidCreate(...) succeded. Bytes:
00000001	0.00029110	20ea90276610dd11bbe2000c291a2f

However, if the machine gets rebooted, one can notice in debugger, that the function ExUuidCreate fails, but the data actually is copied into the buffer:

The most interesting happens if you try to debug this function. Reboot OS in debug mode, attach WinDbg, and wait until loader loads the driver. Wait until the thread PollingThread is created, and the call to ExUuidCreate is done. Turn on Disassembly window in WinDbg, and analyze code:

(Standard function prolog which is committing stack and initializes local variables)


819b68d1 8bff            mov     edi,edi
819b68d3 55              push    ebp
819b68d4 8bec            mov     ebp,esp
819b68d6 83e4f8          and     esp,0FFFFFFF8h
819b68d9 83ec14          sub     esp,14h
819b68dc 8364240400      and     dword ptr [esp+4],0
819b68e1 53              push    ebx
819b68e2 56              push    esi
819b68e3 57              push    edi

(Obtaining references to global variable ExpUuidCachedValues and storing them in eax, ecx, ebx)


819b68f0 a140a3b181      mov     eax,dword ptr [nt!ExpUuidCachedValues (81b1a340)]
819b68f5 8b0d4ca3b181    mov     ecx,dword ptr [nt!ExpUuidCachedValues+0xc (81b1a34c)]
819b68fb 8b1d44a3b181    mov     ebx,dword ptr [nt!ExpUuidCachedValues+0x4 (81b1a344)]
819b6901 89442418        mov     dword ptr [esp+18h],eax ss:0010:87304d38=00000008

This part is interesting, more interesting is to answer the question, what is the role of ExpUuidCachedValues in GUID generation process? So lets do more research,


1: kd> db 81b1a340
81b1a340  00 00 00 00 00 00 00 00-ff ff ff ff 00 00 80 6e  ...............n
81b1a350  6f 6e 69 63 00 00 00 00-00 00 00 00 00 00 00 00  onic............
81b1a360  88 ff ff ff c4 ff ff ff-02 00 00 00 00 00 00 01  ................
81b1a370  c4 ff ff ff 40 00 74 00-7a 00 72 00 65 00 73 00  ....@.t.z.r.e.s.
81b1a380  2e 00 64 00 6c 00 6c 00-2c 00 2d 00 33 00 32 00  ..d.l.l.,.-.3.2.
81b1a390  32 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00  2...............
81b1a3a0  00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00  ................
81b1a3b0  00 00 00 00 00 00 0a 00-05 00 03 00 00 00 00 00  ................

It seems, that ExpUuidCachedValues is some structure, which holds some values, which are updated by system and are copied into GUID buffer passed by user to ExUuidCreate function; lets continue:


819b6905 8b4508          mov     eax,dword ptr [ebp+8] ss:0010:87304d48=87304d50
819b6908 894808          mov     dword ptr [eax+8],ecx
819b690b 8b0d50a3b181    mov     ecx,dword ptr [nt!ExpUuidCachedValues+0x10 (81b1a350)]
819b6911 89480c          mov     dword ptr [eax+0Ch],ecx

Voila! This piece of code writes into buffer which was passed by user into ExUuidCreate. The write value is stored in ECX, which is pointing to [nt!ExpUuidCachedValues+0xc]. In other words, at the begining the function ExUuidCreate takes some field from ExpUuidCachedValues and writes it down into user buffer without taking care about return value of function. It means, that even if later the function might fail, the content of user buffer is altered already.

Just to prove at this point that the write operation is done into user buffer I output the content of buffer which was passed into ExUuidCreate:


1: kd> db 0x87304d50
87304d50  00 00 00 00 00 00 00 00-85 da 80 6e 00 00 00 00

As you can see, at this moment the buffer is not fully zeroed as it was before. Lets go deeper inside the function. It operates with several global variables, and finally it also touches user buffer:


819b6a27 99              cdq
819b6a28 2bf0            sub     esi,eax
819b6a2a 8b4508          mov     eax,dword ptr [ebp+8]
819b6a2d 1bda            sbb     ebx,edx
819b6a2f 66895804        mov     word ptr [eax+4],bx
819b6a33 c1eb10          shr     ebx,10h
819b6a36 6681e3ff0f      and     bx,0FFFh
819b6a3b 6681cb0010      or      bx,1000h
819b6a40 84c9            test    cl,cl
819b6a42 8930            mov     dword ptr [eax],esi

Now the user buffer looks like:


0: kd> db 0x87304d50
87304d50  79 59 e4 06 8c 43 dd 11-85 da 80 6e 6f 6e 69 63

On next iteration:


0: kd> db 0x87304d50
87304d50  7a 59 e4 06 8c 43 dd 11-85 da 80 6e 6f 6e 69 63

Again, on next iteration:


0: kd> db 0x87304d50
87304d50  7d 59 e4 06 8c 43 dd 11-85 da 80 6e 6f 6e 69 63

As if you have mentioned, the first byte is changing all the time. Wonderful, on each call the function gives unique values, although it is failing! Well, I suggest MSFT to documented this behavior, or at least explain this case in documentation.

If you would like to repeat this case, please download full sources of the driver here: sources.

A change for SoftIce

As SoftIce is officially dead, you might want to find its substitution. There is one product which aims to fully substitute SoftIce – Syser debugger, which proposes pretty close user interface, and “live” debugging of kernel on a host machine:

According to documentation, all command line commands are fully softice compatible (you can check all commands in help file which is included in trial version of the product). The whole user interface is pretty close to SoftIce, but with the following differences:

1. Al frames are "more windows like"

2. You have more advanced context menu when clicking on item (which results in more advanced possibilities, for example, changing comments just after the instruction)

3. More user friendly colors highlights. For example, if you hit the line "jz address" and the control is going to be passed to that address, the branch line is colored with yellow color

4. OllyDbg like "CPU" window, which shows are registers of CPUs

5. OllyDbg like "Stack window" with hints and some analysis

6. Possibility to insert bookmarks

7. Calculator :)

8. Virtual keyboard (it allows you to type cmds using only mouse)

9. Embedded PE Explorer

10. Separate windows for IDT, GDT, LDT, Processes, Modules and Pages

11. And much more …

After some time of work, I have a feeling, that this debugger was trying to achieve the power of SoftIce by its possibility to debug the kernel code on host machine, and the flexibility of OllyDbg by allowing to put comments, view things in different windows, highlighting the code branches, etc.

Even taking into account, that the whole debugger is more assembly oriented (unlike WinDbg), the Syser also has the possibility to debug drivers with sources (for this, it has "Source Explorer" window, which I personally did not use.

I personally think that Syser makes competition to all popular debuggers existing nowadays. I will try to compare it with each of them.

1. OllyDbg vs Syser

OllyDbg looses in debugging kernel mode code (it does not debug it at all). However it wins in more advanced assembly output, due to custom analyzer which shows params for all api functions, which makes more advanced static and dynamic analysis. I think that next version of Syser will cover this gap, and will take the advantage of OllyDbg by applying it to both kernel and user mode debugging.

2. SoftIce vs Syser

SoftIce looses in stability. SoftIce looses in many useful features like putting comments, having windows for things like gdt, idt, ldt, processes, and the rest. While the second issue is not that big, the first is a really tragedy (I mean the instability of SoftIce). The biggest plus of Syser is that it has support …

3. WinDbg vs Syser

Assembly debugging in WinDbg is something awful. It makes no analysis of assembly. It does not give any hints while analyzing the code. The assembly window is also not useful. You cannot scroll assembly, because it somehow screws up the whole view. WinDbg does not allow to do a kernel debug on host machine; it requires two computers for this. So, Syser simply wins in all this fields. However, WinDbg supports analysis for crash dumps, and it allows to analyze the Windows structures (dt command) if pdb symbols are properly set.

And now the sad facts. Once I heard about Syser, I visited the official web site, and downloaded the trial version here: http://www.sysersoft.com/download.html. Then I tried it in my virtual machines. All 5 (five) virtual machines had a BSODs. I also give a try, and installed it on my real home machine. And it also resulted in BSOD.

A few months later, I downloaded next version, which is working fine on my virtual machines, but it is totally usless on my real machine. When I try to launch debugger, the Syser console simply disappeares. Although I believe this will be fixed, it makes bad impression as a first expirience with debugger.

So, the top line of my post. Syser is a powerful debugger, and is "a must have tool" for engineers which are working with machine code at kernel level, but for the moment, the debugger is not yet stable, and it will take some time (I believe) to make it a hand tool for me.

New place for the blog

I always wanted to have an own domain, hosting mail, blog and probably some important files for me. However, I always felt the leak in time, and this direction was non primary for me. Until today.

As you probably have mentioned, the server msmvps.com (which is hosting http://msmvps.com/blogs/v_scherbina/) was dead for approximately one week. During these 7 days my brain reorganized some tasks, and I decided to make independent blog which (theoretically) will be constantly up : ).

So let’s welcome www.shcherbyna.com web site. I am going to move completely on this blog, but for some period of time I will be duplicating posts to “Ab origine” as well.