Ignore:
Timestamp:
Jan 22, 2001, 7:26:52 PM (25 years ago)
Author:
sandervl
Message:

memory map + handle manager fixes

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/kernel32/winimagepeldr.cpp

    r4758 r5011  
    1 /* $Id: winimagepeldr.cpp,v 1.65 2000-12-05 20:41:43 sandervl Exp $ */
     1/* $Id: winimagepeldr.cpp,v 1.66 2001-01-22 18:26:51 sandervl Exp $ */
    22
    33/*
     
    1313 * TODO: Loading of forwarder dlls before handling imports might not be correct
    1414 *       (circular dependencies; have to check what NT does)
     15 * TODO: Two LoadLibrary calls in two threads at the same time won't be handled properly (rare but possible)
    1516 *
    1617 * NOTE: FLAG_PELDR_LOADASDATAFILE is a special flag to only load the resource directory
     
    5657//This is very useful during debugging as you'll get lots of exceptions
    5758//otherwise.
     59//#ifdef DEBUG
    5860#define COMMIT_ALL
     61//#endif
    5962
    6063char szErrorTitle[]     = "Odin";
     
    104107Win32PeLdrImage::Win32PeLdrImage(char *pszFileName, BOOL isExe) :
    105108    Win32ImageBase(-1),
    106     nrsections(0), imageSize(0), dwFlags(0),
     109    nrsections(0), imageSize(0), dwFlags(0), section(NULL),
    107110    imageVirtBase(-1), realBaseAddress(0), imageVirtEnd(0),
    108111    nrNameExports(0), nrOrdExports(0), nameexports(NULL), ordexports(NULL),
     
    140143Win32PeLdrImage::~Win32PeLdrImage()
    141144{
    142   if(memmap)
    143     delete memmap;
    144 
    145   if(hFile) {
    146     OSLibDosClose(hFile);
    147     hFile = 0;
    148   }
    149 
    150   if(realBaseAddress)
     145    if(memmap)
     146        delete memmap;
     147
     148    if(hFile) {
     149        OSLibDosClose(hFile);
     150        hFile = 0;
     151    }
     152
     153    if(realBaseAddress)
    151154        DosFreeMem((PVOID)realBaseAddress);
    152155
    153   if(nameexports)
     156    if(nameexports)
    154157        free(nameexports);
    155158
    156   if(ordexports)
     159    if(ordexports)
    157160        free(ordexports);
     161
     162    if(section)
     163        free(section);
    158164}
    159165//******************************************************************************
     
    171177 ULONG  signature;
    172178
    173   hFile = OSLibDosOpen(szFileName, OSLIB_ACCESS_READONLY|OSLIB_ACCESS_SHAREDENYNONE);
    174 
    175   //default error:
    176   strcpy(szErrorModule, OSLibStripPath(szFileName));
    177   if(hFile == NULL) {
     179    hFile = OSLibDosOpen(szFileName, OSLIB_ACCESS_READONLY|OSLIB_ACCESS_SHAREDENYNONE);
     180
     181    //default error:
     182    strcpy(szErrorModule, OSLibStripPath(szFileName));
     183    if(hFile == NULL) {
    178184        goto failure;
    179   }
    180   //read dos header
    181   if(DosRead(hFile, (LPVOID)&doshdr, sizeof(doshdr), &ulRead)) {
     185    }
     186    //read dos header
     187    if(DosRead(hFile, (LPVOID)&doshdr, sizeof(doshdr), &ulRead)) {
    182188        goto failure;
    183   }
    184   if(OSLibDosSetFilePtr(hFile, doshdr.e_lfanew, OSLIB_SETPTR_FILE_BEGIN) == -1) {
     189    }
     190    if(OSLibDosSetFilePtr(hFile, doshdr.e_lfanew, OSLIB_SETPTR_FILE_BEGIN) == -1) {
    185191        goto failure;
    186   }
    187   //read signature dword
    188   if(DosRead(hFile, (LPVOID)&signature, sizeof(signature), &ulRead)) {
     192    }
     193    //read signature dword
     194    if(DosRead(hFile, (LPVOID)&signature, sizeof(signature), &ulRead)) {
    189195        goto failure;
    190   }
    191   //read pe header
    192   if(DosRead(hFile, (LPVOID)&fh, sizeof(fh), &ulRead)) {
     196    }
     197    //read pe header
     198    if(DosRead(hFile, (LPVOID)&fh, sizeof(fh), &ulRead)) {
    193199        goto failure;
    194   }
    195   //read optional header
    196   if(DosRead(hFile, (LPVOID)&oh, sizeof(oh), &ulRead)) {
     200    }
     201    //read optional header
     202    if(DosRead(hFile, (LPVOID)&oh, sizeof(oh), &ulRead)) {
    197203        goto failure;
    198   }
    199   if(doshdr.e_magic != IMAGE_DOS_SIGNATURE || signature != IMAGE_NT_SIGNATURE) {
     204    }
     205    if(doshdr.e_magic != IMAGE_DOS_SIGNATURE || signature != IMAGE_NT_SIGNATURE) {
    200206        dprintf((LOG, "Not a valid PE file (probably a 16 bits windows exe/dll)!"));
    201207        WinMessageBox(HWND_DESKTOP, HWND_DESKTOP, szPEErrorMsg, szErrorTitle, 0, MB_OK | MB_ERROR | MB_MOVEABLE);
    202208        goto failure;
    203   }
    204 
    205   if(oh.SizeOfImage == 0) {//just in case
    206     oh.SizeOfImage = OSLibDosGetFileSize(hFile, NULL);
    207   }
    208 
    209   imageSize = oh.SizeOfImage;
    210   //Allocate memory to hold the entire image
    211   if(allocSections(reservedMem) == FALSE) {
     209    }
     210
     211    if(oh.SizeOfImage == 0) {//just in case
     212        oh.SizeOfImage = OSLibDosGetFileSize(hFile, NULL);
     213    }
     214
     215    imageSize = oh.SizeOfImage;
     216    //Allocate memory to hold the entire image
     217    if(allocSections(reservedMem) == FALSE) {
    212218        dprintf((LOG, "Failed to allocate image memory for %s at %x, rc %d", szFileName, oh.ImageBase, errorState));;
    213219        goto failure;
    214   }
    215 
    216   memmap = new Win32MemMap(this, realBaseAddress, imageSize);
    217   if(memmap == NULL || !memmap->Init(0)) {
     220    }
     221
     222    memmap = new Win32MemMap(this, realBaseAddress, imageSize);
     223    if(memmap == NULL || !memmap->Init()) {
    218224        goto failure;
    219   }
    220   win32file = memmap->mapViewOfFile(0, 0, 2);
    221 
    222   if(DosQueryPathInfo(szFileName, FIL_QUERYFULLNAME, szFullPath, sizeof(szFullPath)) == 0) {
    223     setFullPath(szFullPath);
    224   }
    225 
    226   if(!(fh.Characteristics & IMAGE_FILE_EXECUTABLE_IMAGE)) {//not valid
     225    }
     226    win32file = memmap->mapViewOfFile(0, 0, 2);
     227
     228    if(DosQueryPathInfo(szFileName, FIL_QUERYFULLNAME, szFullPath, sizeof(szFullPath)) == 0) {
     229        setFullPath(szFullPath);
     230    }
     231
     232    if(!(fh.Characteristics & IMAGE_FILE_EXECUTABLE_IMAGE)) {//not valid
    227233        dprintf((LOG, "Not a valid PE file!"));
    228234        WinMessageBox(HWND_DESKTOP, HWND_DESKTOP, szPEErrorMsg, szErrorTitle, 0, MB_OK | MB_ERROR | MB_MOVEABLE);
    229235        goto failure;
    230   }
    231   if(fh.Machine != IMAGE_FILE_MACHINE_I386) {
     236    }
     237    if(fh.Machine != IMAGE_FILE_MACHINE_I386) {
    232238        dprintf((LOG, "Doesn't run on x86 processors!"));
    233239        WinMessageBox(HWND_DESKTOP, HWND_DESKTOP, szCPUErrorMsg, szErrorTitle, 0, MB_OK | MB_ERROR | MB_MOVEABLE);
    234240        goto failure;
    235   }
    236   //IMAGE_FILE_SYSTEM == only drivers (device/file system/video etc)?
    237   if(fh.Characteristics & IMAGE_FILE_SYSTEM) {
     241    }
     242    //IMAGE_FILE_SYSTEM == only drivers (device/file system/video etc)?
     243    if(fh.Characteristics & IMAGE_FILE_SYSTEM) {
    238244        dprintf((LOG, "Can't convert system files"));
    239245        WinMessageBox(HWND_DESKTOP, HWND_DESKTOP, szExeErrorMsg, szErrorTitle, 0, MB_OK | MB_ERROR | MB_MOVEABLE);
    240246        goto failure;
    241   }
    242 
    243   if(fh.Characteristics & IMAGE_FILE_RELOCS_STRIPPED) {
     247    }
     248
     249    if(fh.Characteristics & IMAGE_FILE_RELOCS_STRIPPED) {
    244250        dprintf((LOG, "No fixups, might not run!"));
    245   }
    246 
    247   dprintf((LOG, "PE file           : %s", szFileName));
    248   dprintf((LOG, "PE Optional header: "));
    249   dprintf((LOG, "Preferred address : %d", oh.ImageBase ));
    250   dprintf((LOG, "Base Of Code      : %d", oh.BaseOfCode ));
    251   dprintf((LOG, "CodeSize          : %d", oh.SizeOfCode ));
    252   dprintf((LOG, "Base Of Data      : %d", oh.BaseOfData ));
    253   dprintf((LOG, "Data Size (uninit): %d", oh.SizeOfUninitializedData ));
    254   dprintf((LOG, "Data Size (init)  : %d", oh.SizeOfInitializedData ));
    255   dprintf((LOG, "Entry Point       : %d", oh.AddressOfEntryPoint ));
    256   dprintf((LOG, "Section Alignment : %d", oh.SectionAlignment ));
    257   dprintf((LOG, "Stack Reserve size: %d", oh.SizeOfStackReserve ));
    258   dprintf((LOG, "Stack Commit size : %d", oh.SizeOfStackCommit ));
    259   dprintf((LOG, "SizeOfHeapReserve : %d", oh.SizeOfHeapReserve ));
    260   dprintf((LOG, "SizeOfHeapCommit  : %d", oh.SizeOfHeapCommit ));
    261   dprintf((LOG, "FileAlignment     : %d", oh.FileAlignment ));
    262   dprintf((LOG, "Subsystem         : %d", oh.Subsystem ));
    263   dprintf((LOG, "Image Size        : %d", oh.SizeOfImage ));
    264   dprintf((LOG, "Header Size       : %d", oh.SizeOfHeaders ));
    265   dprintf((LOG, "MajorImageVersion : %d", oh.MajorImageVersion ));
    266   dprintf((LOG, "MinorImageVersion : %d", oh.MinorImageVersion ));
    267 
    268   //get header page
    269   commitPage(realBaseAddress, FALSE);
    270 
    271   nSections = NR_SECTIONS(win32file);
    272 
    273   if(!(dwFlags & FLAG_PELDR_LOADASDATAFILE))
    274   {
    275     imageSize = 0;
    276     if ((psh = (PIMAGE_SECTION_HEADER)SECTIONHDROFF (win32file)) != NULL)
     251    }
     252
     253    dprintf((LOG, "PE file           : %s", szFileName));
     254    dprintf((LOG, "PE Optional header: "));
     255    dprintf((LOG, "Preferred address : %d", oh.ImageBase ));
     256    dprintf((LOG, "Base Of Code      : %d", oh.BaseOfCode ));
     257    dprintf((LOG, "CodeSize          : %d", oh.SizeOfCode ));
     258    dprintf((LOG, "Base Of Data      : %d", oh.BaseOfData ));
     259    dprintf((LOG, "Data Size (uninit): %d", oh.SizeOfUninitializedData ));
     260    dprintf((LOG, "Data Size (init)  : %d", oh.SizeOfInitializedData ));
     261    dprintf((LOG, "Entry Point       : %d", oh.AddressOfEntryPoint ));
     262    dprintf((LOG, "Section Alignment : %d", oh.SectionAlignment ));
     263    dprintf((LOG, "Stack Reserve size: %d", oh.SizeOfStackReserve ));
     264    dprintf((LOG, "Stack Commit size : %d", oh.SizeOfStackCommit ));
     265    dprintf((LOG, "SizeOfHeapReserve : %d", oh.SizeOfHeapReserve ));
     266    dprintf((LOG, "SizeOfHeapCommit  : %d", oh.SizeOfHeapCommit ));
     267    dprintf((LOG, "FileAlignment     : %d", oh.FileAlignment ));
     268    dprintf((LOG, "Subsystem         : %d", oh.Subsystem ));
     269    dprintf((LOG, "Image Size        : %d", oh.SizeOfImage ));
     270    dprintf((LOG, "Header Size       : %d", oh.SizeOfHeaders ));
     271    dprintf((LOG, "MajorImageVersion : %d", oh.MajorImageVersion ));
     272    dprintf((LOG, "MinorImageVersion : %d", oh.MinorImageVersion ));
     273
     274    //get header page
     275    commitPage(realBaseAddress, FALSE);
     276
     277    nSections = NR_SECTIONS(win32file);
     278    section = (Section *)malloc(nSections*sizeof(Section));
     279    if(section == NULL) {
     280        DebugInt3();
     281        goto failure;
     282    }
     283    memset(section, 0, nSections*sizeof(Section));
     284
     285    if(!(dwFlags & FLAG_PELDR_LOADASDATAFILE))
    277286    {
    278         dprintf((LOG, "*************************PE SECTIONS START**************************" ));
    279         for (i=0; i<nSections; i++)
     287        imageSize = 0;
     288        if ((psh = (PIMAGE_SECTION_HEADER)SECTIONHDROFF (win32file)) != NULL)
    280289        {
    281             dprintf((LOG, "Raw data size:        %x", psh[i].SizeOfRawData ));
    282             dprintf((LOG, "Virtual Address:      %x", psh[i].VirtualAddress ));
    283             dprintf((LOG, "Virtual Address Start:%x", psh[i].VirtualAddress+oh.ImageBase ));
    284             dprintf((LOG, "Virtual Address End:  %x", psh[i].VirtualAddress+oh.ImageBase+psh[i].Misc.VirtualSize ));
    285             dprintf((LOG, "Virtual Size:         %x", psh[i].Misc.VirtualSize ));
    286             dprintf((LOG, "Pointer to raw data:  %x", psh[i].PointerToRawData ));
    287             dprintf((LOG, "Section flags:        %x\n\n", psh[i].Characteristics ));
    288 
    289             if(IsSectionType(win32file, &psh[i], IMAGE_DIRECTORY_ENTRY_BASERELOC))
     290            dprintf((LOG, "*************************PE SECTIONS START**************************" ));
     291            for (i=0; i<nSections; i++)
    290292            {
    291                 dprintf((LOG, ".reloc" ));
    292                 addSection(SECTION_RELOC, psh[i].PointerToRawData,
    293                        psh[i].SizeOfRawData, psh[i].VirtualAddress + oh.ImageBase,
    294                        psh[i].Misc.VirtualSize, psh[i].Characteristics);
    295                 continue;
    296             }
    297             if(IsSectionType(win32file, &psh[i], IMAGE_DIRECTORY_ENTRY_EXPORT))
    298             {
    299                 //SvL: Angus.exe has empty export section that's really an
    300                 //     uninitialized data section
    301                 if(psh[i].SizeOfRawData) {
    302                      dprintf((LOG, ".edata" ));
    303                      addSection(SECTION_EXPORT, psh[i].PointerToRawData,
    304                           psh[i].SizeOfRawData, psh[i].VirtualAddress + oh.ImageBase,
    305                           psh[i].Misc.VirtualSize, psh[i].Characteristics);
    306                      continue;
    307                 }
    308             }
    309             if(IsSectionType(win32file, &psh[i], IMAGE_DIRECTORY_ENTRY_RESOURCE))
    310             {
    311                 dprintf((LOG, ".rsrc" ));
    312                 addSection(SECTION_RESOURCE, psh[i].PointerToRawData,
    313                        psh[i].SizeOfRawData, psh[i].VirtualAddress + oh.ImageBase,
    314                        psh[i].Misc.VirtualSize, psh[i].Characteristics);
    315                 continue;
    316             }
    317             if(IsSectionType(win32file, &psh[i], IMAGE_DIRECTORY_ENTRY_TLS))
    318             {
    319                 dprintf((LOG, "TLS section"));
    320                 tlsDir = (IMAGE_TLS_DIRECTORY *)ImageDirectoryOffset(win32file, IMAGE_DIRECTORY_ENTRY_TLS);
    321                 if(tlsDir) {
     293                dprintf((LOG, "Raw data size:        %x", psh[i].SizeOfRawData ));
     294                dprintf((LOG, "Virtual Address:      %x", psh[i].VirtualAddress ));
     295                dprintf((LOG, "Virtual Address Start:%x", psh[i].VirtualAddress+oh.ImageBase ));
     296                dprintf((LOG, "Virtual Address End:  %x", psh[i].VirtualAddress+oh.ImageBase+psh[i].Misc.VirtualSize ));
     297                dprintf((LOG, "Virtual Size:         %x", psh[i].Misc.VirtualSize ));
     298                dprintf((LOG, "Pointer to raw data:  %x", psh[i].PointerToRawData ));
     299                dprintf((LOG, "Section flags:        %x\n\n", psh[i].Characteristics ));
     300
     301                if(IsSectionType(win32file, &psh[i], IMAGE_DIRECTORY_ENTRY_BASERELOC))
     302                {
     303                    dprintf((LOG, ".reloc" ));
     304                    addSection(SECTION_RELOC, psh[i].PointerToRawData,
     305                               psh[i].SizeOfRawData, psh[i].VirtualAddress + oh.ImageBase,
     306                               psh[i].Misc.VirtualSize, psh[i].Characteristics);
     307                    continue;
     308                }
     309                if(IsSectionType(win32file, &psh[i], IMAGE_DIRECTORY_ENTRY_EXPORT))
     310                {
     311                    //SvL: Angus.exe has empty export section that's really an
     312                    //     uninitialized data section
     313                    if(psh[i].SizeOfRawData) {
     314                         dprintf((LOG, ".edata" ));
     315                         addSection(SECTION_EXPORT, psh[i].PointerToRawData,
     316                                    psh[i].SizeOfRawData, psh[i].VirtualAddress + oh.ImageBase,
     317                                    psh[i].Misc.VirtualSize, psh[i].Characteristics);
     318                        continue;
     319                    }
     320                }
     321                if(IsSectionType(win32file, &psh[i], IMAGE_DIRECTORY_ENTRY_RESOURCE))
     322                {
     323                    dprintf((LOG, ".rsrc" ));
     324                    addSection(SECTION_RESOURCE, psh[i].PointerToRawData,
     325                               psh[i].SizeOfRawData, psh[i].VirtualAddress + oh.ImageBase,
     326                               psh[i].Misc.VirtualSize, psh[i].Characteristics);
     327                    continue;
     328                }
     329                if(IsSectionType(win32file, &psh[i], IMAGE_DIRECTORY_ENTRY_TLS))
     330                {
     331                    dprintf((LOG, "TLS section"));
     332                    tlsDir = (IMAGE_TLS_DIRECTORY *)ImageDirectoryOffset(win32file, IMAGE_DIRECTORY_ENTRY_TLS);
     333                    if(tlsDir) {
    322334                        addSection(SECTION_TLS, psh[i].PointerToRawData,
    323335                                   psh[i].SizeOfRawData, psh[i].VirtualAddress + oh.ImageBase,
    324336                                   psh[i].Misc.VirtualSize, psh[i].Characteristics);
    325                 }
    326                 continue;
    327             }
    328             if(IsSectionType(win32file, &psh[i], IMAGE_DIRECTORY_ENTRY_DEBUG))
    329             {
    330                 dprintf((LOG, ".rdebug" ));
    331                 addSection(SECTION_DEBUG,  psh[i].PointerToRawData,
    332                            psh[i].SizeOfRawData, psh[i].VirtualAddress + oh.ImageBase,
    333                            psh[i].Misc.VirtualSize, psh[i].Characteristics);
    334                 continue;
    335             }
    336             if(IsSectionType(win32file, &psh[i], IMAGE_DIRECTORY_ENTRY_IMPORT))
    337             {
    338                 int type = SECTION_IMPORT;
    339 
    340                 dprintf((LOG, "Import Data Section" ));
    341                 if(psh[i].Characteristics & IMAGE_SCN_CNT_CODE) {
    342                     dprintf((LOG, "Also Code Section"));
    343                     type |= SECTION_CODE;
    344                 }
    345                 addSection(type, psh[i].PointerToRawData,
    346                        psh[i].SizeOfRawData, psh[i].VirtualAddress + oh.ImageBase,
    347                        psh[i].Misc.VirtualSize, psh[i].Characteristics);
    348                 continue;
    349             }
    350 
    351             //KSO Sun 1998-08-09: Borland does not alway set the CODE flag for its "CODE" section
    352             if(psh[i].Characteristics & IMAGE_SCN_CNT_CODE ||
    353                (psh[i].Characteristics & IMAGE_SCN_MEM_EXECUTE &&
    354                !(psh[i].Characteristics & (IMAGE_SCN_CNT_UNINITIALIZED_DATA | IMAGE_SCN_CNT_INITIALIZED_DATA))) //KSO: make sure its not marked as a datasection
    355                 )
    356             {
    357                 dprintf((LOG, "Code Section"));
    358                 addSection(SECTION_CODE, psh[i].PointerToRawData,
    359                        psh[i].SizeOfRawData, psh[i].VirtualAddress + oh.ImageBase,
    360                        psh[i].Misc.VirtualSize, psh[i].Characteristics);
    361                 continue;
    362             }
    363             if(!(psh[i].Characteristics & IMAGE_SCN_MEM_WRITE)) { //read only data section
    364                 dprintf((LOG, "Read Only Data Section" ));
    365                 addSection(SECTION_READONLYDATA, psh[i].PointerToRawData,
    366                        psh[i].SizeOfRawData, psh[i].VirtualAddress + oh.ImageBase,
    367                        psh[i].Misc.VirtualSize, psh[i].Characteristics);
    368                 continue;
    369             }
    370             if(psh[i].Characteristics & IMAGE_SCN_CNT_UNINITIALIZED_DATA) {
    371                 dprintf((LOG, "Uninitialized Data Section" ));
    372                 addSection(SECTION_UNINITDATA, psh[i].PointerToRawData,
    373                        psh[i].SizeOfRawData, psh[i].VirtualAddress + oh.ImageBase,
    374                        psh[i].Misc.VirtualSize, psh[i].Characteristics);
    375                 continue;
    376             }
    377             if(psh[i].Characteristics & IMAGE_SCN_CNT_INITIALIZED_DATA) {
    378                 dprintf((LOG, "Initialized Data Section" ));
    379                 addSection(SECTION_INITDATA, psh[i].PointerToRawData,
    380                        psh[i].SizeOfRawData, psh[i].VirtualAddress + oh.ImageBase,
    381                        psh[i].Misc.VirtualSize, psh[i].Characteristics);
    382                 continue;
    383             }
    384             if(psh[i].Characteristics & (IMAGE_SCN_MEM_WRITE | IMAGE_SCN_MEM_READ)) {
    385                 dprintf((LOG, "Other Section, stored as read/write uninit data" ));
    386                 addSection(SECTION_UNINITDATA, psh[i].PointerToRawData,
    387                        psh[i].SizeOfRawData, psh[i].VirtualAddress + oh.ImageBase,
    388                        psh[i].Misc.VirtualSize, psh[i].Characteristics);
    389                 continue;
    390             }
    391             dprintf((LOG, "Unknown section" ));
    392             goto failure;
    393          }
    394     }
    395   }
    396   else {
     337                    }
     338                    continue;
     339                }
     340                if(IsSectionType(win32file, &psh[i], IMAGE_DIRECTORY_ENTRY_DEBUG))
     341                {
     342                    dprintf((LOG, ".rdebug" ));
     343                    addSection(SECTION_DEBUG,  psh[i].PointerToRawData,
     344                               psh[i].SizeOfRawData, psh[i].VirtualAddress + oh.ImageBase,
     345                               psh[i].Misc.VirtualSize, psh[i].Characteristics);
     346                    continue;
     347                }
     348                if(IsSectionType(win32file, &psh[i], IMAGE_DIRECTORY_ENTRY_IMPORT))
     349                {
     350                    int type = SECTION_IMPORT;
     351
     352                    dprintf((LOG, "Import Data Section" ));
     353                    if(psh[i].Characteristics & IMAGE_SCN_CNT_CODE) {
     354                        dprintf((LOG, "Also Code Section"));
     355                        type |= SECTION_CODE;
     356                    }
     357                    addSection(type, psh[i].PointerToRawData,
     358                               psh[i].SizeOfRawData, psh[i].VirtualAddress + oh.ImageBase,
     359                               psh[i].Misc.VirtualSize, psh[i].Characteristics);
     360                    continue;
     361                }
     362
     363                //KSO Sun 1998-08-09: Borland does not alway set the CODE flag for its "CODE" section
     364                if(psh[i].Characteristics & IMAGE_SCN_CNT_CODE ||
     365                   (psh[i].Characteristics & IMAGE_SCN_MEM_EXECUTE &&
     366                   !(psh[i].Characteristics & (IMAGE_SCN_CNT_UNINITIALIZED_DATA | IMAGE_SCN_CNT_INITIALIZED_DATA))) //KSO: make sure its not marked as a datasection
     367                  )
     368                {
     369                    dprintf((LOG, "Code Section"));
     370                    addSection(SECTION_CODE, psh[i].PointerToRawData,
     371                               psh[i].SizeOfRawData, psh[i].VirtualAddress + oh.ImageBase,
     372                               psh[i].Misc.VirtualSize, psh[i].Characteristics);
     373                    continue;
     374                }
     375                if(!(psh[i].Characteristics & IMAGE_SCN_MEM_WRITE)) { //read only data section
     376                    dprintf((LOG, "Read Only Data Section" ));
     377                    addSection(SECTION_READONLYDATA, psh[i].PointerToRawData,
     378                               psh[i].SizeOfRawData, psh[i].VirtualAddress + oh.ImageBase,
     379                               psh[i].Misc.VirtualSize, psh[i].Characteristics);
     380                    continue;
     381                }
     382                if(psh[i].Characteristics & IMAGE_SCN_CNT_UNINITIALIZED_DATA) {
     383                    dprintf((LOG, "Uninitialized Data Section" ));
     384                    addSection(SECTION_UNINITDATA, psh[i].PointerToRawData,
     385                               psh[i].SizeOfRawData, psh[i].VirtualAddress + oh.ImageBase,
     386                               psh[i].Misc.VirtualSize, psh[i].Characteristics);
     387                    continue;
     388                }
     389                if(psh[i].Characteristics & IMAGE_SCN_CNT_INITIALIZED_DATA) {
     390                    dprintf((LOG, "Initialized Data Section" ));
     391                    addSection(SECTION_INITDATA, psh[i].PointerToRawData,
     392                               psh[i].SizeOfRawData, psh[i].VirtualAddress + oh.ImageBase,
     393                               psh[i].Misc.VirtualSize, psh[i].Characteristics);
     394                    continue;
     395                }
     396                if(psh[i].Characteristics & (IMAGE_SCN_MEM_WRITE | IMAGE_SCN_MEM_READ)) {
     397                    dprintf((LOG, "Other Section, stored as read/write uninit data" ));
     398                    addSection(SECTION_UNINITDATA, psh[i].PointerToRawData,
     399                               psh[i].SizeOfRawData, psh[i].VirtualAddress + oh.ImageBase,
     400                               psh[i].Misc.VirtualSize, psh[i].Characteristics);
     401                    continue;
     402                }
     403                dprintf((LOG, "Unknown section" ));
     404                goto failure;
     405            }
     406        }
     407    }
     408    else {
    397409        if(GetSectionHdrByImageDir(win32file, IMAGE_DIRECTORY_ENTRY_RESOURCE, &sh))
    398410        {
     
    401413                       sh.Misc.VirtualSize, sh.Characteristics);
    402414        }
    403   }
    404   dprintf((LOG, "*************************PE SECTIONS END **************************" ));
    405 
    406   imageSize += imageVirtBase - oh.ImageBase;
    407   dprintf((LOG, "Total size of Image %x", imageSize ));
    408   dprintf((LOG, "imageVirtBase       %x", imageVirtBase ));
    409   dprintf((LOG, "imageVirtEnd        %x", imageVirtEnd ));
    410 
    411   //In case there are any gaps between sections, adjust size
    412   if(imageSize != imageVirtEnd - oh.ImageBase)
    413   {
    414     dprintf((LOG, "imageSize != imageVirtEnd - oh.ImageBase!" ));
    415     imageSize = imageVirtEnd - oh.ImageBase;
    416   }
    417   if(imageSize < oh.SizeOfImage) {
    418     imageSize = oh.SizeOfImage;
    419   }
    420 
    421   dprintf((LOG, "OS/2 base address %x", realBaseAddress ));
    422   if(oh.AddressOfEntryPoint) {
    423     entryPoint = realBaseAddress + oh.AddressOfEntryPoint;
    424   }
    425   else {
    426     dprintf((LOG, "EntryPoint == NULL" ));
    427     entryPoint = NULL;
    428   }
    429 
    430   //set memory protection flags
    431   if(setMemFlags() == FALSE) {
    432     dprintf((LOG, "Failed to set memory protection" ));
    433     goto failure;
    434   }
    435 
    436   if(realBaseAddress != oh.ImageBase) {
    437     pFixups     = (PIMAGE_BASE_RELOCATION)ImageDirectoryOffset(win32file, IMAGE_DIRECTORY_ENTRY_BASERELOC);
    438     dwFixupSize = ImageDirectorySize(win32file, IMAGE_DIRECTORY_ENTRY_BASERELOC);
    439     commitPage((ULONG)pFixups, FALSE);
    440   }
    441 
    442   if(!(dwFlags & FLAG_PELDR_LOADASDATAFILE))
    443   {
    444     if(tlsDir = (IMAGE_TLS_DIRECTORY *)ImageDirectoryOffset(win32file, IMAGE_DIRECTORY_ENTRY_TLS))
     415    }
     416    dprintf((LOG, "*************************PE SECTIONS END **************************" ));
     417
     418    imageSize += imageVirtBase - oh.ImageBase;
     419    dprintf((LOG, "Total size of Image %x", imageSize ));
     420    dprintf((LOG, "imageVirtBase       %x", imageVirtBase ));
     421    dprintf((LOG, "imageVirtEnd        %x", imageVirtEnd ));
     422
     423    //In case there are any gaps between sections, adjust size
     424    if(imageSize != imageVirtEnd - oh.ImageBase)
    445425    {
    446         Section *sect;
    447         BOOL     fTLSFixups = FALSE;
    448 
    449         sect = findSectionByAddr(tlsDir->StartAddressOfRawData);
    450         //There might be fixups for the TLS structure, so search the sections
    451         //by the OS/2 virtual address too
    452         if(sect == NULL) {
    453             sect = findSectionByOS2Addr(tlsDir->StartAddressOfRawData);
    454             fTLSFixups = TRUE;
    455         }
    456 
    457         dprintf((LOG, "TLS Directory" ));
    458         dprintf((LOG, "TLS Address of Index     %x", tlsDir->AddressOfIndex ));
    459         dprintf((LOG, "TLS Address of Callbacks %x", tlsDir->AddressOfCallBacks ));
    460         dprintf((LOG, "TLS SizeOfZeroFill       %x", tlsDir->SizeOfZeroFill ));
    461         dprintf((LOG, "TLS Characteristics      %x", tlsDir->Characteristics ));
    462         if(sect == NULL) {
    463             dprintf((LOG, "Couldn't find TLS section!!" ));
    464             goto failure;
    465         }
    466         setTLSAddress((char *)sect->realvirtaddr);
    467         setTLSInitSize(tlsDir->EndAddressOfRawData - tlsDir->StartAddressOfRawData);
    468         setTLSTotalSize(tlsDir->EndAddressOfRawData - tlsDir->StartAddressOfRawData + tlsDir->SizeOfZeroFill);
    469 
    470         fTLSFixups = FALSE;
    471         sect = findSectionByAddr((ULONG)tlsDir->AddressOfIndex);
    472         //There might be fixups for the TLS structure, so search the sections
    473         //by the OS/2 virtual address too
    474         if(sect == NULL) {
    475             sect = findSectionByOS2Addr((ULONG)tlsDir->AddressOfIndex);
    476             fTLSFixups = TRUE;
    477         }
    478         if(sect == NULL) {
    479             dprintf((LOG, "Couldn't find TLS AddressOfIndex section!!" ));
    480             goto failure;
    481         }
    482         if(fTLSFixups) {
    483             setTLSIndexAddr((LPDWORD)tlsDir->AddressOfIndex);  //no fixup required
    484         }
    485         else {//need to add a manual fixup
    486             setTLSIndexAddr((LPDWORD)(sect->realvirtaddr + ((ULONG)tlsDir->AddressOfIndex - sect->virtaddr)));
    487         }
    488 
    489         if((ULONG)tlsDir->AddressOfCallBacks != 0)
     426        dprintf((LOG, "imageSize != imageVirtEnd - oh.ImageBase!" ));
     427        imageSize = imageVirtEnd - oh.ImageBase;
     428    }
     429    if(imageSize < oh.SizeOfImage) {
     430        imageSize = oh.SizeOfImage;
     431    }
     432
     433    dprintf((LOG, "OS/2 base address %x", realBaseAddress ));
     434    if(oh.AddressOfEntryPoint) {
     435        entryPoint = realBaseAddress + oh.AddressOfEntryPoint;
     436    }
     437    else {
     438        dprintf((LOG, "EntryPoint == NULL" ));
     439        entryPoint = NULL;
     440    }
     441
     442    //set memory protection flags
     443    if(setMemFlags() == FALSE) {
     444        dprintf((LOG, "Failed to set memory protection" ));
     445        goto failure;
     446    }
     447
     448    if(realBaseAddress != oh.ImageBase) {
     449        pFixups     = (PIMAGE_BASE_RELOCATION)ImageDirectoryOffset(win32file, IMAGE_DIRECTORY_ENTRY_BASERELOC);
     450        dwFixupSize = ImageDirectorySize(win32file, IMAGE_DIRECTORY_ENTRY_BASERELOC);
     451        commitPage((ULONG)pFixups, FALSE);
     452    }
     453
     454    if(!(dwFlags & FLAG_PELDR_LOADASDATAFILE))
     455    {
     456        if(tlsDir = (IMAGE_TLS_DIRECTORY *)ImageDirectoryOffset(win32file, IMAGE_DIRECTORY_ENTRY_TLS))
    490457        {
     458            Section *sect;
     459            BOOL     fTLSFixups = FALSE;
     460
     461            sect = findSectionByAddr(tlsDir->StartAddressOfRawData);
     462            //There might be fixups for the TLS structure, so search the sections
     463            //by the OS/2 virtual address too
     464            if(sect == NULL) {
     465                sect = findSectionByOS2Addr(tlsDir->StartAddressOfRawData);
     466                fTLSFixups = TRUE;
     467            }
     468
     469            dprintf((LOG, "TLS Directory" ));
     470            dprintf((LOG, "TLS Address of Index     %x", tlsDir->AddressOfIndex ));
     471            dprintf((LOG, "TLS Address of Callbacks %x", tlsDir->AddressOfCallBacks ));
     472            dprintf((LOG, "TLS SizeOfZeroFill       %x", tlsDir->SizeOfZeroFill ));
     473            dprintf((LOG, "TLS Characteristics      %x", tlsDir->Characteristics ));
     474            if(sect == NULL) {
     475                dprintf((LOG, "Couldn't find TLS section!!" ));
     476                goto failure;
     477            }
     478            setTLSAddress((char *)sect->realvirtaddr);
     479            setTLSInitSize(tlsDir->EndAddressOfRawData - tlsDir->StartAddressOfRawData);
     480            setTLSTotalSize(tlsDir->EndAddressOfRawData - tlsDir->StartAddressOfRawData + tlsDir->SizeOfZeroFill);
     481
    491482            fTLSFixups = FALSE;
    492 
    493             sect = findSectionByAddr((ULONG)tlsDir->AddressOfCallBacks);
     483            sect = findSectionByAddr((ULONG)tlsDir->AddressOfIndex);
    494484            //There might be fixups for the TLS structure, so search the sections
    495485            //by the OS/2 virtual address too
     
    499489            }
    500490            if(sect == NULL) {
    501                 dprintf((LOG, "Couldn't find TLS AddressOfCallBacks section!!" ));
     491                dprintf((LOG, "Couldn't find TLS AddressOfIndex section!!" ));
    502492                goto failure;
    503493            }
    504494            if(fTLSFixups) {
    505                 setTLSCallBackAddr((PIMAGE_TLS_CALLBACK *)tlsDir->AddressOfCallBacks); //no fixup required
     495                setTLSIndexAddr((LPDWORD)tlsDir->AddressOfIndex); //no fixup required
    506496            }
    507497            else {//need to add a manual fixup
    508                 setTLSCallBackAddr((PIMAGE_TLS_CALLBACK *)(sect->realvirtaddr + ((ULONG)tlsDir->AddressOfCallBacks - sect->virtaddr)));
    509             }
    510             //modify tls callback pointers for new image base address
    511             int i = 0;
    512             while(tlsCallBackAddr[i])
     498                setTLSIndexAddr((LPDWORD)(sect->realvirtaddr + ((ULONG)tlsDir->AddressOfIndex - sect->virtaddr)));
     499            }
     500
     501            if((ULONG)tlsDir->AddressOfCallBacks != 0)
    513502            {
    514503                fTLSFixups = FALSE;
    515504
    516                 sect = findSectionByAddr((ULONG)tlsCallBackAddr[i]);
     505                sect = findSectionByAddr((ULONG)tlsDir->AddressOfCallBacks);
    517506                //There might be fixups for the TLS structure, so search the sections
    518507                //by the OS/2 virtual address too
    519508                if(sect == NULL) {
    520                     sect = findSectionByOS2Addr((ULONG)tlsCallBackAddr[i]);
     509                    sect = findSectionByOS2Addr((ULONG)tlsDir->AddressOfIndex);
    521510                    fTLSFixups = TRUE;
    522511                }
    523512                if(sect == NULL) {
    524                     dprintf((LOG, "Couldn't find TLS callback section!!" ));
     513                    dprintf((LOG, "Couldn't find TLS AddressOfCallBacks section!!" ));
    525514                    goto failure;
    526515                }
    527516                if(fTLSFixups) {
    528                         tlsCallBackAddr[i] = tlsCallBackAddr[i];
    529                 }
    530                 else    tlsCallBackAddr[i] = (PIMAGE_TLS_CALLBACK)(realBaseAddress + ((ULONG)tlsCallBackAddr[i] - oh.ImageBase));
    531                 i++;
    532             }
    533         }
    534    }
     517                    setTLSCallBackAddr((PIMAGE_TLS_CALLBACK *)tlsDir->AddressOfCallBacks); //no fixup required
     518                }
     519                else {//need to add a manual fixup
     520                    setTLSCallBackAddr((PIMAGE_TLS_CALLBACK *)(sect->realvirtaddr + ((ULONG)tlsDir->AddressOfCallBacks - sect->virtaddr)));
     521                }
     522                //modify tls callback pointers for new image base address
     523                int i = 0;
     524                while(tlsCallBackAddr[i])
     525                {
     526                    fTLSFixups = FALSE;
     527
     528                    sect = findSectionByAddr((ULONG)tlsCallBackAddr[i]);
     529                    //There might be fixups for the TLS structure, so search the sections
     530                    //by the OS/2 virtual address too
     531                    if(sect == NULL) {
     532                        sect = findSectionByOS2Addr((ULONG)tlsCallBackAddr[i]);
     533                        fTLSFixups = TRUE;
     534                    }
     535                    if(sect == NULL) {
     536                        dprintf((LOG, "Couldn't find TLS callback section!!" ));
     537                        goto failure;
     538                    }
     539                    if(fTLSFixups) {
     540                            tlsCallBackAddr[i] = tlsCallBackAddr[i];
     541                    }
     542                    else    tlsCallBackAddr[i] = (PIMAGE_TLS_CALLBACK)(realBaseAddress + ((ULONG)tlsCallBackAddr[i] - oh.ImageBase));
     543                    i++;
     544                }
     545            }
     546        }
    535547
    536548#ifdef DEBUG
    537    dprintf((LOG, "Image directories: "));
    538    for (i = 0; i < IMAGE_NUMBEROF_DIRECTORY_ENTRIES; i++)
    539    {
    540         char *pszName;
    541 
    542         if(oh.DataDirectory[i].VirtualAddress && oh.DataDirectory[i].Size) {
    543             switch (i)
     549        dprintf((LOG, "Image directories: "));
     550        for (i = 0; i < IMAGE_NUMBEROF_DIRECTORY_ENTRIES; i++)
     551        {
     552            char *pszName;
     553
     554            if(oh.DataDirectory[i].VirtualAddress && oh.DataDirectory[i].Size) {
     555                switch (i)
     556                {
     557                case IMAGE_DIRECTORY_ENTRY_EXPORT:      pszName = "Export Directory (IMAGE_DIRECTORY_ENTRY_EXPORT)"; break;
     558                case IMAGE_DIRECTORY_ENTRY_IMPORT:      pszName = "Import Directory (IMAGE_DIRECTORY_ENTRY_IMPORT)"; break;
     559                case IMAGE_DIRECTORY_ENTRY_RESOURCE:    pszName = "Resource Directory (IMAGE_DIRECTORY_ENTRY_RESOURCE)"; break;
     560                case IMAGE_DIRECTORY_ENTRY_EXCEPTION:   pszName = "Exception Directory (IMAGE_DIRECTORY_ENTRY_EXCEPTION)"; break;
     561                case IMAGE_DIRECTORY_ENTRY_SECURITY:    pszName = "Security Directory (IMAGE_DIRECTORY_ENTRY_SECURITY)"; break;
     562                case IMAGE_DIRECTORY_ENTRY_BASERELOC:   pszName = "Base Relocation Table (IMAGE_DIRECTORY_ENTRY_BASERELOC)"; break;
     563                case IMAGE_DIRECTORY_ENTRY_DEBUG:       pszName = "Debug Directory (IMAGE_DIRECTORY_ENTRY_DEBUG)"; break;
     564                case IMAGE_DIRECTORY_ENTRY_COPYRIGHT:   pszName = "Description String (IMAGE_DIRECTORY_ENTRY_COPYRIGHT)"; break;
     565                case IMAGE_DIRECTORY_ENTRY_GLOBALPTR:   pszName = "Machine Value (MIPS GP) (IMAGE_DIRECTORY_ENTRY_GLOBALPTR)"; break;
     566                case IMAGE_DIRECTORY_ENTRY_TLS:         pszName = "TLS Directory (IMAGE_DIRECTORY_ENTRY_TLS)"; break;
     567                case IMAGE_DIRECTORY_ENTRY_LOAD_CONFIG: pszName = "Load Configuration Directory (IMAGE_DIRECTORY_ENTRY_LOAD_CONFIG)"; break;
     568                case IMAGE_DIRECTORY_ENTRY_BOUND_IMPORT:pszName = "Bound Import Directory in headers (IMAGE_DIRECTORY_ENTRY_BOUND_IMPORT)"; break;
     569                case IMAGE_DIRECTORY_ENTRY_IAT:         pszName = "Import Address Table (IMAGE_DIRECTORY_ENTRY_IAT)"; break;
     570                default:
     571                    pszName = "unknown";
     572                }
     573                dprintf((LOG, "directory %s", pszName));
     574                dprintf((LOG, "          Address    0x%08x", oh.DataDirectory[i].VirtualAddress));
     575                dprintf((LOG, "          Size       0x%08x", oh.DataDirectory[i].Size));
     576            }
     577        }
     578        dprintf((LOG, "\n\n"));
     579#endif
     580
     581#ifdef COMMIT_ALL
     582        for (i=0; i<nSections; i++) {
     583            commitPage((ULONG)section[i].realvirtaddr, FALSE, COMPLETE_SECTION);
     584        }
     585#else
     586        for (i=0; i<nSections; i++) {
     587            switch(section[i].type)
    544588            {
    545             case IMAGE_DIRECTORY_ENTRY_EXPORT:      pszName = "Export Directory (IMAGE_DIRECTORY_ENTRY_EXPORT)"; break;
    546             case IMAGE_DIRECTORY_ENTRY_IMPORT:      pszName = "Import Directory (IMAGE_DIRECTORY_ENTRY_IMPORT)"; break;
    547             case IMAGE_DIRECTORY_ENTRY_RESOURCE:    pszName = "Resource Directory (IMAGE_DIRECTORY_ENTRY_RESOURCE)"; break;
    548             case IMAGE_DIRECTORY_ENTRY_EXCEPTION:   pszName = "Exception Directory (IMAGE_DIRECTORY_ENTRY_EXCEPTION)"; break;
    549             case IMAGE_DIRECTORY_ENTRY_SECURITY:    pszName = "Security Directory (IMAGE_DIRECTORY_ENTRY_SECURITY)"; break;
    550             case IMAGE_DIRECTORY_ENTRY_BASERELOC:   pszName = "Base Relocation Table (IMAGE_DIRECTORY_ENTRY_BASERELOC)"; break;
    551             case IMAGE_DIRECTORY_ENTRY_DEBUG:       pszName = "Debug Directory (IMAGE_DIRECTORY_ENTRY_DEBUG)"; break;
    552             case IMAGE_DIRECTORY_ENTRY_COPYRIGHT:   pszName = "Description String (IMAGE_DIRECTORY_ENTRY_COPYRIGHT)"; break;
    553             case IMAGE_DIRECTORY_ENTRY_GLOBALPTR:   pszName = "Machine Value (MIPS GP) (IMAGE_DIRECTORY_ENTRY_GLOBALPTR)"; break;
    554             case IMAGE_DIRECTORY_ENTRY_TLS:         pszName = "TLS Directory (IMAGE_DIRECTORY_ENTRY_TLS)"; break;
    555             case IMAGE_DIRECTORY_ENTRY_LOAD_CONFIG: pszName = "Load Configuration Directory (IMAGE_DIRECTORY_ENTRY_LOAD_CONFIG)"; break;
    556             case IMAGE_DIRECTORY_ENTRY_BOUND_IMPORT:pszName = "Bound Import Directory in headers (IMAGE_DIRECTORY_ENTRY_BOUND_IMPORT)"; break;
    557             case IMAGE_DIRECTORY_ENTRY_IAT:         pszName = "Import Address Table (IMAGE_DIRECTORY_ENTRY_IAT)"; break;
    558             default:
    559                 pszName = "unknown";
    560             }
    561             dprintf((LOG, "directory %s", pszName));
    562             dprintf((LOG, "          Address    0x%08x", oh.DataDirectory[i].VirtualAddress));
    563             dprintf((LOG, "          Size       0x%08x", oh.DataDirectory[i].Size));
    564         }
    565     }
    566     dprintf((LOG, "\n\n"));
     589            case SECTION_IMPORT:
     590            case SECTION_RELOC:
     591            case SECTION_EXPORT:
     592                commitPage((ULONG)section[i].realvirtaddr, FALSE, COMPLETE_SECTION);
     593                break;
     594            }
     595        }
    567596#endif
    568 
     597        if(processExports((char *)win32file) == FALSE) {
     598            dprintf((LOG, "Failed to process exported apis" ));
     599            goto failure;
     600        }
     601    }
    569602#ifdef COMMIT_ALL
    570     for (i=0; i<nSections; i++) {
    571         commitPage((ULONG)section[i].realvirtaddr, FALSE, COMPLETE_SECTION);
    572     }
    573 #else
    574     for (i=0; i<nSections; i++) {
    575         switch(section[i].type)
    576         {
    577         case SECTION_IMPORT:
    578         case SECTION_RELOC:
    579         case SECTION_EXPORT:
    580             commitPage((ULONG)section[i].realvirtaddr, FALSE, COMPLETE_SECTION);
    581             break;
    582         }
     603    else {
     604        commitPage((ULONG)section[0].realvirtaddr, FALSE, COMPLETE_SECTION);
    583605    }
    584606#endif
    585     if(processExports((char *)win32file) == FALSE) {
    586         dprintf((LOG, "Failed to process exported apis" ));
    587         goto failure;
    588     }
    589   }
    590 #ifdef COMMIT_ALL
    591   else {
    592         commitPage((ULONG)section[0].realvirtaddr, FALSE, COMPLETE_SECTION);
    593   }
     607
     608#ifndef COMMIT_ALL
     609    if(entryPoint) {
     610        //commit code at entrypoint, since we going to call it anyway
     611        commitPage((ULONG)entryPoint, FALSE);
     612    }
    594613#endif
    595614
    596   //SvL: Use pointer to image header as module handle now. Some apps needs this
    597   hinstance = (HINSTANCE)realBaseAddress;
    598 
    599   //SvL: Set instance handle in process database structure
    600   SetPDBInstance(hinstance);
    601 
    602   //PH: get pResRootDir pointer correct first, since processImports may
    603   //    implicitly call functions depending on it.
    604   if(oh.DataDirectory[IMAGE_DIRECTORY_ENTRY_RESOURCE].VirtualAddress && oh.DataDirectory[IMAGE_DIRECTORY_ENTRY_RESOURCE].Size)
    605   {
    606     //get offset in resource object of directory entry
    607     pResRootDir = (PIMAGE_RESOURCE_DIRECTORY)(oh.DataDirectory[IMAGE_DIRECTORY_ENTRY_RESOURCE].VirtualAddress + realBaseAddress);
    608     ulRVAResourceSection = oh.DataDirectory[IMAGE_DIRECTORY_ENTRY_RESOURCE].VirtualAddress;
    609   }
    610 
    611   if(!(dwFlags & (FLAG_PELDR_LOADASDATAFILE | FLAG_PELDR_SKIPIMPORTS)))
    612   {
    613     if(processImports((char *)win32file) == FALSE) {
    614         dprintf((LOG, "Failed to process imports!" ));
    615         goto failure;
    616     }
    617   }
    618   return(TRUE);
     615    //SvL: Use pointer to image header as module handle now. Some apps needs this
     616    hinstance = (HINSTANCE)realBaseAddress;
     617
     618    //SvL: Set instance handle in process database structure
     619    SetPDBInstance(hinstance);
     620
     621    //PH: get pResRootDir pointer correct first, since processImports may
     622    //    implicitly call functions depending on it.
     623    if(oh.DataDirectory[IMAGE_DIRECTORY_ENTRY_RESOURCE].VirtualAddress && oh.DataDirectory[IMAGE_DIRECTORY_ENTRY_RESOURCE].Size)
     624    {
     625        //get offset in resource object of directory entry
     626        pResRootDir = (PIMAGE_RESOURCE_DIRECTORY)(oh.DataDirectory[IMAGE_DIRECTORY_ENTRY_RESOURCE].VirtualAddress + realBaseAddress);
     627        ulRVAResourceSection = oh.DataDirectory[IMAGE_DIRECTORY_ENTRY_RESOURCE].VirtualAddress;
     628    }
     629
     630    if(!(dwFlags & (FLAG_PELDR_LOADASDATAFILE | FLAG_PELDR_SKIPIMPORTS)))
     631    {
     632        if(processImports((char *)win32file) == FALSE) {
     633            dprintf((LOG, "Failed to process imports!" ));
     634            goto failure;
     635        }
     636    }
     637    return(TRUE);
    619638
    620639failure:
    621   if(memmap) {
    622     delete memmap;
    623     memmap = NULL;
    624   }
    625   if(hFile) {
    626     OSLibDosClose(hFile);
    627     hFile = 0;
    628   }
    629   errorState = ERROR_INTERNAL;
    630   return FALSE;
    631 }
    632 //******************************************************************************
    633 //commits image page(s) when an access violation exception is dispatched
    634 //virtAddress = address of exception (rounded down to page boundary)
     640    if(memmap) {
     641        delete memmap;
     642        memmap = NULL;
     643    }
     644    if(hFile) {
     645        OSLibDosClose(hFile);
     646        hFile = 0;
     647    }
     648    errorState = ERROR_INTERNAL;
     649    return FALSE;
     650}
     651//******************************************************************************
     652//  commitPage:
     653//      commits image page(s) when an access violation exception is received
     654//      (usually called from exception.cpp; also from other methods in this file)
     655//
     656//  Parameters:
     657//      virtAddress     - address of exception (rounded down to page boundary)
     658//      fWriteAccess    - type of access violation (read or write)
     659//      fPageCmd        - SINGLE_PAGE       -> commit single page
     660//                        SECTION_PAGES     -> commit default nr of pages
     661//                        COMPLETE_SECTION  -> commit entire section
     662//
     663//  Remarks:
     664//      DosEnterCritSec/DosExitCritSec is used to make sure the other threads in
     665//      the application can't touch the pages before they are loaded from disk and
     666//      fixups are applied.
     667//
     668//  TODO:
     669//      SECTION_PAGES:  - don't load pages starting at access violation address, but
     670//                        a region surrounding it (e.g. -32k -> + 32k)
     671//                        this will prevent many pagefaults when the app uses
     672//                        pages with a lower addr.
     673//
    635674//******************************************************************************
    636675BOOL Win32PeLdrImage::commitPage(ULONG virtAddress, BOOL fWriteAccess, int fPageCmd)
     
    641680 APIRET   rc;
    642681
    643   //Round down to nearest page boundary
    644   virtAddress = virtAddress & ~0xFFF;
    645 
    646   section = findSectionByOS2Addr(virtAddress);
    647   if(section == NULL) {
    648     size        = 4096;
    649     sectionsize = 4096;
    650     protflags   = PAG_READ|PAG_WRITE; //readonly?
    651     section = findPreviousSectionByOS2Addr(virtAddress);
    652     if(section == NULL) {//access to header
    653         offset     = 0;
    654         fileoffset = virtAddress - realBaseAddress;
     682    //Round down to nearest page boundary
     683    virtAddress = virtAddress & ~0xFFF;
     684
     685    section = findSectionByOS2Addr(virtAddress);
     686    if(section == NULL) {
     687        size        = 4096;
     688        sectionsize = 4096;
     689        protflags   = PAG_READ|PAG_WRITE; //readonly?
     690        section = findPreviousSectionByOS2Addr(virtAddress);
     691        if(section == NULL) {//access to header
     692            offset     = 0;
     693            fileoffset = virtAddress - realBaseAddress;
     694        }
     695        else {
     696            offset     = virtAddress - (section->realvirtaddr + section->virtualsize);
     697            fileoffset = section->rawoffset + section->rawsize + offset;
     698        }
    655699    }
    656700    else {
    657         offset     = virtAddress - (section->realvirtaddr + section->virtualsize);
    658         fileoffset = section->rawoffset + section->rawsize + offset;
    659     }
    660   }
    661   else {
    662     protflags   = section->pageflags;
    663     offset      = virtAddress - section->realvirtaddr;
    664     sectionsize = section->virtualsize - offset;
    665 
    666     if(offset > section->rawsize || section->type == SECTION_UNINITDATA) {
    667         //unintialized data (set to 0)
    668         size = 0;
    669         fileoffset = -1;
     701        protflags   = section->pageflags;
     702        offset      = virtAddress - section->realvirtaddr;
     703        sectionsize = section->virtualsize - offset;
     704
     705        if(offset > section->rawsize || section->type == SECTION_UNINITDATA) {
     706            //unintialized data (set to 0)
     707            size = 0;
     708            fileoffset = -1;
     709        }
     710        else {
     711            size = section->rawsize-offset;
     712            fileoffset = section->rawoffset + offset;
     713        }
     714        if(fWriteAccess & !(section->pageflags & PAG_WRITE)) {
     715            dprintf((LOG, "Win32PeLdrImage::commitPage: No write access to 0%x!", virtAddress));
     716            return FALSE;
     717        }
     718    }
     719    //Check range of pages with the same attributes starting at virtAddress
     720    //(some pages might already have been loaded)
     721    range = sectionsize;
     722    rc = DosQueryMem((PVOID)virtAddress, &range, &attr);
     723    if(rc) {
     724        dprintf((LOG, "Win32PeLdrImage::commitPage: DosQueryMem for %x returned %d", virtAddress, rc));
     725        return FALSE;
     726    }
     727    if(attr & PAG_COMMIT) {
     728        dprintf((LOG, "Win32PeLdrImage::commitPage: Memory at 0x%x already committed!", virtAddress));
     729        return FALSE;
     730    }
     731
     732    if(fPageCmd == SINGLE_PAGE) {
     733        size = min(size, PAGE_SIZE);
     734        sectionsize = min(sectionsize, PAGE_SIZE);
     735    }
     736    else
     737    if(fPageCmd == SECTION_PAGES) {
     738        size = min(size, DEFAULT_NR_PAGES*PAGE_SIZE);
     739        sectionsize = min(sectionsize, DEFAULT_NR_PAGES*PAGE_SIZE);
     740    }
     741    //else complete section
     742
     743    size = min(size, range);
     744    sectionsize = min(sectionsize, range);
     745
     746    if(fileoffset != -1) {
     747        rc = DosEnterCritSec();
     748        if(rc) {
     749            dprintf((LOG, "DosEnterCritSec failed with rc %d", rc));
     750            goto fail;
     751        }
     752        rc = DosSetMem((PVOID)virtAddress, sectionsize, PAG_READ|PAG_WRITE|PAG_COMMIT);
     753        if(rc) {
     754            DosExitCritSec();
     755            dprintf((LOG, "Win32PeLdrImage::commitPage: DosSetMem failed (%d)!", rc));
     756            goto fail;
     757        }
     758
     759        if(DosSetFilePtr(hFile, fileoffset, FILE_BEGIN, &ulNewPos) == -1) {
     760            DosExitCritSec();
     761            dprintf((LOG, "Win32PeLdrImage::commitPage: DosSetFilePtr failed for 0x%x!", fileoffset));
     762            goto fail;
     763        }
     764        rc = DosRead(hFile, (PVOID)virtAddress, size, &ulRead);
     765        if(rc) {
     766            DosExitCritSec();
     767            dprintf((LOG, "Win32PeLdrImage::commitPage: DosRead failed for 0x%x %x %x %x (rc=%d)!", virtAddress, size, ulRead, fileoffset, rc));
     768            goto fail;
     769        }
     770        if(ulRead != size) {
     771            DosExitCritSec();
     772            dprintf((LOG, "Win32PeLdrImage::commitPage: DosRead failed to read %x (%x) bytes at %x for 0x%x!", size, ulRead, fileoffset, virtAddress));
     773            goto fail;
     774        }
     775        setFixups(virtAddress, sectionsize);
     776
     777        rc = DosSetMem((PVOID)virtAddress, sectionsize, protflags);
     778        DosExitCritSec();
     779        if(rc) {
     780            dprintf((LOG, "Win32PeLdrImage::commitPage: DosSetMem failed (%d)!", rc));
     781            goto fail;
     782        }
    670783    }
    671784    else {
    672         size = section->rawsize-offset;
    673         fileoffset = section->rawoffset + offset;
    674     }
    675     if(fWriteAccess & !(section->pageflags & PAG_WRITE)) {
    676         dprintf((LOG, "Win32PeLdrImage::commitPage: No write access to 0%x!", virtAddress));
    677         return FALSE;
    678     }
    679   }
    680   //Check range of pages with the same attributes starting at virtAddress
    681   //(some pages might already have been loaded)
    682   range = sectionsize;
    683   rc = DosQueryMem((PVOID)virtAddress, &range, &attr);
    684   if(rc) {
    685     dprintf((LOG, "Win32PeLdrImage::commitPage: DosQueryMem for %x returned %d", virtAddress, rc));
     785        rc = DosEnterCritSec();
     786        if(rc) {
     787            dprintf((LOG, "DosEnterCritSec failed with rc %d", rc));
     788            goto fail;
     789        }
     790
     791        rc = DosSetMem((PVOID)virtAddress, sectionsize, PAG_READ|PAG_WRITE|PAG_COMMIT);
     792        if(rc) {
     793            DosExitCritSec();
     794            dprintf((LOG, "Win32PeLdrImage::commitPage: DosSetMem failed (%d)!", rc));
     795            goto fail;
     796        }
     797        setFixups(virtAddress, sectionsize);
     798
     799        rc = DosSetMem((PVOID)virtAddress, sectionsize, protflags);
     800        DosExitCritSec();
     801        if(rc) {
     802            dprintf((LOG, "Win32PeLdrImage::commitPage: DosSetMem failed (%d)!", rc));
     803            goto fail;
     804        }
     805    }
     806    return TRUE;
     807
     808fail:
    686809    return FALSE;
    687   }
    688   if(attr & PAG_COMMIT) {
    689     dprintf((LOG, "Win32PeLdrImage::commitPage: Memory at 0x%x already committed!", virtAddress));
    690     return FALSE;
    691   }
    692 
    693   if(fPageCmd == SINGLE_PAGE) {
    694     size = min(size, PAGE_SIZE);
    695     sectionsize = min(sectionsize, PAGE_SIZE);
    696   }
    697   else
    698   if(fPageCmd == SECTION_PAGES) {
    699     size = min(size, DEFAULT_NR_PAGES*PAGE_SIZE);
    700     sectionsize = min(sectionsize, DEFAULT_NR_PAGES*PAGE_SIZE);
    701   }
    702   size = min(size, range);
    703   sectionsize = min(sectionsize, range);
    704 
    705   if(fileoffset != -1) {
    706     rc = DosSetMem((PVOID)virtAddress, sectionsize, PAG_READ|PAG_WRITE|PAG_COMMIT);
    707     if(rc) {
    708         dprintf((LOG, "Win32PeLdrImage::commitPage: DosSetMem failed (%d)!", rc));
    709             return FALSE;
    710     }
    711 
    712     if(DosSetFilePtr(hFile, fileoffset, FILE_BEGIN, &ulNewPos) == -1) {
    713         dprintf((LOG, "Win32PeLdrImage::commitPage: DosSetFilePtr failed for 0x%x!", fileoffset));
    714             return FALSE;
    715     }
    716     if(DosRead(hFile, (PVOID)virtAddress, size, &ulRead)) {
    717         dprintf((LOG, "Win32PeLdrImage::commitPage: DosRead failed for 0x%x!", virtAddress));
    718             return FALSE;
    719     }
    720     if(ulRead != size) {
    721         dprintf((LOG, "Win32PeLdrImage::commitPage: DosRead failed to read %x (%x) bytes at %x for 0x%x!", size, ulRead, fileoffset, virtAddress));
    722             return FALSE;
    723     }
    724     setFixups(virtAddress, sectionsize);
    725 
    726     rc = DosSetMem((PVOID)virtAddress, sectionsize, protflags);
    727     if(rc) {
    728         dprintf((LOG, "Win32PeLdrImage::commitPage: DosSetMem failed (%d)!", rc));
    729         return FALSE;
    730     }
    731   }
    732   else {
    733     rc = DosSetMem((PVOID)virtAddress, sectionsize, PAG_READ|PAG_WRITE|PAG_COMMIT);
    734     if(rc) {
    735         dprintf((LOG, "Win32PeLdrImage::commitPage: DosSetMem failed (%d)!", rc));
    736             return FALSE;
    737     }
    738     setFixups(virtAddress, sectionsize);
    739 
    740     rc = DosSetMem((PVOID)virtAddress, sectionsize, protflags);
    741     if(rc) {
    742         dprintf((LOG, "Win32PeLdrImage::commitPage: DosSetMem failed (%d)!", rc));
    743         return FALSE;
    744     }
    745   }
    746   return TRUE;
    747810}
    748811//******************************************************************************
     
    750813void Win32PeLdrImage::addSection(ULONG type, ULONG rawoffset, ULONG rawsize, ULONG virtaddress, ULONG virtsize, ULONG flags)
    751814{
    752   virtsize = max(rawsize, virtsize);
    753 
    754   section[nrsections].rawoffset      = rawoffset;
    755   section[nrsections].type           = type;
    756   section[nrsections].rawsize        = rawsize;
    757   section[nrsections].virtaddr       = virtaddress;
    758   section[nrsections].flags          = flags;
    759 
    760   virtsize   = ((virtsize - 1) & ~0xFFF) + PAGE_SIZE;
    761   imageSize += virtsize;
    762   section[nrsections].virtualsize = virtsize;
    763 
    764   if(virtaddress < imageVirtBase)
     815    virtsize = max(rawsize, virtsize);
     816
     817    section[nrsections].rawoffset      = rawoffset;
     818    section[nrsections].type           = type;
     819    section[nrsections].rawsize        = rawsize;
     820    section[nrsections].virtaddr       = virtaddress;
     821    section[nrsections].flags          = flags;
     822
     823    virtsize   = ((virtsize - 1) & ~0xFFF) + PAGE_SIZE;
     824    imageSize += virtsize;
     825    section[nrsections].virtualsize = virtsize;
     826
     827    if(virtaddress < imageVirtBase)
    765828        imageVirtBase = virtaddress;
    766   if(virtaddress + virtsize > imageVirtEnd)
     829    if(virtaddress + virtsize > imageVirtEnd)
    767830        imageVirtEnd  = virtaddress + virtsize;
    768831
    769   nrsections++;
     832    nrsections++;
    770833}
    771834//******************************************************************************
     
    776839 ULONG  baseAddress;
    777840
    778   realBaseAddress = 0;
    779 
    780   //Allocated in by pe.exe
    781   if(reservedMem && reservedMem == oh.ImageBase) {
    782     realBaseAddress = oh.ImageBase;
    783     return TRUE;
    784   }
    785 
    786   //SvL: We don't care where the image is loaded for resource lookup
    787   if(fh.Characteristics & IMAGE_FILE_RELOCS_STRIPPED && !(dwFlags & FLAG_PELDR_LOADASDATAFILE)) {
     841    realBaseAddress = 0;
     842
     843    //Allocated in by pe.exe
     844    if(reservedMem && reservedMem == oh.ImageBase) {
     845        realBaseAddress = oh.ImageBase;
     846        return TRUE;
     847    }
     848
     849    //SvL: We don't care where the image is loaded for resource lookup
     850    if(fh.Characteristics & IMAGE_FILE_RELOCS_STRIPPED && !(dwFlags & FLAG_PELDR_LOADASDATAFILE)) {
    788851        return allocFixedMem(reservedMem);
    789   }
    790   rc = DosAllocMem((PPVOID)&baseAddress, imageSize, PAG_READ | PAG_WRITE | flAllocMem);
    791   if(rc) {
    792     dprintf((LOG, "Win32PeLdrImage::allocSections, DosAllocMem returned %d", rc));
     852    }
     853    rc = DosAllocMem((PPVOID)&baseAddress, imageSize, PAG_READ | PAG_WRITE | flAllocMem);
     854    if(rc) {
     855        dprintf((LOG, "Win32PeLdrImage::allocSections, DosAllocMem returned %d", rc));
    793856        errorState = rc;
    794857        return(FALSE);
    795   }
    796   realBaseAddress = baseAddress;
    797   return(TRUE);
     858    }
     859    realBaseAddress = baseAddress;
     860    return(TRUE);
    798861}
    799862//******************************************************************************
     
    801864Section *Win32PeLdrImage::findSection(ULONG type)
    802865{
    803   for(int i=0;i<nrsections;i++) {
    804     if(section[i].type == type) {
    805         return &section[i];
    806     }
    807   }
    808   return NULL;
     866    for(int i=0;i<nrsections;i++) {
     867        if(section[i].type == type) {
     868            return &section[i];
     869        }
     870    }
     871    return NULL;
    809872}
    810873//******************************************************************************
     
    812875Section *Win32PeLdrImage::findSectionByAddr(ULONG addr)
    813876{
    814   for(int i=0;i<nrsections;i++) {
    815     if(section[i].virtaddr <= addr && section[i].virtaddr + section[i].virtualsize > addr) {
    816         return &section[i];
    817     }
    818   }
    819   return NULL;
     877    for(int i=0;i<nrsections;i++) {
     878        if(section[i].virtaddr <= addr && section[i].virtaddr + section[i].virtualsize > addr) {
     879            return &section[i];
     880        }
     881    }
     882    return NULL;
    820883}
    821884//******************************************************************************
     
    823886Section *Win32PeLdrImage::findSectionByOS2Addr(ULONG addr)
    824887{
    825   for(int i=0;i<nrsections;i++) {
    826     if(section[i].realvirtaddr <= addr && section[i].realvirtaddr + section[i].virtualsize > addr) {
    827         return &section[i];
    828     }
    829   }
    830   return NULL;
     888    for(int i=0;i<nrsections;i++) {
     889        if(section[i].realvirtaddr <= addr && section[i].realvirtaddr + section[i].virtualsize > addr) {
     890            return &section[i];
     891        }
     892    }
     893    return NULL;
    831894}
    832895//******************************************************************************
     
    837900 ULONG index = -1;
    838901
    839   for(int i=0;i<nrsections;i++) {
    840     if(section[i].realvirtaddr > addr) {
    841         if(section[i].realvirtaddr < lowestAddr) {
    842             lowestAddr = section[i].realvirtaddr;
    843             index = i;
    844         }
    845     }
    846   }
    847   if(index == -1)
    848     return NULL;
    849 
    850   return &section[index];
     902    for(int i=0;i<nrsections;i++) {
     903        if(section[i].realvirtaddr > addr) {
     904            if(section[i].realvirtaddr < lowestAddr) {
     905                lowestAddr = section[i].realvirtaddr;
     906                index = i;
     907            }
     908        }
     909    }
     910    if(index == -1)
     911        return NULL;
     912
     913    return &section[index];
    851914}
    852915//******************************************************************************
     
    864927 BOOL   allocFlags = flAllocMem;
    865928
    866   //Reserve enough space to store 4096 pointers to 1MB memory chunks
    867   memallocs = (ULONG *)malloc(4096*sizeof(ULONG *));
    868   if(memallocs == NULL) {
    869     dprintf((LOG, "allocFixedMem: MALLOC FAILED for memallocs" ));
    870     return FALSE;
    871   }
    872 
    873   if(oh.ImageBase < 512*1024*1024) {
    874     allocFlags = 0;
    875   }
    876   while(TRUE) {
     929    //Reserve enough space to store 4096 pointers to 1MB memory chunks
     930    memallocs = (ULONG *)malloc(4096*sizeof(ULONG *));
     931    if(memallocs == NULL) {
     932        dprintf((LOG, "allocFixedMem: MALLOC FAILED for memallocs" ));
     933        return FALSE;
     934    }
     935
     936    if(oh.ImageBase < 512*1024*1024) {
     937        allocFlags = 0;
     938    }
     939    while(TRUE) {
    877940        rc = DosAllocMem((PPVOID)&address, FALLOC_SIZE, PAG_READ | allocFlags);
    878941        if(rc) break;
     
    881944        if(address + FALLOC_SIZE >= oh.ImageBase) {
    882945            if(address > oh.ImageBase) {//we've passed it!
    883                     DosFreeMem((PVOID)address);
    884                     break;
     946                DosFreeMem((PVOID)address);
     947                break;
    885948            }
    886949            //found the right address
     
    889952            diff = oh.ImageBase - address;
    890953            if(diff) {
    891                     rc = DosAllocMem((PPVOID)&address, diff, PAG_READ | allocFlags);
    892                     if(rc) break;
     954                rc = DosAllocMem((PPVOID)&address, diff, PAG_READ | allocFlags);
     955                if(rc) break;
    893956            }
    894957            rc = DosAllocMem((PPVOID)&baseAddress, imageSize, PAG_READ | PAG_WRITE | allocFlags);
     
    900963            break;
    901964        }
    902     memallocs[alloccnt++] = address;
    903   }
    904   for(i=0;i<alloccnt;i++) {
     965        memallocs[alloccnt++] = address;
     966    }
     967    for(i=0;i<alloccnt;i++) {
    905968        DosFreeMem((PVOID)memallocs[i]);
    906   }
    907   free(memallocs);
    908 
    909   if(realBaseAddress == 0) //Let me guess.. MS Office app?
     969    }
     970    free(memallocs);
     971
     972    if(realBaseAddress == 0) //Let me guess.. MS Office app?
    910973        return(FALSE);
    911974
    912   return(TRUE);
     975    return(TRUE);
    913976}
    914977//******************************************************************************
     
    931994  for(i=0;i<nrsections;i++) {
    932995        switch(section[i].type)
    933     {
     996        {
    934997        case SECTION_CODE:
    935998        case (SECTION_CODE | SECTION_IMPORT):
    936                 section[i].pageflags = PAG_EXECUTE | PAG_READ;
    937         if(section[i].flags & IMAGE_SCN_MEM_WRITE)
    938             section[i].pageflags |= PAG_WRITE;
    939                 break;
     999            section[i].pageflags = PAG_EXECUTE | PAG_READ;
     1000            if(section[i].flags & IMAGE_SCN_MEM_WRITE)
     1001                section[i].pageflags |= PAG_WRITE;
     1002            break;
    9401003        case SECTION_INITDATA:
    9411004        case SECTION_UNINITDATA:
    9421005        case SECTION_IMPORT:
    943     case SECTION_TLS:
    944                 section[i].pageflags = PAG_WRITE | PAG_READ;
    945                 break;
     1006        case SECTION_TLS:
     1007            section[i].pageflags = PAG_WRITE | PAG_READ;
     1008            break;
    9461009
    9471010        case SECTION_RESOURCE:
    948         //TODO: GDI32 changes some bitmap structures to avoid problems in Open32
    949                 //      -> causes crashes if resource section is readonly
    950                 //      -> make it readonly again when gdi32 has been rewritten
    951                 section[i].pageflags = PAG_WRITE | PAG_READ;
    952         break;
     1011            //TODO: GDI32 changes some bitmap structures to avoid problems in Open32
     1012            //      -> causes crashes if resource section is readonly
     1013            //      -> make it readonly again when gdi32 has been rewritten
     1014            section[i].pageflags = PAG_WRITE | PAG_READ;
     1015            break;
    9531016
    9541017        case SECTION_READONLYDATA:
    9551018        case SECTION_EXPORT:
    9561019        default:
    957                 section[i].pageflags = PAG_READ;
    958                 break;
    959         }
    960     if(section[i].flags & (IMAGE_SCN_CNT_INITIALIZED_DATA|IMAGE_SCN_CNT_UNINITIALIZED_DATA)) {
    961         //SvL: sometimes i.e. import/export sections also contain data
    962                 //     must make them read/write
    963                 section[i].pageflags = PAG_WRITE;
    964         }
    965 
     1020            section[i].pageflags = PAG_READ;
     1021            break;
     1022        }
     1023        if(section[i].flags & (IMAGE_SCN_CNT_INITIALIZED_DATA|IMAGE_SCN_CNT_UNINITIALIZED_DATA)) {
     1024            //SvL: sometimes i.e. import/export sections also contain data
     1025            //     must make them read/write
     1026            section[i].pageflags = PAG_WRITE;
     1027        }
    9661028  }
    9671029  return(TRUE);
     
    9871049
    9881050  if(prel) {
    989     j = 1;
    990     while(((ULONG)prel < (ULONG)pFixups+dwFixupSize) &&
     1051        j = 1;
     1052        while(((ULONG)prel < (ULONG)pFixups+dwFixupSize) &&
    9911053              prel->VirtualAddress && prel->VirtualAddress < virtAddress)
    9921054        {
    9931055            prel = (PIMAGE_BASE_RELOCATION)((char*)prel + prel->SizeOfBlock);
    994     }
    995     while(((ULONG)prel < (ULONG)pFixups+dwFixupSize) &&
    996               prel->VirtualAddress && prel->VirtualAddress < virtAddress + size)
     1056        }
     1057        while(((ULONG)prel < (ULONG)pFixups+dwFixupSize) &&
     1058               prel->VirtualAddress && prel->VirtualAddress < virtAddress + size)
    9971059        {
    9981060            page = (char *)((char *)prel + (ULONG)prel->VirtualAddress);
     
    10021064                int type   = prel->TypeOffset[i] >> 12;
    10031065                int offset = prel->TypeOffset[i] & 0xFFF;
    1004             int fixupsize = 0;
     1066                int fixupsize = 0;
    10051067
    10061068                switch(type)
    1007             {
     1069                {
    10081070                case IMAGE_REL_BASED_HIGHLOW:
    1009                 fixupsize = 4;
    1010                 break;
    1011                     case IMAGE_REL_BASED_HIGH:
    1012                     case IMAGE_REL_BASED_LOW:
    1013                 fixupsize = 2;
    1014                 break;
    1015             }
    1016             //If the fixup crosses the final page boundary,
    1017             //then we have to load another page
    1018             if(prel->VirtualAddress + offset + fixupsize > virtAddress + size)
    1019             {
    1020                 newpage  = realBaseAddress + prel->VirtualAddress + offset + fixupsize;
    1021                 newpage &= ~0xFFF;
     1071                    fixupsize = 4;
     1072                    break;
     1073                case IMAGE_REL_BASED_HIGH:
     1074                case IMAGE_REL_BASED_LOW:
     1075                    fixupsize = 2;
     1076                    break;
     1077                }
     1078                //If the fixup crosses the final page boundary,
     1079                //then we have to load another page
     1080                if(prel->VirtualAddress + offset + fixupsize > virtAddress + size)
     1081                {
     1082                    newpage  = realBaseAddress + prel->VirtualAddress + offset + fixupsize;
     1083                    newpage &= ~0xFFF;
    10221084
    10231085                    section  = findSectionByOS2Addr(newpage);
    10241086                    if(section == NULL) {
    1025                     //should never happen
    1026                     dprintf((LOG, "::setFixups -> section == NULL!!"));
    1027                     return FALSE;
     1087                        //should never happen
     1088                        dprintf((LOG, "::setFixups -> section == NULL!!"));
     1089                        return FALSE;
    10281090                    }
    1029                 //SvL: Read page from disk
    1030                 commitPage(newpage, FALSE, SINGLE_PAGE);
    1031 
    1032                     //SvL: Enable write access
     1091                    //SvL: Read page from disk
     1092                    commitPage(newpage, FALSE, SINGLE_PAGE);
     1093
     1094                    //SvL: Enable write access (TODO: may need to prevent other threads from being active)
    10331095                    DosSetMem((PVOID)newpage, PAGE_SIZE, PAG_READ|PAG_WRITE);
    1034             }
     1096                }
    10351097
    10361098                switch(type)
    1037             {
     1099                {
    10381100                case IMAGE_REL_BASED_ABSOLUTE:
    10391101                    break;  //skip
    10401102                case IMAGE_REL_BASED_HIGHLOW:
    1041                         AddOff32Fixup(prel->VirtualAddress + offset);
    1042                         break;
    1043                     case IMAGE_REL_BASED_HIGH:
    1044                 AddOff16Fixup(prel->VirtualAddress + offset, TRUE);
    1045                 break;
    1046                     case IMAGE_REL_BASED_LOW:
    1047                 AddOff16Fixup(prel->VirtualAddress + offset, FALSE);
    1048                 break;
    1049                     case IMAGE_REL_BASED_HIGHADJ:
    1050                     case IMAGE_REL_BASED_MIPS_JMPADDR:
     1103                    AddOff32Fixup(prel->VirtualAddress + offset);
     1104                    break;
     1105                case IMAGE_REL_BASED_HIGH:
     1106                    AddOff16Fixup(prel->VirtualAddress + offset, TRUE);
     1107                    break;
     1108                case IMAGE_REL_BASED_LOW:
     1109                    AddOff16Fixup(prel->VirtualAddress + offset, FALSE);
     1110                    break;
     1111                case IMAGE_REL_BASED_HIGHADJ:
     1112                case IMAGE_REL_BASED_MIPS_JMPADDR:
    10511113                default:
    10521114                        break;
    10531115                }
    1054             if(prel->VirtualAddress + offset + fixupsize > virtAddress + size)
    1055             {
    1056                     //SvL: Restore original page protection flags
     1116                if(prel->VirtualAddress + offset + fixupsize > virtAddress + size)
     1117                {
     1118                    //SvL: Restore original page protection flags (TODO: may need to prevent other threads from being active)
    10571119                    DosSetMem((PVOID)newpage, PAGE_SIZE, section->pageflags);
    1058             }
     1120                }
    10591121            }
    10601122            prel = (PIMAGE_BASE_RELOCATION)((char*)prel + prel->SizeOfBlock);
     
    10621124  }
    10631125  else {
    1064     dprintf((LOG, "Win32PeLdrImage::setFixups, no fixups at %x, %d", virtAddress, size));
     1126        dprintf((LOG, "Win32PeLdrImage::setFixups, no fixups at %x, %d", virtAddress, size));
    10651127        return(FALSE);
    10661128  }
     
    10811143  if(prel) {
    10821144        j = 1;
    1083     while(prel->VirtualAddress) {
    1084       page = (char *)((char *)prel + (ULONG)prel->VirtualAddress);
    1085       count  = (prel->SizeOfBlock - 8)/2;
    1086       dprintf((LOG, "Page %d Address %x Count %d", j, prel->VirtualAddress, count ));
    1087       j++;
    1088       for(i=0;i<count;i++) {
    1089         int type   = prel->TypeOffset[i] >> 12;
    1090         int offset = prel->TypeOffset[i] & 0xFFF;
    1091         switch(type) {
    1092             case IMAGE_REL_BASED_ABSOLUTE:
     1145        while(prel->VirtualAddress) {
     1146            page = (char *)((char *)prel + (ULONG)prel->VirtualAddress);
     1147            count  = (prel->SizeOfBlock - 8)/2;
     1148            dprintf((LOG, "Page %d Address %x Count %d", j, prel->VirtualAddress, count ));
     1149            j++;
     1150            for(i=0;i<count;i++) {
     1151                int type   = prel->TypeOffset[i] >> 12;
     1152                int offset = prel->TypeOffset[i] & 0xFFF;
     1153                switch(type) {
     1154                case IMAGE_REL_BASED_ABSOLUTE:
    10931155////                dprintf((LOG, "absolute fixup; unused" ));
    1094                 break;  //skip
    1095             case IMAGE_REL_BASED_HIGHLOW:
     1156                    break;  //skip
     1157                case IMAGE_REL_BASED_HIGHLOW:
    10961158////                dprintf((LOG, "address ", offset << " type ", type ));
    1097                 AddOff32Fixup(prel->VirtualAddress + offset);
    1098                 break;
    1099             case IMAGE_REL_BASED_HIGH:
    1100         AddOff16Fixup(prel->VirtualAddress + offset, TRUE);
    1101         break;
    1102             case IMAGE_REL_BASED_LOW:
    1103         AddOff16Fixup(prel->VirtualAddress + offset, FALSE);
    1104         break;
    1105             case IMAGE_REL_BASED_HIGHADJ:
    1106             case IMAGE_REL_BASED_MIPS_JMPADDR:
    1107             default:
    1108                 dprintf((LOG, "Unknown/unsupported fixup type!" ));
    1109                 break;
    1110         }
    1111       }
    1112       prel = (PIMAGE_BASE_RELOCATION)((char*)prel + prel->SizeOfBlock);
    1113     }//while
     1159                    AddOff32Fixup(prel->VirtualAddress + offset);
     1160                    break;
     1161                case IMAGE_REL_BASED_HIGH:
     1162                    AddOff16Fixup(prel->VirtualAddress + offset, TRUE);
     1163                    break;
     1164                case IMAGE_REL_BASED_LOW:
     1165                    AddOff16Fixup(prel->VirtualAddress + offset, FALSE);
     1166                    break;
     1167                case IMAGE_REL_BASED_HIGHADJ:
     1168                case IMAGE_REL_BASED_MIPS_JMPADDR:
     1169                default:
     1170                    dprintf((LOG, "Unknown/unsupported fixup type!" ));
     1171                    break;
     1172                }
     1173            }
     1174            prel = (PIMAGE_BASE_RELOCATION)((char*)prel + prel->SizeOfBlock);
     1175        }//while
    11141176  }
    11151177  else {
    1116     dprintf((LOG, "No internal fixups found!" ));
    1117     errorState = ERROR_INTERNAL;
    1118     return(FALSE);
     1178        dprintf((LOG, "No internal fixups found!" ));
     1179        errorState = ERROR_INTERNAL;
     1180        return(FALSE);
    11191181  }
    11201182  return(TRUE);
Note: See TracChangeset for help on using the changeset viewer.