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.