Wednesday, June 3, 2009

"Did you forget to check something?"


NTSTATUS: STATUS_KABOOM


Some .net applications have been behaving strangely... Actually, practically all of them have been behaving strangely, but consistently. They crash after
approximately 5 seconds upon starting up. Obviously, it must be something I did.

The reported error:

Description:
Stopped working

Problem signature:
Problem Event Name: APPCRASH
Application Name: MyApp.exe
Application Version: 1.0.0.0
Application Timestamp: 49f5e887
Fault Module Name: mscorwks.dll
Fault Module Version: 2.0.50727.1434
Fault Module Timestamp: 4757b767
Exception Code: c0000005
Exception Offset: 001496a2
OS Version: 6.0.6001.2.1.0.256.4
Locale ID: 1033


Upon debugging, the crash consistently fails at the below piece of code in mscorwks.dll (highlighted in the red box):














... where the value of the register esi is zero(0):








The Call Stack:











The modules list indicating the base address of mscorwks.dll:





Upon inspection of the disassembly, it is immediately obvious that it is a poorly written bit of code related to the 2 instructions before the faulting instruction at address 7148FF92.

The return from the (function) call at 7148FF8A is not checked for zero/NULL before being used as a pointer:

Call function:

7148FF8A call dword ptr ds:[71EB3244h]



Save the return value of the function call from the register eax into the register esi:

7148FF90 mov esi,eax


Use the value in esi as a dword pointer with offset 0Ch(0xC) and store the value at the address into eax. It appears likely to be code to get a value from the address of a struct at offset 0Ch and save it into eax:

7148FF92 mov eax,dword ptr [esi+0Ch]


The value from the struct member is then saved into a local variable via eax:

7148FF95 mov dword ptr [ebp-14h],eax



Now, there is one more detail I have not mentioned until now, and that is, the .net application(s) are being injected with a DLL as soon as its process is created. This is the 'something' I must have done, and did. This is the scenario where it is experiencing this crash. If the .net processes are being injected with a DLL after (not instantly) it has started up and running, then there isn't a problem.

So, even if the .net process is being injected with a DLL immediately after its creation, why should there be a problem? All other Win32 processes do not have this problem. If someone is going to tell me that I shouldn't be doing something like this, yadda yadda yadda, then I'd tell them to talk to the hand.

In any case, back to the crashing code, it is clearly a situation where the return value of the function being called can be a NULL (seems obvious to be a pointer) value, and it was never checked prior to being used. Although I don't know what the operational implications are to the returned pointer being NULL, I expect the .net framework to handle it properly and either return with an error gracefully, or raise a .net exception instead of crashing out.

Oh, and some nice folks at Microsoft are kind enough to take a look into this. It's very much appreciated.

2 comments:

  1. Hello, I'm Jon, a program manager on the CLR team. Someone in the Visual Basic MVP community pointed me to your post. I'm sorry you're running into issues.

    If you'd like to create a Connect bug for this issue, we'd be happy to look into it for you (you can use the URL in my signature). You'll need to provide more information on how you're "injecting" your dll into the process and possibly what the dll does (a simple repro is fine). Feel free to drop me an e-mail (jlangdon AT microsoft DOT com) when you've created the bug. I'll see that it gets routed correctly. Regards,
    Jon

    ReplyDelete
  2. Hi Jon, it's mighty nice of you to drop a note, and thanks very much for your assistance.

    I will send you an email with more details on the bug, and hope that it would be of some help.

    Thanks again, and your assistance is much appreciated.

    ReplyDelete