MartonNemeth

Personal page for MartonNemeth

This page is created to note my experiences connected to wine.

Cross development for Win32 system

This chapter describes how to create binary Win32 .EXE and .DLL, how to run it under Linux with the help of wine and how to analyse content of the created binary.

I am using Debian 3.1, you can install the cross developement tools with the following command:

# apt-get install mingw32 mingw32-binutils mingw32-runtime

Building a Win32 .EXE

The Win32 .EXE file can be built for different subsystems: console user interface (CUI), graphical user interface (GUI) and Native NT. (There might be other subsystems also, but I don't know about them.) The console applications can run in the "cmd window" and outputs characters. The applications for GUI usually opens a graphical window to communicate with the user. The "Native NT" applications are usually device drivers.

Building a Win32 .EXE for CUI

Let's start with the 'Hello World' program, and compile a Win32 .EXE out of the source:

#include <stdio.h>

int main(int argc, char* args[]) {
        printf("Hello World!\n");
        return 0;
}

Let's name this as hello.c. To compile hello.c to hello.exe use the following command:

$ i586-mingw32msvc-gcc hello.c -o hello.exe

If everything went all right, the hello.exe was created. You can run the code with

$ wine hello.exe
Hello World!

Building a Win32 .EXE for GUI

The next example is a program written for the Win32 GUI subsystem.

#include <windows.h>

int main(int argc, char* args[]) {
        int retval;

        retval = MessageBox(NULL, "Message", "Caption", MB_OK);
        return 0;
}

To compile to a Win32 binary .EXE, the following command can be used:

$ i586-mingw32msvc-gcc -mwindows box.c -o box.exe
$ wine box.exe

Running the box.exe with the help of wine will display a message box with the text "Message", the title will be "Caption" and the only button displayed will be an OK button.

Building a Win32 .EXE for "Native NT"

To build an .exe file for "Native NT" subsystem you'll need the followings:

gcc myapp.c -o myapp.exe -lntdll -nostdlib -Wl,--subsystem,native,-e,_NtProcessStartup@4

The prototype of the entry function is:

void WINAPI NtProcessStartup(PSTARTUP_ARGUMENT Argument);

Peter Quiring's page about building "Native NT" with gcc: http://digiforce.sourceforge.net/gnu_native_nt.php

Hello World kernel driver: http://www.catch22.net/tuts/kernel1.asp

Analyzing the created Win32 binary

The objdump program of the binutils is able to show the content of a binary in human readable form. This utility can display a lot about the binary, but for a first look the -p option is enough to see. The -p will show the private headers of the Win32 .EXE. This dump will contain among others the import and export table of the .EXE. The import table contains the system functions what our program will use. The export table contains the functions what the binary provides for others, usually this is used in .DLLs.

The hello.exe was a console based program. You can verify this at the Subsystem row. The printf() function is used from the msvcrt.dll. The printf() function is emulated by wine through the wine implementation of msvcrt.dll:

$ i586-mingw32msvc-objdump -p hello.exe

hello.exe:     file format pei-i386

Characteristics 0x107
        relocations stripped
        executable
        line numbers stripped
        32 bit words

Time/Date               Thu Jan 25 20:30:25 2007

ImageBase               00400000
SectionAlignment        00001000
FileAlignment           00000200
MajorOSystemVersion     4
MinorOSystemVersion     0
MajorImageVersion       1
MinorImageVersion       0
MajorSubsystemVersion   4
MinorSubsystemVersion   0
Win32Version            00000000
SizeOfImage             00035000
SizeOfHeaders           00000400
CheckSum                000324ee
Subsystem               00000003        (Windows CUI)
DllCharacteristics      00000000
SizeOfStackReserve      00200000
SizeOfStackCommit       00001000
SizeOfHeapReserve       00100000
SizeOfHeapCommit        00001000
LoaderFlags             00000000
NumberOfRvaAndSizes     00000010

The Data Directory
Entry 0 00000000 00000000 Export Directory [.edata (or where ever we found it)]
Entry 1 00006000 0000027c Import Directory [parts of .idata]
Entry 2 00000000 00000000 Resource Directory [.rsrc]
Entry 3 00000000 00000000 Exception Directory [.pdata]
Entry 4 00000000 00000000 Security Directory
Entry 5 00000000 00000000 Base Relocation Directory [.reloc]
Entry 6 00000000 00000000 Debug Directory
Entry 7 00000000 00000000 Description Directory
Entry 8 00000000 00000000 Special Directory
Entry 9 00000000 00000000 Thread Storage Directory [.tls]
Entry a 00000000 00000000 Load Configuration Directory
Entry b 00000000 00000000 Bound Import Directory
Entry c 00000000 00000000 Import Address Table Directory
Entry d 00000000 00000000 Delay Import Directory
Entry e 00000000 00000000 Reserved
Entry f 00000000 00000000 Reserved


There is an import table in .idata at 0x406000

The Import Tables (interpreted .idata section contents)
 vma:            Hint    Time      Forward  DLL       First
                 Table   Stamp     Chain    Name      Thunk
 00006000       00006040 00000000 00000000 00006224 000060a0

        DLL Name: KERNEL32.dll
        vma:  Hint/Ord Member-Name Bound-To
        60fc        1  AddAtomA
        6108      155  ExitProcess
        6118      175  FindAtomA
        6124      220  GetAtomNameA
        6134      735  SetUnhandledExceptionFilter

 00006014       0000605c 00000000 00000000 00006270 000060bc

        DLL Name: msvcrt.dll
        vma:  Hint/Ord Member-Name Bound-To
        6154       39  __getmainargs
        6164       60  __p__environ
        6174       62  __p__fmode
        6184       80  __set_app_type
        6198      111  _assert
        61a4      121  _cexit
        61b0      233  _iob
        61b8      350  _onexit
        61c4      388  _setmode
        61d0      533  abort
        61d8      540  atexit
        61e4      575  free
        61ec      626  malloc
        61f8      639  printf
        6204      656  signal

 00006028       00000000 00000000 00000000 00000000 00000000

The box.exe was compiled with the '-mwindows' option. This results that the Subsystem will be the Win32 GUI (Graphical User Interface). The MessageBoxA() function is used from the user32.dll. This function is also provided by wine:

$ i586-mingw32msvc-objdump -p box.exe


box.exe:     file format pei-i386

Characteristics 0x107
        relocations stripped
        executable
        line numbers stripped
        32 bit words

Time/Date               Thu Jan 25 21:05:12 2007

ImageBase               00400000
SectionAlignment        00001000
FileAlignment           00000200
MajorOSystemVersion     4
MinorOSystemVersion     0
MajorImageVersion       1
MinorImageVersion       0
MajorSubsystemVersion   4
MinorSubsystemVersion   0
Win32Version            00000000
SizeOfImage             00035000
SizeOfHeaders           00000400
CheckSum                00032a42
Subsystem               00000002        (Windows GUI)
DllCharacteristics      00000000
SizeOfStackReserve      00200000
SizeOfStackCommit       00001000
SizeOfHeapReserve       00100000
SizeOfHeapCommit        00001000
LoaderFlags             00000000
NumberOfRvaAndSizes     00000010

The Data Directory
Entry 0 00000000 00000000 Export Directory [.edata (or where ever we found it)]
Entry 1 00006000 000002b0 Import Directory [parts of .idata]
Entry 2 00000000 00000000 Resource Directory [.rsrc]
Entry 3 00000000 00000000 Exception Directory [.pdata]
Entry 4 00000000 00000000 Security Directory
Entry 5 00000000 00000000 Base Relocation Directory [.reloc]
Entry 6 00000000 00000000 Debug Directory
Entry 7 00000000 00000000 Description Directory
Entry 8 00000000 00000000 Special Directory
Entry 9 00000000 00000000 Thread Storage Directory [.tls]
Entry a 00000000 00000000 Load Configuration Directory
Entry b 00000000 00000000 Bound Import Directory
Entry c 00000000 00000000 Import Address Table Directory
Entry d 00000000 00000000 Delay Import Directory
Entry e 00000000 00000000 Reserved
Entry f 00000000 00000000 Reserved

There is an import table in .idata at 0x406000

The Import Tables (interpreted .idata section contents)
 vma:            Hint    Time      Forward  DLL       First
                 Table   Stamp     Chain    Name      Thunk
 00006000       00006054 00000000 00000000 0000624c 000060bc

        DLL Name: KERNEL32.dll
        vma:  Hint/Ord Member-Name Bound-To
        6120        1  AddAtomA
        612c      155  ExitProcess
        613c      175  FindAtomA
        6148      220  GetAtomNameA
        6158      735  SetUnhandledExceptionFilter

 00006014       00006070 00000000 00000000 00006294 000060d8

        DLL Name: msvcrt.dll
        vma:  Hint/Ord Member-Name Bound-To
        6178       39  __getmainargs
        6188       60  __p__environ
        6198       62  __p__fmode
        61a8       80  __set_app_type
        61bc      111  _assert
        61c8      121  _cexit
        61d4      233  _iob
        61dc      350  _onexit
        61e8      388  _setmode
        61f4      533  abort
        61fc      540  atexit
        6208      575  free
        6210      626  malloc
        621c      656  signal

 00006028       000060b0 00000000 00000000 000062a4 00006118

        DLL Name: USER32.dll
        vma:  Hint/Ord Member-Name Bound-To
        6228      430  MessageBoxA

 0000603c       00000000 00000000 00000000 00000000 00000000


CategoryHomepage

MartonNemeth (last edited 2008-04-23 00:15:22 by nathan.n)