GCC and Vista Incompatibility

Since ReactOS is still being built with GCC (unfortunately), some of our devs have started to report a problem when using the MinGW build under Windows Vista. The call to MapViewOfFileEx that the compiler users for precompiled header support fails, so the compilation fails for any project that uses a PCH.

This type of error might creep up in other system software as well, and it’s not really GCC’s fault for succumbing to it. If you look at the documentation for CreateFileMapping, you’ll notice this blurb in the Remarks section:

Creating a file mapping object from a session other than session zero requires the SeCreateGlobalPrivilege privilege. Note that this privilege check is limited to the creation of file mapping objects and does not apply to opening existing ones. For example, if a service or the system creates a file mapping object, any process running in any session can access that file mapping object provided that the caller has the required access rights.

Windows XP/2000: The requirement described in the previous paragraph was introduced with Windows Server 2003, Windows XP SP2 and Windows 2000 Server SP4.

Although this feature was added in SP2, the reason it doesn’t happen in Windows XP has to do with two changes in Vista. First, UAC means that programs don’t get the SeCreateGlobalPrivilege anymore, because they’re not running in administrator accounts anymore. Secondly, in Vista, Session 0 is now the SYSTEM account session, where the login screen and services are running. Therefore, any user processes will run in Session 1, even in a normal single-user system. These two factors combined mean that CreateFileMapping is now significantly reduced in functionality and that only services are allowed to create global shared memory.

There are three workarounds if you really need the functionality:

  1. Use the Microsoft Management Console (MMC) and the Local Security Policy Snap-In to give SeCreateGlobalPrivilege to the limited account.
  2. Write a wrapper program that executes with elevated rights and and uses RtlAcquire/AdjustPrivilege to get the privilege before running your target program (Such as gcc).
  3. Use the HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Session Manager\Kernel\ObUnsecureGlobalNames string array to add the name of the section to the list. Hopefully your program isn’t randomizing the name. Adding this name will disable the kernel protection check.

Why Io/NtCreateFile Fails…

If you’ve ever had a call to NtCreateFile or IoCreateFail fail with the very helpful “STATUS_INVALID_PARAMETER” status code, you can now how exciting it can be to track down which flag exactly you might’ve messed up. Hopefully this snippet of code should help you manually validate your call (I’m not sure if the latest PREFast checks for these things when compiling). This code is from ReactOS.

/* Check if we need to check parameters, or if we’re user mode */

if ((AccessMode != KernelMode) || (Options & IO_CHECK_CREATE_PARAMETERS))

{

    /* Validate parameters */

    if ((FileAttributes & ~FILE_ATTRIBUTE_VALID_FLAGS) ||

        (ShareAccess & ~FILE_SHARE_VALID_FLAGS) ||

        (Disposition > FILE_MAXIMUM_DISPOSITION) ||

        (CreateOptions & ~FILE_VALID_OPTION_FLAGS) ||

         (CreateOptions &

         (FILE_SYNCHRONOUS_IO_ALERT | FILE_SYNCHRONOUS_IO_NONALERT) &&

         (!(DesiredAccess & SYNCHRONIZE))) ||

        ((CreateOptions &

         (FILE_SYNCHRONOUS_IO_NONALERT | FILE_SYNCHRONOUS_IO_ALERT)) ==

         (FILE_SYNCHRONOUS_IO_NONALERT | FILE_SYNCHRONOUS_IO_ALERT)) ||

        ((CreateOptions & FILE_DIRECTORY_FILE) &&

         !(CreateOptions & FILE_NON_DIRECTORY_FILE) &&

          ((CreateOptions & ~(FILE_DIRECTORY_FILE |

                              FILE_SYNCHRONOUS_IO_ALERT |

                              FILE_SYNCHRONOUS_IO_NONALERT |

                              FILE_WRITE_THROUGH |

                              FILE_COMPLETE_IF_OPLOCKED |

                              FILE_OPEN_FOR_BACKUP_INTENT |

                              FILE_DELETE_ON_CLOSE |

                              FILE_OPEN_FOR_FREE_SPACE_QUERY |

                              FILE_OPEN_BY_FILE_ID |

                              FILE_OPEN_REPARSE_POINT)) ||

          ((Disposition != FILE_CREATE) &&

           (Disposition != FILE_OPEN) &&

           (Disposition != FILE_OPEN_IF)))) ||

        ((CreateOptions & FILE_COMPLETE_IF_OPLOCKED) &&

         (CreateOptions & FILE_RESERVE_OPFILTER)) ||

        ((CreateOptions & FILE_NO_INTERMEDIATE_BUFFERING) &&

         (DesiredAccess & FILE_APPEND_DATA)))

    {

        /*

         * Parameter failure. We’ll be as unspecific as NT as to

         * why this happened though, to make debugging a pain!

         */

        DPRINT1(“File Create Parameter Failure!\n”);

        return STATUS_INVALID_PARAMETER;

    }

 

    /* Now check if this is a named pipe */

    if (CreateFileType == CreateFileTypeNamedPipe)

    {

        /* Make sure we have extra parameters */

        if (!ExtraCreateParameters) return STATUS_INVALID_PARAMETER;

 

        /* Get the parameters and validate them */

        NamedPipeCreateParameters = ExtraCreateParameters;

        if ((NamedPipeCreateParameters->NamedPipeType >

             FILE_PIPE_MESSAGE_TYPE) ||

            (NamedPipeCreateParameters->ReadMode >

             FILE_PIPE_MESSAGE_MODE) ||

            (NamedPipeCreateParameters->CompletionMode >

             FILE_PIPE_COMPLETE_OPERATION) ||

            (ShareAccess & FILE_SHARE_DELETE) ||

            ((Disposition < FILE_OPEN) || (Disposition > FILE_OPEN_IF)) ||

            (CreateOptions & ~FILE_VALID_PIPE_OPTION_FLAGS))

        {

            /* Invalid named pipe create */

            return STATUS_INVALID_PARAMETER;

        }

    }

    else if (CreateFileType == CreateFileTypeMailslot)

    {

        /* Make sure we have extra parameters */

        if (!ExtraCreateParameters) return STATUS_INVALID_PARAMETER;

 

        /* Get the parameters and validate them */

        MailslotCreateParameters = ExtraCreateParameters;

        if ((ShareAccess & FILE_SHARE_DELETE) ||

            !(ShareAccess & ~FILE_SHARE_WRITE) ||

            (Disposition != FILE_CREATE) ||

            (CreateOptions & ~FILE_VALID_MAILSLOT_OPTION_FLAGS))

        {

            /* Invalid mailslot create */

            return STATUS_INVALID_PARAMETER;

        }

    }

}

News and Todos…

I apologize for the lack of updates, but these upcoming weeks (until December 20th) are my finals, and I can’t afford to do badly on them, so I won’t probably have time to blog at all or post part 3 of my article on OpenRCE. I apologize for the disappointment.

However, here’s what I plan on writing on once I have some time:

1) Recognizing macros and other constructs in IDA for MSVC binaries. Will focus on Microsoft kernel-mode code.

2) Unveiling of the NDK and a sample background application that uses LPC.
3) A sample AFD (Ancilliary Function Driver) Client and Server, and its relationship to security/rootkit detection.

See you all soon!

Blogroll and Publications

It’s been a pretty slow week until now, so I’m going to take this time to do the last “todo” for my blog. As I mentionned previously, I have been setting up my blogroll and publication page, and now that I’ve finished uploading everything, I wanted to give a more in-depth overview of the materials and links:

Blogs

  • Ken Johnson’s Blog Ken is a well-known NT expert known as Skywing. We met while he was still working on ReactOS, and we frequently discuss NT implementation details and security bugs. We both have a hate for crappy drivers, hooks, and other kinds of dangerous code. If there’s something I don’t post here, Ken probably has posted about it before or will 🙂
  • Ero Carrera’s Blog Ero is a fellow security researcher that I met while at Recon, and he is well known for his work at Sabre, especially in analysis of binaries, and he has published various papers and given talks at conferences, as well as trainings. If you have a chance to meet him, take it, because he knows a lot!
  • TinyKRNL Website TinyKRNL is my own personal project, and team of people working on it. You can find more information on its website. It is a Windows NT Kernel implementation for educational use.
  • Larry Osterman’s Blog Larry is one of my favorite bloggers at Microsoft. He has been working there for over two decades, and his experience (and anecdotes) are always insightful. He has interesing topics such as “What’s wrong with this code” and other optimization/algorithm questions sometimes.
  • ReactOS The other project that I work on, ReactOS attempts to create an open-sourced (GPL) version of the Windows NT (XP/2003) Operating System by implementing its own kernel and using Wine’s Win32 libraries.
  • Jason Geffner’s Blog Jason is a reverse engineer at Microsoft that I’m happy to call my friend. He’s one of the smartest guys I’ve met, and he has a lot of neat ideas that he gets the chance to work on. He’s also responsible for saving the world a couple of times.
  • Raymond Chen’s Blog Raymond chen is the iconic Microsoft blogger. Blogging on everything from languages, music to Windows 1.0 compatibility functions present in Vista, Raymond makes it hard for you to hate those annoying features in Windows, and explains just how stupid some 3rd-party developers really are, and how much trouble he and his team have to go through to keep those apps working, so that you don’t complain.
  • OpenRCE OpenRCE is the premier Reverse Code Engineering portal, with all the big names in the field, interesting articles (such as mine ;), forum posts, tools and diagrams, and a helpful bunch of users from all over the industry. It’s also the brainchild of a very good friend of mine, Pedram.
  • Steve Dispensa’s Blog Steve is another NT genius, especially in NDIS, that took his knowledge to the corporate level and now is a CTO for a very sucessful company. We met through Ken Johnson, who is now employed there, and I’m still hoping to finally be able to meet him in the future. His blog is of particular interest to NT driver developers, much like Ken’s.
  • Pedram’s Blog Pedram is another security researcher and big name, as well as the creator of OpenRCE and many other valuable tools, including PaiMei and tools such as PyDbg. He’s also a good friend of mine, and a very fun guy.

Using spaces in your TARGETLIBS path

I’ve been trying to find a solution on this annoying “sources” problems in the Build utility for ages. Thankfully, a post at NotAKernelGuy pointed a way to the solution. It’s in Russian, but the basic solution is simple:

LINKER_OPTIDATA = \\
"$(VS80COMNTOOLS)\\..\\..\\VC\\PlatformSDK\\lib\\mscoree.lib"

Replace that path by whatever you need, but the end result is the same: the library will be added to the response file, and spaces will be preserved and respected.

WDK RTM Changes

I consistently did diffs (differential changes) between each new release of the WDK. It was interesting to follow the evolution of certain APIs and structures, as well as APIs which were added by mistake.

The latter happens because kits like the WDK are built from a master header file. Suppose it looks like this:

// begin_ntddk

//
// Process Functions
//
NTKERNELAPI
NTAPI
KeSetProcess(IN PRKPROCESS Process);

//
// Thread Functions
//
NTKERNELAPI
NTAPI
KeStartThread(IN PRKTHREAD Thread);

// end_ntddk

NTKERNELAPI
NTAPI
KeSetThreadDrmProtection(IN PRKTHREAD Thread);

What would happen in the DDK is that the KeSetProcess and KeStartThread would be exported, and by definition, “legit” to be used in drivers. Now suppose the developers add a new API in Vista, and don’t properly take a look at the DDK tags, you could end up with this:

// begin_ntddk

//
// Process Functions
//
NTKERNELAPI
NTAPI
KeSetProcess(IN PRKPROCESS Process);

NTKERNELAPI
NTAPI
KeProtectProcessForDrm(IN PRKPROCESS Process);

//
// Thread Functions
//
NTKERNELAPI
NTAPI
KeStartThread(IN PRKTHREAD Thread);

// end_ntddk

NTKERNELAPI
NTAPI
KeSetThreadDrmProtection(IN PRKTHREAD Thread);

Notice that the tags weren’t properly updated to keep the DRM/internal/undocumented function out from the DDK, so it will appear in the WDK. Of course, at the next release, someone is bound to notice and fixup the tags. So by doing cumulative diffs, I was able to get the prototypes of quite a few new APIs that didn’t make it into the final WDK. Of course, I don’t condone their use in a driver, but they’re useful for ReactOS/TinyKRNL development and to better understand some of the changes done in Vista.

One of the more memorable API sets that were added allow drivers (well, at least, were supposed to!) to modify the size of the kernel stack. Typically MmCreateKernelStack was a way to do this, but these new Ke functions give a much greater degree of control as well as give you a Callout function:

#define MAXIMUM_EXPANSION_SIZE (KERNEL_LARGE_STACK_SIZE – (PAGE_SIZE / 2))

typedef
VOID
(NTAPI *PEXPAND_STACK_CALLOUT) (
__in_opt PVOID Parameter
);

#if (NTDDI_VERSION >= NTDDI_WS03SP1)
NTKERNELAPI
NTSTATUS
KeExpandKernelStackAndCallout (
__in PEXPAND_STACK_CALLOUT Callout,
__in_opt PVOID Parameter,
__in SIZE_T Size
);
#endif

#if (NTDDI_VERSION >= NTDDI_LONGHORN)
NTKERNELAPI
NTSTATUS
KeExpandKernelStackAndCalloutEx (
__in PEXPAND_STACK_CALLOUT Callout,
__in_opt PVOID Parameter,
__in SIZE_T Size,
__in BOOLEAN Wait,
__in_opt PVOID Context
);

NTKERNELAPI
PVOID
KeAllocateCalloutStack (
__in BOOLEAN LargeStack
);

NTKERNELAPI
VOID
KeFreeCalloutStack (
__in PVOID Context
);

#endif

Now here’s the ironic thing: http://msdn.microsoft.com/library/default.asp?url=/library/en-us/DevTest_g/hh/DevTest_g/t06_bugs_B0_77bda7e9-4f41-49e9-86db-04446dc9c7b7.xml.asp

“The driver switched stacks using a method that is not supported by the operating system. The only supported way to extend a kernel mode stack is by using KeExpandKernelStackAndCallout.”

I guess it’s either time for a WDK bug or an MSDN documentation bug to be opened!

However, perhaps the best WDK RTM change was this:

Original:

// This logic is a reasonable hack-o-rama to make BillG happy
// since his machine ran chkdsk after he installed Beta 3. Why?
// ’cause setup cracked a non-exclusive DASD handle near the
// end of setup, wrote some data, closed the handle and we
// set the verify bit … came back around and saw that other
// arbitrary activity had left the volume in a temporarily dirty
// state.
//
// Of course, the real problem is that we don’t have a journal.
//

RTM:

// This logic is a reasonable change. Why?
// ’cause setup cracked a non-exclusive DASD handle near the
// end of setup, wrote some data, closed the handle and we
// set the verify bit … came back around and saw that other
// arbitrary activity had left the volume in a temporarily dirty
// state.
//
// Of course, the real problem is that we don’t have a journal.

“hack-o-rama to make BillG happy” => “reasonable change”.

Got any more similar changes of your own? Feel free the post them!

First Post

I’ve kept many blogs during recent times, often struggling to combine personal, private, profesional and random information into various places, usually without much success, and only fragmenting the pieces of my online life.

This site is now the definitive resource for anything that’s not of a private nature or not of general public interest, and it will contain news, rants, ramblings and otherwise hopefully informative data. I will also post up some biographical information and resume, and and detailed contact information.

I hope you’ll find this site a valuable resource to keep yourself informed of my activities and interests. I will probably blog on random topics, but you can expect to find:

  • Mirrors of my articles, presentations and blog-entries at OpenRCE.org.
  • NT Kernel/Native Mode or otherwise low-level information about Windows NT.
  • Development news from ReactOS and TinyKRNL.
  • Personal projects and achievements.
  • Reversing and coding hints and tips.
  • Links to valuable resources.

As always, don’t hesitate to contact me if you have any questions, or simply leave a comment.