I'll have to write a small program to collect some statistics:-)
Okay, I did a quick and dirty program to do that. It looked through the following products that I've got installed:
Win2000 sp1 MSDEV 98 MS Office 2000
Using the following command:
find /fs/win2000/WINNT \ "/fs/win2000/Program Files/Microsoft Visual Studio" \ "/fs/win2000/Program Files/Microsoft Office" -type f | ./scandll
And came up with the following statistics:
files accessed : 3985 valid PE images : 1752 - libraries : 1280 - badly VM aligned : 20 - standard image base : 42 - specific image base : 1218 - file align by sector: 976 - file align by page : 284 - executables : 472 - badly VM aligned : 133 - standard image base : 70 - specific image base : 269 - file align by sector: 287 - file align by page : 52
I've attached the program I used.
As you can see, most DLLs actually have their image base set manually to avoid conflicts. Also a lot of EXEs have it set too... presumably so that they can also be used as DLLs.
However! the majority of DLLs and EXEs are sector-aligned (512) in the files, not page-aligned (4096).
David
/* scandll.c: scan DLLs and EXEs * * Copyright (c) 2001 David Howells (dhowells@redhat.com). */ #include <stdio.h> #include <string.h> #include <unistd.h> #include <fcntl.h> #include <errno.h> #include <linux/types.h>
typedef __u8 BOOL, BYTE; typedef __u16 WORD; typedef __u32 DWORD, UINT;
#define PAGE_SIZE 4096
#define _H_229A4E44_C7CC_11D4_8F92_0000C0005742 /* skip section.h */ #include "pefile.h"
IMAGE_SECTION_HEADER sechdr; IMAGE_DOS_HEADER imghdr; IMAGE_NT_HEADERS nthdr;
int files; int valid_image; int dlls; int exes; int bad_vm_align[2]; int file_align_sector[2]; int file_align_page[2]; int normal_image_base[2]; int specific_image_base[2];
/*****************************************************************************/ /* * */ int main(int argc, char **argv) { char fname[1024], *cp; int fd = -1, tmp, isexe;
while (close(fd), fd = -1, fgets(fname,sizeof(fname),stdin) ) { cp = strpbrk(fname,"\r\n"); if (cp) *cp = 0;
fd = open(fname,O_RDONLY); if (!fd) { if (errno==EISDIR) continue; perror("open"); return 1; }
/* get the DOS image header */ tmp = read(fd,&imghdr,sizeof(imghdr)); if (tmp<0) { if (errno==EISDIR) continue; perror("read doshdr"); return 1; } if (tmp<sizeof(imghdr)) continue;
files++;
if (imghdr.e_magic != IMAGE_DOS_SIGNATURE) continue;
/* get the NT image header */ lseek(fd,imghdr.e_lfanew,SEEK_SET); tmp = read(fd,&nthdr,sizeof(nthdr)); if (tmp<0) { perror("read nthdr"); return 1; } if (tmp<sizeof(nthdr)) continue;
if (nthdr.Signature != IMAGE_NT_SIGNATURE || nthdr.FileHeader.Machine != IMAGE_FILE_MACHINE_I386 ) continue;
if (!(nthdr.FileHeader.Characteristics & IMAGE_FILE_EXECUTABLE_IMAGE)) continue;
if (nthdr.OptionalHeader.Magic != IMAGE_NT_OPTIONAL_HDR_MAGIC) continue;
/* okay... it's a valid PE image */ valid_image++;
/* is it an EXE file? */ if (nthdr.FileHeader.Characteristics & IMAGE_FILE_DLL) { dlls++; isexe = 0; } else { exes++; isexe = 1; }
/* check the VM alignment */ if (!nthdr.OptionalHeader.SectionAlignment || nthdr.OptionalHeader.SectionAlignment&(PAGE_SIZE-1) ) { bad_vm_align[isexe]++; continue; }
/* check the file alignment */ if (!nthdr.OptionalHeader.FileAlignment || nthdr.OptionalHeader.FileAlignment&(PAGE_SIZE-1) ) { file_align_sector[isexe]++; } else { file_align_page[isexe]++; }
/* consider the image base */ printf("%08x %s\n",nthdr.OptionalHeader.ImageBase,fname); if (nthdr.OptionalHeader.ImageBase==0x10000000 || nthdr.OptionalHeader.ImageBase==0x00400000 ) { normal_image_base[isexe]++; } else { specific_image_base[isexe]++; } }
printf("files accessed : %d\n",files); printf("valid PE images : %d\n",valid_image); printf("- libraries : %d\n",dlls); printf(" - badly VM aligned : %d\n",bad_vm_align[0]); printf(" - standard image base : %d\n",normal_image_base[0]); printf(" - specific image base : %d\n",specific_image_base[0]); printf(" - file align by sector: %d\n",file_align_sector[0]); printf(" - file align by page : %d\n",file_align_page[0]); printf("- executables : %d\n",exes); printf(" - badly VM aligned : %d\n",bad_vm_align[1]); printf(" - standard image base : %d\n",normal_image_base[1]); printf(" - specific image base : %d\n",specific_image_base[1]); printf(" - file align by sector: %d\n",file_align_sector[1]); printf(" - file align by page : %d\n",file_align_page[1]);
return 0; } /* end main() */ \n",exes); printf(" - badly VM aligned : %d\n",bad_vm_align[1]); printf(" - standard image base : %d\n",normal_image_base[1]); printf(" - specific image base : %d\n",specific_image_base[1]); printf(" - file align by sector: %d\n",file_align_sector[1]); printf(" - file align by page : %d\n",file_align_page[1]);
return 0; } /* end main() */