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
