The Old New Thing About Development
Here I want to discuss general development of Windows applications, how to professionally develop them. I want to leave out any frameworks, no .NET and no Msvcrt are used in professional environments. Beside the frameworkless development I want also give an insight in Unicode and future techniques that existed already many years before. I remember once a user to give a comment on my article that it's cool that I am still using and referencing old development work in the internet, because nowadays either this work is used or re-invented. In this way, it's the old new thing about development. Enjoy one of my last articles.
Peter Kleissner, Software Developer (May 2009)
No default library
"..ur" ... default library. When compiling a program in Visual Studio there will be automatically linked the runtime library, for C its the "Microsoft C Runtime Library", also called msvrt, for Visual Basic it's msvbvm and so on. Linked in the manner either used as a normal library by importing functions of it or statically linked, the binary of the runtime library included into the programs executable. Latest one is very useful for portability and if you do not want to take a look on Windows Side by Side Assembly (WinSxS) and do not want to ship the redistributable runtime dll or the installer for it (known as Redistributable Packages).
In Visual Studio under Project -> Project Settings you can select Configuration Settings and there C/C++ and Linker. Under C/C++ -> Code Generation is the option runtime library, Multithreaded is linked statically and Multithreaded DLL is the option to use the local stored Msvcrt. If the Msvcrt.dll is then locally not available, then the program will be unable to start and Windows reports an error. This is really annoying if you develop a program under Vista and it's not working on XP.
Since you are developing Visual C++ in Visual Studio there is no way to turn off the runtime library - otherwise your program could not work. It would be possible to manually use the command line compiler/linker and pass the correct parameters, however I haven't done it yet. For general information about the C Runtime Libraries, there is a good documentation under http://msdn.microsoft.com/en-us/library/abx4dbyh.aspx.
Every good developer needs to take advantage of resources, to extract files and data at runtime. Even manifest files are stored as resources. Resources are stored in the .rsrc section of PE files and have an identifier (string or id number), a type and of course the data. There can be different types of resources, for example a string table, an icon, a picture, raw data and some more. The types of resources are defined in winbase.h and contain following:
#define RT_CURSOR WINELIB_NAME_AW(RT_CURSOR) #define RT_BITMAP WINELIB_NAME_AW(RT_BITMAP) #define RT_ICON WINELIB_NAME_AW(RT_ICON) #define RT_MENU WINELIB_NAME_AW(RT_MENU) #define RT_DIALOG WINELIB_NAME_AW(RT_DIALOG) #define RT_STRING WINELIB_NAME_AW(RT_STRING) #define RT_FONTDIR WINELIB_NAME_AW(RT_FONTDIR) #define RT_FONT WINELIB_NAME_AW(RT_FONT) #define RT_ACCELERATOR WINELIB_NAME_AW(RT_ACCELERATOR) #define RT_RCDATA WINELIB_NAME_AW(RT_RCDATA) #define RT_MESSAGELIST WINELIB_NAME_AW(RT_MESSAGELIST) #define RT_GROUP_CURSOR WINELIB_NAME_AW(RT_GROUP_CURSOR) #define RT_GROUP_ICON WINELIB_NAME_AW(RT_GROUP_ICON)
These types identify the type of a resource. To include a resouce, you can do that automatically with Visual Studio Editor (has a nice interface for pre defined default resource types) or manually by editing *.rc once you've told VS to use resources. The rc file will contain strings which look like following example from me:
IDR_RT_MASTERBOOTRECORD RT_RCDATA "Master Boot Record.bin" IDR_RT_BOOTAPPLICATION1 RT_RCDATA "Forensic Lockdown Software.sys" IDR_RT_BOOTAPPLICATION2 RT_RCDATA "Hibernation File Attack.sys"
The first column is a define to an id number, given in resource.h:
#define IDR_RT_MASTERBOOTRECORD 103 #define IDR_RT_BOOTAPPLICATION1 104
RT_RCDATA defines raw data, and the string after the type is the file to include. You can later use following API functions to access the resource (example code, same as used in the infectors of Stoned Bootkit and Hibernation File Attack):
HRSRC Resource = FindResource(NULL, MAKEINTRESOURCE(IDR_RT_MASTERBOOTRECORD), RT_RCDATA); HANDLE GlobalMemory = LoadResource(NULL, Resource); void * Memory = LockResource(GlobalMemory); DWORD SizeOfResourceImage = SizeofResource(NULL, Resource); ..and then having the resource load as data using Memory and SizeOfResourceImage
Many people are wondering about the actual entry point in an application. When using C/C++ there is the main function, however this is only a programming language specific function that is called by the runtime library. At the beginning the operating system calls the programs Entry Point, which is defined in the PE Header. Depending on the type of PE executable (executable, dll, driver) the entry point has different names and parameter lists. The real entry point for dlls looks like (check out the MSDN documentation about it):
BOOL WINAPI DllMain( __in HINSTANCE hinstDLL, __in DWORD fdwReason, __in LPVOID lpvReserved );
The C++ entry point (called by the runtime) for Windows executables is defined as WinMain:
int WINAPI WinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow );
There is no information available about the real entry point and its parameters, however it is known that the instance handle (= address of PE file in memory) is pushed on the stack. The real entry point of drivers is named GsDriverEntry (the @8 means there are 2 dwords pushed) and defined as:
GsDriverEntry@8 NTSTATUS DriverEntry( __in struct _DRIVER_OBJECT *DriverObject, __in PUNICODE_STRING RegistryPath )
The default real entry point (for applications) when using the runtime library is named according to the MSDN library article "/ENTRY (Entry-Point Symbol)" as:
mainCRTStartup (or wmainCRTStartup) An application using /SUBSYSTEM:CONSOLE; calls main (or wmain) WinMainCRTStartup (or wWinMainCRTStartup) An application using /SUBSYSTEM:WINDOWS; calls WinMain (or wWinMain), which must be defined with __stdcall _DllMainCRTStartup A DLL; calls DllMain, which must be defined with __stdcall, if it exists
Manifests can be used for multiple purposes:
- For WinSxS (Windows Side by Side Assembly) to define the versions of the wanted dlls
- For Windows Vista to tell the OS elevated Administrator rights are needed (results in Credential or Consent UI)
- General publishings to the OS
- For example for use with Common Language Runtime to define the wanted versions
As printed out in the Stoned Bootkit paper there is for example the Visual Studio Linker switch /MANIFESTUAC to tell the required rights for execution. Depending on the current logged on user (Administrator or not) and the option will Windows Vista (the User Account Control) display the Consent UI, Credential UI, just execute the program or display an error message and abort.
/MANIFESTUAC:”level=asInvoker” You can specify the level to be asInvoker, highestAvailable or requireAdministrator.
Normally you don't need to include manifests manually, however it can be useful for external certificates etc. Visual Studio automatically generates and includes the required manifests (for Windows XP to define the style, Windows Vista and later the UAC, dll/framework versions etc.).
The very last topic covered here is the subsystem. The subsystem refers to the executed environment, which include the art of loading and executing, the API, the dlls, in general the whole programming interface. The Windows Portable Executable format defines different subsystems (not a complete list):
IMAGE_SUBSYSTEM_UNKNOWN 0 An unknown subsystem IMAGE_SUBSYSTEM_NATIVE 1 Device drivers and native Windows processes IMAGE_SUBSYSTEM_WINDOWS_GUI 2 The Windows graphical user interface (GUI) subsystem IMAGE_SUBSYSTEM_WINDOWS_CUI 3 The Windows character subsystem IMAGE_SUBSYSTEM_POSIX_CUI 7 The Posix character subsystem IMAGE_SUBSYSTEM_WINDOWS_CE_GUI 9 Windows CE IMAGE_SUBSYSTEM_EFI_APPLICATION 10 An Extensible Firmware Interface (EFI) application IMAGE_SUBSYSTEM_EFI_BOOT_SERVICE_DRIVER 11 An EFI driver with boot services IMAGE_SUBSYSTEM_EFI_RUNTIME_DRIVER 12 An EFI driver with run-time services IMAGE_SUBSYSTEM_EFI_ROM 13 An EFI ROM image IMAGE_SUBSYSTEM_XBOX 14 XBOX
The important subsystems for us are Windows CUI, GUI and Native. The first one are command line programs (CUI, character/console user interface), the second normal windowed applications (Graphic User Interface) and the last one (native) are drivers. So this different type of programs just differ with one byte in the PE header.
Development has never been exciting so far. We have new technologies to use, Windows 7 is coming and the computer industry is growing and growing. But the more modern technologies become, the more it is important to now the basics and the backgrounds of that technologies. The best software is written with the above considerations, which includes for example ZeuS and Sinowal. The point of view is to be compatible with all Windows versions, which can be reached by using the core technology (Win32 API, native applications). This also includes then creation of small and fast applications.