Thursday, December 24, 2009

Happy Holidays!


NTSTATUS: STATUS_W00T


Here's wishing everyone a Merry Christmas, and a Happy New Year! :)

Sunday, December 6, 2009

"You cannot be serious!"


NTSTATUS: STATUS_IS_NOT_WIN32


Following up from my previous post...

I found a novel way to crash WPF (.net 3.5 SP1). Here's how to do it:

Create a WPF DLL:
1. Create WPF User Control Library
2. Create a User Control, say, MyUserControl
3. Create another User Control, say, MySubUserControl
4. Add MySubUserControl (as a project control) into MyUserControl (in the XAML)

So now you have a user control that has a user control in it. Next:

Create an Application (I created a .net WinForm app):
1. Create a WinForm Application
2. Load the DLL created, via Assembly.Load(byte[] rawAssembly)
2.a. Create an instance of the type MyUserControl
2.b. Add the instance of MyUserControl in a container (I just put it into an ElementHost)
3. Repeat setps 2, 2.a. and 2.b.

Basically, in the WinForm app, you just need to run your code that does steps 2, 2.a. and 2.b. twice. I just execute that piece of code via a button's event, so I can run it by pressing the button twice.

On the second execution of the code, it crashes. The exception I got is:

"Cannot create instance of '
MySubUserControl' defined in assembly 'WpfControlLibrary1, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null'. Exception has been thrown by the target of an invocation. Error at object 'System.Windows.Controls.Canvas' in markup file 'WpfControlLibrary1;component/MyUserControl.xaml' Line 9 Position 6."


So, long story short, it seems that you can't multi-load, and re-instantiate a WPF user control, that has a user control inside it! You can imagine the shock my colleague was in for when I broke the news.

I was doing this basically to implement plug-ins. Tough luck, apparently... Who would expect this to happen? Certainly not me. This can't be right. It had me doing a Johnny Mac.

Saturday, October 24, 2009

"I thought you were still there..."


NTSTATUS: STATUS_IS_NOT_WIN32



This has to do with the .net CLR loading assemblies dynamically. Sure, it's not a Win32 thing, but it is related when I went about trying to achieve what I normally would in native Win32 apps.

The story begins quite simply, in implementing basic plug-in type architectures. When one did it in regular (native) Win32 apps with C/C++, you'd just use LoadLibrary() and FreeLibrary() to load and unload the relevant DLL's that would function as plug-ins.

Trying to achieve the same in .net, the methods from the Assembly class LoadFrom() and LoadFile() can be used to load an assembly at runtime. However, what's obviously missing is any method to unload those assemblies. After a little searching, we come across this. Apparently, there are plenty of reasons not to. So, this clearly begs the question, why it can be done in native Win32, and not in the .net CLR. From what I can tell, it's basically a case of trying to stop people from shooting themselves in the foot. In my case, I know exactly what I'm doing, and it's exactly what I intend to do. But too bad, everyone gets the same treatment.

It seems the closest is to read the entire assembly binary into memory, and use Assembly.Load(). Effectively, this gets the job done. So, problem solved. However, it wasn't so for me. The problem laid in WPF. This 'bug' is related to user controls and assembly loading, and I will write about that in a subsequent post.

So anyway, I wanted to see what would happen if I manually unloaded a .net assembly. I did the obvious thing having the assembly's path:

IntPtr hModule = Win32.GetModuleHandleW(assemblyPath);

if (hModule != null)
{
if (Win32.FreeLibrary(hModule))
{
Debug.WriteLine("DLL released...");
}
else
{
// failed
Debug.WriteLine("Failed to release DLL...");
}
}


Win32 in the above code is a class in which I declared the Win32 API functions. In any case, the assembly is unloaded from the process, piece of cake. So, the question now is, does anybody know about it? Obviously, the answer is NO. I suppose it is not reasonable for the .net CLR to check if the assembly is still there anytime it wanted anything from it. Heck, I wouldn't do that either since I did not let anybody else but myself do it.

Calling the code to load the assembly again does not result in the assembly being loaded again. Simply a matter of replacing the assembly with one with different content/code, and loading it again. As far as the CLR is concerned, it's already loaded. Fair enough. So the next time you called anything in the assembly, BOOM! It crashes as expected.

Oh, do note that there would still be a handle to the assembly (the DLL) in the process. It is no easy task to find the handle and close it, so I wasn't bothered as it wouldn't make any difference.

Freeing the .net DLL manually was really just a case of 'let's see what happens'. Not recommended for .net assemblies, but it's just regular for native Windows Win32 DLL's if you're working with them.

Thursday, October 8, 2009

"Who's your daddy, and what does he do?"


NTSTATUS: STATUS_NO_SUCH_PROCESS



Recently, I had stumbled upon some bizarre behaviour relating to Windows processes. Here's how it went...

I noticed that a process (of an app I wrote) had been running for a couple of minutes and still had not completed. It usually takes only a matter of seconds to complete (this is in Windows Vista). So I killed it (with Sysinternal's Process Explorer), and ran it again. Same behaviour...

Before going further, the basic operation of this app is to run some checks on processes in certain branches of the system process tree. For example, to only perform a task on processes that are not services.

To dig into the problem, I proceeded to rebuild the app with debug output, and see what it says with Sysinternal's DebugView. According to the output, it appears that the process doesn't get past going through the processes in the system.

Next thing I did was to run the app in the debugger and see what happens. Well, it just keeps going, and going. Trying my luck, I hit the 'pause' button to break the process. Happily, it actually stopped in my code. It stopped in a piece of code that traverses up the process tree from any particular process. This is pretty straightforward:

I had already built a map of all the processes in the system. I got the processes via ToolHelp32. So the basic idea is (simplified):

For a process:
  1. Stop if this is an ancestor I am looking for
  2. Get the parent process of currently examined process
  3. If there are no more processes, stop
  4. Loop back to 1.
So basically, it just goes up a process's ancestry, to see if it can find a specific process. The problem that was occurring, was that it somehow ended up being an infinite loop! And how can that happen?!?

Well, here's how it happened... Two processes have each other as parents! In the instance of the problem I was having, this was how it went:

devenv.exe[PID:3824] has parent [PID:3364]
explorer.exe[PID:3364] has parent [PID:3824]

"This can't be right?!?", I thought. Taking a look at explorer.exe in Process Explorer, it did show that devenv.exe was its parent, which I know is wrong because I did not use devenv.exe to start the shell. It was the other way round, as is normally. However, Process Explorer, or rather, Mark Russinovich (We're not worthy!!!) knows it's wrong, and indicates that the parent process is a 'Non-existent Process'.

So, I reworked the code to account for such a situation, and it works nominally again. In retrospect, I think it's fair that I did not write the code to expect such a situation, or to even think of it.

It was late and I was tired, so I turned in right after that. Later, I realized I should have taken some screenshots as I still have no idea how that whole fiasco happened...

Monday, August 3, 2009

Process Creation API Functions Path (XP)


NTSTATUS: STATUS_CREATE_PROCESS_NT51


Following up on the previous post on the Win32 API's process creation functions in Windows Vista SP1, now let's take a look at how it was in Windows XP SP2.

Following are the process creation functions available in the Win32 API:

kernel32.dll:
  • CreateProcessA()
  • CreateProcessW()
  • CreateProcessInternalA()
  • CreateProcessInternalW()
  • CreateProcessInternalWSecure()

advapi32.dll:
  • CreateProcessAsUserA()
  • CreateProcessAsUserW()
  • CreateProcessWithLogonW()
  • CreateProcessAsUserSecure()

Of note are CreateProcessInternalWSecure() and CreateProcessAsUserSecure(). These two functions do absolutely nothing. They just return zero. It's also worth noting that these two functions do not appear in Windows Vista. I suppose as a joke, it means that there is no secure way to create processes in Windows XP! GYAHAHA!!!

Below is a diagram that shows how these functions are related to each other, with the exception of
CreateProcessWithLogonW():



Win32 API Process Creation Functions


The general workings of these functions are the same as they were described in the previous post for Windows Vista.


Friday, July 3, 2009

Process Creation API Functions Path (Vista)


NTSTATUS: STATUS_CREATE_PROCESS_NT60


It's been a while since the last posting, so let's move right on to the current one...

We'll have a little look at the
Win32 API process creation functions, and what other exported (Win32) functions they use under the hood. First, we'll take a look at how it goes for Windows Vista (SP1), and we'll look at Windows XP in a subsequent posting.

Following are the process creation functions available in the Win32 API:

kernel32.dll:
  • CreateProcessA()
  • CreateProcessW()
  • CreateProcessInternalA()
  • CreateProcessInternalW()

advapi32.dll:
  • CreateProcessAsUserA()
  • CreateProcessAsUserW()
  • CreateProcessWithLogonW()
  • CreateProcessWithTokenW()

The two 'internal' versions of CreateProcess are not documented. Also, for those who are not familiar with the Win32 API conventions, the suffix of either 'A' or 'W' as in the above functions denote whether they are the ANSI or Unicode versions of the functions.

Below is a diagram that shows how these functions are related to each other, with the exception of
CreateProcessWithLogonW() and CreateProcessWithTokenW(). Those two are more complicated, and we'll leave them out for now (translated as, I haven't looked into it enough at this time):



Win32 API Process Creation Functions


So, from the diagram above,
we can see that the five above functions ultimately call CreateProcessInternalW().

It is interesting to note the following of the above mentioned five functions:
  • CreateProcessA/W() sets up parameters and calls CreateProcessInternalA/W() respectively, nothing more.
  • CreateProcessAsUserA/W() sets up parameters and calls CreateProcessInternalA/W() (respectively). then sets process, thread and security information of the user [the high-level overview].
  • CreateProcessInternalA() sets up parameters, converts ANSI strings to Unicode strings, then calls CreateProcessInternalW().

As of all undocumented functions, whether in the Win32 API or not, the general idea is that they are undocumented because they could change between versions of the operating system. Of course, there is also the old, old conspiracy theory that they are being kept secret for advantage. Maybe a little bit of both. Fair game, if you ask me. However, I will confirm that I have seen changes in undocumented functions even between different Windows service packs. And this is includes function prototypes and behaviour.

I suppose the moral is, that if you depend on undocumented functions or behaviours, you will basically have more work to do in making sure that your applications don't blow up in different versions of the system binaries.

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.

Tuesday, May 19, 2009

New Offering From Microsoft Research


NTSTATUS: STATUS_CIBAI


I swear I did not make this up... Look here: Cibai from Microsoft Research

Here's what they have to say in the abstract:

"We introduce Cibai a generic static analyzer based on abstract interpretation for the modular analysis and verification of Java classes. We present the abstract semantics and the underlying abstract domain, a combination of an aliasing analysis and octagons.

We discuss some implementation issues, and we compare Cibai with similar tools (I dunno, like 'blue bird'? :P), showing how Cibai achieves a higher level of automation and precision while having comparable performances."

I'm not sure what to think about that last statement... a "Cibai achieves a higher level of automation and precision while having comparable performances"... If that isn't speechlessly incredible in-your-dreams type of thing, I don't know what is...

I mean, heck, if Jabba The Hutt can say "Kan Ni Naa", it's all good ;)


Monday, May 11, 2009

Determining User Local Groups


NTSTATUS: STATUS_WHAT_IS_MY_POWER


There might be occasions where you are developing an application where it has to take actions which depend on the permissions and privileges of the user context under which it is running. To check if a process has a specific security privilege enabled, the LSA (Local Security Authority) API functions can be used.

In this article, we will look at a simpler and more general scenario. We will make a decision based on what everybody should be well familiar with, and that is Local Groups (we'll call it LG for short). The most common ones are of course:
  • Administrators
  • Power Users
  • Users

So, our simple scenario is that based on the our process's user's LG membership, we will take different courses of action(s).

We will use the following Network Management Function:
NET_API_STATUS NetUserGetLocalGroups(
__in LPCWSTR servername,
__in LPCWSTR username,
__in DWORD level,
__in DWORD flags,
__out LPBYTE *bufptr,
__in DWORD prefmaxlen,
__out LPDWORD entriesread,
__out LPDWORD totalentries
);

There is an example of how to use this function in MSDN: NetuserGetLocalGroups Function

What's important here are the first two parameters. The servername would be the local computer name, or localhost can also be used in its place. The username is of course the user whose LG membership we're interested in.

The value for level should be 0, the only value defined for flags is LG_INCLUDE_INDIRECT. The data will then be return in the buffer as type LPLOCALGROUP_USERS_INFO_0:
typedef struct _LOCALGROUP_USERS_INFO_0 {
LPWSTR lgrui0_name;
} LOCALGROUP_USERS_INFO_0, *PLOCALGROUP_USERS_INFO_0, *LPLOCALGROUP_USERS_INFO_0;

The LG info returned are therefore the names of the groups itself as Unicode strings. So, string comparisons have to be done to check for the groups (such as) "Administrators", "Power Users" and "Users".

Friday, April 24, 2009

That is not how you say my name...


NTSTATUS: STATUS_LMAO

If you're ever looking for some random, cryptic or WTF type of name to use as an identifier in your code, I've got one for you... And it is: Xobile.

However, there are some rather special uses for Xobile. It works best in C/C++, and can also be used in C#. Here are the characteristics:
  • It should be of a type where it can be tested for 0 (zero)
  • The type can be of a pointer type
  • The type can be of a numerical type
  • The special case is that it must be tested for 0 (zero)
  • The whole crux of this is to use the '!' operator on it

What we are specifically targeting for, is to write: !Xobile

Examples of declarations as variables:






Examples of declarations as a function:






Examples of usage:













Just FYI, 'Xobile' is not pronounced "so-buy-l", or "so-beel", or "so-bee-leh". But more importantly, how do you say "!Xobile"?

With no further delay, please allow me to introduce Russell Peters to give us the low-down on '!Xobile'... *Applause*




Tuesday, April 21, 2009

Handling And Re-Handling


NTSTATUS
: STATUS_IT_WASNT_REALLY_OBVIOUS


In the Windows system, an object that represents a system resource such as a process, thread, file or synchronization object are accessed via a handle. The application will have to obtain a handle to such objects which can then be used to manipulate or examine these objects.

Here are some common handle types in Win32:

Kernel Objects
:
  • Process: HANDLE
  • Thread: HANDLE
  • File: HANDLE
  • Synchronization Objects (mutex, semaphore): HANDLE

User Objects:
  • Window: HWND
  • Menu: HMENU
  • Icon: HICON

GDI Objects:
  • Device Context: HDC
  • Bitmap: HBITMAP
  • Brush: HBRUSH

What we're going to focus on here are kernel objects, and a particular scenario where a not-so-obvious Win32 API function earns it's dollars.

Here's the scenario. You have obtained a handle to a kernel object, and for this example, it is a process handle (HANDLE). You did not create the process to which this handle is for, nor did you open the process to which this handle is for. You just got hold of it. Now, you want to get some information on this process, so let's start by trying to get the process's module file name with GetProcessImageFileName().

Boom! The function returns a failure. And the error reason is that you basically do not have the access permissions to do so. The handle must have one of the following permissions:
  • PROCESS_QUERY_INFORMATION
  • PROCESS_QUERY_LIMITED_INFORMATION
So clearly, it doesn't. And since you did not create or open that process, you also don't know which Process ID it was either that the handle came from. !@#$%. Guess we'll just have to try to get that information from the handle then. Oh, wait, we probably can't either coz we don't have the necessary permissions. How now brown cow?

Well, as it turns out, there is a particular Win32 API function I've known for ages, but had never examined it (clearly, I've not used it until not too long ago) as it seemed silly back then. The function: DuplicateHandle(). I guess I never paid attention to it because I didn't see the need for that as I could just use another HANDLE variable and assign it the same value. D-uh...

However, here's the prototype:

BOOL WINAPI DuplicateHandle(
__in HANDLE hSourceProcessHandle,
__in HANDLE hSourceHandle,
__in HANDLE hTargetProcessHandle,
__out LPHANDLE lpTargetHandle,
__in DWORD dwDesiredAccess,
__in BOOL bInheritHandle,
__in DWORD dwOptions
);


So, it clearly does a whole lot more than just duplicating a handle, so to speak. The magic is in the parameter
dwDesiredAccess. You can set the permissions for the new handle that is to be duplicated from the original. So, what you'd get is a new handle that accesses the same object as the original handle, but with different properties such as the access permissions. However, there is another catch. This won't work either unless the source process of the original handle has the PROCESS_DUP_HANDLE permission. So far, I don't think it's common to not have this permission.

Just for good measure, you can specify DUPLICATE_SAME_ACCESS in the
dwOptions parameter, and the dwDesiredAccess parameter will be ignored.
Therefore, by duplicating the original process handle this way, you can now obtain some information from it, like what GetProcessImageFileName() can tell you.

Monday, April 20, 2009

NTSTATUS? Wazzat?


NTSTATUS
: STATUS_GENERAL_INFORMATION


In recent times, I've met a fair number of people in software development who work on Microsoft Windows who go "Win32 API? What's that?" I guess it is that people just don't, or can get by without needing to know what that is, let alone use it. I'm not saying that there's anything wrong with that. Just sign o' the times, I guess. Also a sign of what kind of development is being done more pervasively nowadays.

In this blog, unless specified, 'Windows' (as in Microsoft Windows) will generally refer to WindowsNT, and usually NT5.1 (Windows XP), and NT6.0 (Windows Vista) unless specified. I still have some good memories of Windows 9x, but they are few and far between.

So, for those who don't already know, the calling convention alias for the Win32 API is WINAPI, and the standard error does not have a special type definition. One more layer down, in Window's kernel-mode, where the neat NT Native API is used, the calling convention is NTAPI, and the standard return type is NTSTATUS.

And then, WINAPI and NTAPI is the stdcall calling convention of Intel's x86 architecture, and NTSTATUS is an unsigned 32-bit (unless you're into 64-bit) type.

Well, so that's that. Let's see if there will be anything randomly interesting coming up...