n u MiT_o r's programming pages
Small PE project
I've devoted time to find ways to get smallest PE Windows32 files. I
have not
yet writen any theoretical paper about this. By now, I've only done
some tests.
Here are the results, all done with free tools. Look at these and think
about them. You must revise and edit before the MKE.BAT files in each
.ZIP. In the
examples for C compiler, I used several linker and some tools that I
wrote to
link object files with Borland TLINK32. You can comment or change the
MKE.BAT
files as you want.
· Using free C compilers
- Using mingw32: generated using mingw32 gcc free compiler, tested
with various linkers (LD, iLINK32, ALINK, LINK).
The MKE.BAT of this .ZIP, include some lines to compile from Borland
BCC++ free compiler.
- Using cc386: generated using cc386
free compiler, tested with various linkers ( VALX, TLINK32, ALINK,
LINK).
The smallest PE file that I found here, was compiling with MINGW32
GCC C compiler and linking with Microsoft LINK.
· Using only NASM: flat PE
- Flat PE: small PE generated using
only NASM
assembler, without any linker.
The issue of this project really is write some macros that permit
easyly create smallest PE files using only NASM free assembler.
However, I intended a smallest PE file:
- Smallest Flat PE: smaller than Flat
PE (by now [07/09/2002] 582 bytes) :-)
By default, the size of the PE sections must have 512 (200h) bytes of
size. So, the minimun size of a PE file must to be 2x512=1024 bytes
(the header and one section for the code and data of the program). But
I remembered that accidentally I ran in windows 2000 a patched PE file
which last section had a size of 100h (256) bytes: we don't need that a
section has a minimun size equal to the file alignment value. The
important here is that the size of section does not be greater than the
raw size of section value. Also is possible write code in empty areas
of the PE Header, because the code runs in read only areas. You can not
put the IMAGE_IMPORT_BY_NAME entries in the PE header, because the
loader writes here info to find the imported functions in the process
address space.
However, my friend blaz
has demonstred that is possible put the import data structures in the
PE header. How? The
documentation about the PE header says about the
IMAGE_DIRECTORY_ENTRY_IAT entry in the IMAGE_DATA_DIRECTORY, that:
Points to the beginning of the first Import Address
Table (IAT). The IATs
for each imported DLL appear sequentially in memory. The Size field
indicates
the total size of all the IATs. The loader uses this address and size
to
temporarily mark the IATs as read-write during import resolution.
So, if you set the IAT field in the IMAGE_DATA_DIRECTORY --at the end
of the IMAGE_OPTIONAL_HEADER-- with the info about the IAT address and
size, the NT loader will set the read/write attribute to the page where
will be the PE header. With this info, I wrote this.
But blaz, has gone beyond and wrote in hex a PE file with only 276 bytes of
size :) However, there is a new problem: only runs in NT :( [by
now!]
- Flat PE with resources: Flat PE
with dialog and menu (1.6KB).
Here, I add resources using flat PE programming. To add icons, bitmaps
and cursors we need a tool that extracts the raw data from the .ico and
.bmp files, and converts this raw data to a format that can be included
in the .ASM source code. But is posible to load pictures from the disk:
is not necessary include them in the resource data.
I begun flatpe study with a source code from vecna hand-made PE file. The
original proggie does not run in Windows 2000, so that I did some
changes, including some incipient and useful macros.
TODO: add macros and code to include export symbols.
Notes about the linkers
- ld: comes with mingw32
distribution
- Borland iLINK32: the incremental linker comes with Borland C++
free command line compiler. Only works with OMF
object files, and waits that the object files define the entry point of
the programs. This is defined by the compiler using initialization
libraries or by the assembler with the directive:
end entrypoit
that says to the assembler where ends a program. Here, "entrypoint" is
the label for the main procedure of the program.
The object omf files include a record at the
end of files that says what is the entry point. TASM32 generates this
record. C++ Borland compiler does not include this record: you have to
use initialization libraries to link object files in a PE file.
- ALINK: this is a
wonderfull free linker developed by Anthony A.J. Williams. It permits
indicate the entry point in the command line that invokes it.
- Microsoft LINK: comes with the DDK windows 98 and 2000
distribution. The best for generate PE files. It works with omf and coff object files,
and permits indicate the entry point in the command line that invokes
it.
- VALX: comes with the CC386 distribution. Originaly, is a
project of David Troendle to develope a DOS 16 bits linker. David Lindauer
extended the project to soport w32 executables files.
Contactar a n
u M I T_o r
e-mail:
numit_or@cantv.net