Changeset 3393 for trunk/src/kernel32/winimagepeldr.cpp
- Timestamp:
- Apr 15, 2000, 11:17:06 PM (25 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/kernel32/winimagepeldr.cpp
r3375 r3393 1 /* $Id: winimagepeldr.cpp,v 1. 39 2000-04-14 22:35:28 sandervlExp $ */1 /* $Id: winimagepeldr.cpp,v 1.40 2000-04-15 21:17:06 bird Exp $ */ 2 2 3 3 /* … … 77 77 char logname[CCHMAXPATH]; 78 78 79 80 81 82 83 84 85 79 sprintf(logname, "pe_%d.log", loadNr); 80 _privateLogFile = fopen(logname, "w"); 81 if(_privateLogFile == NULL) { 82 sprintf(logname, "%spe_%d.log", kernel32Path, loadNr); 83 _privateLogFile = fopen(logname, "w"); 84 } 85 dprintfGlobal(("PE LOGFILE : %s", logname)); 86 86 #endif 87 87 } … … 91 91 { 92 92 #ifdef DEBUG 93 94 95 96 93 if(_privateLogFile) { 94 fclose(_privateLogFile); 95 _privateLogFile = NULL; 96 } 97 97 #endif 98 98 } … … 113 113 strupr(szFileName); 114 114 if(isExe) { 115 116 117 118 119 120 121 122 123 124 125 126 127 128 elseOSLibDosClose(dllfile);115 if(!strchr(szFileName, '.')) { 116 strcat(szFileName,".EXE"); 117 } 118 dllfile = OSLibDosOpen(szFileName, OSLIB_ACCESS_READONLY|OSLIB_ACCESS_SHAREDENYNONE); 119 if(dllfile == NULL) { 120 if(!strstr(szFileName, ".EXE")) { 121 strcat(szFileName,".EXE"); 122 } 123 dllfile = OSLibDosOpen(szFileName, OSLIB_ACCESS_READONLY|OSLIB_ACCESS_SHAREDENYNONE); 124 if(dllfile == NULL) { 125 OSLibDosSearchPath(OSLIB_SEARCHENV, "PATH", szFileName, szFileName, sizeof(szFileName)); 126 } 127 } 128 else OSLibDosClose(dllfile); 129 129 } 130 130 else { 131 findDll(szFileName, szModule, sizeof(szModule));132 131 if (findDll(szFileName, szModule, sizeof(szModule))) 132 strcpy(szFileName, szModule); 133 133 } 134 134 strcpy(szModule, OSLibStripPath(szFileName)); … … 136 136 char *dot = strstr(szModule, "."); 137 137 while(dot) { 138 139 if(newdot == NULL)break;140 138 char *newdot = strstr(dot+1, "."); 139 if(newdot == NULL) break; 140 dot = newdot; 141 141 } 142 142 if(dot) 143 143 *dot = 0; 144 144 } 145 145 //****************************************************************************** … … 148 148 { 149 149 if(memmap) 150 150 delete memmap; 151 151 152 152 if(hFile) { 153 154 153 OSLibDosClose(hFile); 154 hFile = 0; 155 155 } 156 156 157 157 if(realBaseAddress) 158 158 DosFreeMem((PVOID)realBaseAddress); 159 159 160 160 if(nameexports) 161 161 free(nameexports); 162 162 163 163 if(ordexports) 164 164 free(ordexports); 165 165 } 166 166 //****************************************************************************** … … 183 183 strcpy(szErrorModule, OSLibStripPath(szFileName)); 184 184 if(hFile == NULL) { 185 185 goto failure; 186 186 } 187 187 //read dos header 188 188 if(DosRead(hFile, (LPVOID)&doshdr, sizeof(doshdr), &ulRead)) { 189 189 goto failure; 190 190 } 191 191 if(OSLibDosSetFilePtr(hFile, doshdr.e_lfanew, OSLIB_SETPTR_FILE_BEGIN) == -1) { 192 192 goto failure; 193 193 } 194 194 //read signature dword 195 195 if(DosRead(hFile, (LPVOID)&signature, sizeof(signature), &ulRead)) { 196 196 goto failure; 197 197 } 198 198 //read pe header 199 199 if(DosRead(hFile, (LPVOID)&fh, sizeof(fh), &ulRead)) { 200 200 goto failure; 201 201 } 202 202 //read optional header 203 203 if(DosRead(hFile, (LPVOID)&oh, sizeof(oh), &ulRead)) { 204 204 goto failure; 205 205 } 206 206 if(doshdr.e_magic != IMAGE_DOS_SIGNATURE || signature != IMAGE_NT_SIGNATURE) { 207 207 dprintf((LOG, "Not a valid PE file (probably a 16 bits windows exe/dll)!")); 208 208 WinMessageBox(HWND_DESKTOP, HWND_DESKTOP, szPEErrorMsg, szErrorTitle, 0, MB_OK | MB_ERROR | MB_MOVEABLE); 209 209 goto failure; 210 210 } 211 211 212 212 if(oh.SizeOfImage == 0) {//just in case 213 213 oh.SizeOfImage = OSLibDosGetFileSize(hFile); 214 214 } 215 215 … … 217 217 //Allocate memory to hold the entire image 218 218 if(allocSections(reservedMem) == FALSE) { 219 220 219 dprintf((LOG, "Failed to allocate image memory, rc %d", errorState));; 220 goto failure; 221 221 } 222 222 223 223 memmap = new Win32MemMap(this, realBaseAddress, imageSize); 224 224 if(memmap == NULL || !memmap->Init(0)) { 225 225 goto failure; 226 226 } 227 227 win32file = memmap->mapViewOfFile(0, 0, 2); 228 228 229 229 if(DosQueryPathInfo(szFileName, FIL_QUERYFULLNAME, szFullPath, sizeof(szFullPath)) == 0) { 230 230 setFullPath(szFullPath); 231 231 } 232 232 233 233 if(!(fh.Characteristics & IMAGE_FILE_EXECUTABLE_IMAGE)) {//not valid 234 234 dprintf((LOG, "Not a valid PE file!")); 235 235 WinMessageBox(HWND_DESKTOP, HWND_DESKTOP, szPEErrorMsg, szErrorTitle, 0, MB_OK | MB_ERROR | MB_MOVEABLE); 236 236 goto failure; 237 237 } 238 238 if(fh.Machine != IMAGE_FILE_MACHINE_I386) { 239 239 dprintf((LOG, "Doesn't run on x86 processors!")); 240 240 WinMessageBox(HWND_DESKTOP, HWND_DESKTOP, szCPUErrorMsg, szErrorTitle, 0, MB_OK | MB_ERROR | MB_MOVEABLE); 241 241 goto failure; 242 242 } 243 243 //IMAGE_FILE_SYSTEM == only drivers (device/file system/video etc)? 244 244 if(fh.Characteristics & IMAGE_FILE_SYSTEM) { 245 245 dprintf((LOG, "Can't convert system files")); 246 246 WinMessageBox(HWND_DESKTOP, HWND_DESKTOP, szExeErrorMsg, szErrorTitle, 0, MB_OK | MB_ERROR | MB_MOVEABLE); 247 247 goto failure; 248 248 } 249 249 250 250 if(fh.Characteristics & IMAGE_FILE_RELOCS_STRIPPED) { 251 251 dprintf((LOG, "No fixups, might not run!")); 252 252 } 253 253 … … 283 283 if ((psh = (PIMAGE_SECTION_HEADER)SECTIONHDROFF (win32file)) != NULL) { 284 284 dprintf((LOG, "*************************PE SECTIONS START**************************" )); 285 for (i=0; i<nSections; i++) { 285 for (i=0; i<nSections; i++) { 286 286 dprintf((LOG, "Raw data size: %x", psh[i].SizeOfRawData )); 287 287 dprintf((LOG, "Virtual Address: %x", psh[i].VirtualAddress )); … … 312 312 continue; 313 313 } 314 315 316 317 318 319 320 321 322 323 314 if(strcmp(psh[i].Name, ".tls") == 0) 315 { 316 tlsDir = (IMAGE_TLS_DIRECTORY *)ImageDirectoryOffset(win32file, IMAGE_DIRECTORY_ENTRY_TLS); 317 if(tlsDir) { 318 addSection(SECTION_TLS, psh[i].PointerToRawData, 319 psh[i].SizeOfRawData, psh[i].VirtualAddress + oh.ImageBase, 320 psh[i].Misc.VirtualSize, psh[i].Characteristics); 321 } 322 continue; 323 } 324 324 325 325 if(strcmp(psh[i].Name, ".debug") == 0) { … … 330 330 continue; 331 331 } 332 333 332 if(IsImportSection(win32file, &psh[i])) 333 { 334 334 int type = SECTION_IMPORT; 335 335 dprintf((LOG, "Import Data Section" )); … … 385 385 } 386 386 dprintf((LOG, "Unknown section" )); 387 387 goto failure; 388 388 } 389 389 } 390 390 } 391 391 else { 392 392 if(GetSectionHdrByName (win32file, &sh, ".rsrc")) 393 393 { 394 394 addSection(SECTION_RESOURCE, sh.PointerToRawData, 395 395 sh.SizeOfRawData, sh.VirtualAddress + oh.ImageBase, 396 396 sh.Misc.VirtualSize, sh.Characteristics); 397 397 } 398 398 } 399 399 dprintf((LOG, "*************************PE SECTIONS END **************************" )); … … 405 405 //In case there are any gaps between sections, adjust size 406 406 if(imageSize != imageVirtEnd - oh.ImageBase) { 407 408 407 dprintf((LOG, "imageSize != imageVirtEnd - oh.ImageBase!" )); 408 imageSize = imageVirtEnd - oh.ImageBase; 409 409 } 410 410 if(imageSize < oh.SizeOfImage) { 411 411 imageSize = oh.SizeOfImage; 412 412 } 413 413 414 414 dprintf((LOG, "OS/2 base address %x", realBaseAddress )); 415 415 if(oh.AddressOfEntryPoint) { 416 416 entryPoint = realBaseAddress + oh.AddressOfEntryPoint; 417 417 } 418 418 else { 419 420 419 dprintf((LOG, "EntryPoint == NULL" )); 420 entryPoint = NULL; 421 421 } 422 422 423 423 //set memory protection flags 424 424 if(setMemFlags() == FALSE) { 425 426 425 dprintf((LOG, "Failed to set memory protection" )); 426 goto failure; 427 427 } 428 428 … … 432 432 Section *sect = findSection(SECTION_TLS); 433 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 434 if(sect == NULL) { 435 dprintf((LOG, "Couldn't find TLS section!!" )); 436 goto failure; 437 } 438 dprintf((LOG, "TLS Directory" )); 439 dprintf((LOG, "TLS Address of Index %x", tlsDir->AddressOfIndex )); 440 dprintf((LOG, "TLS Address of Callbacks %x", tlsDir->AddressOfCallBacks )); 441 dprintf((LOG, "TLS SizeOfZeroFill %x", tlsDir->SizeOfZeroFill )); 442 dprintf((LOG, "TLS Characteristics %x", tlsDir->Characteristics )); 443 setTLSAddress((char *)sect->realvirtaddr); 444 setTLSInitSize(tlsDir->EndAddressOfRawData - tlsDir->StartAddressOfRawData); 445 setTLSTotalSize(tlsDir->EndAddressOfRawData - tlsDir->StartAddressOfRawData + tlsDir->SizeOfZeroFill); 446 447 sect = findSectionByAddr((ULONG)tlsDir->AddressOfIndex); 448 if(sect == NULL) { 449 dprintf((LOG, "Couldn't find TLS AddressOfIndex section!!" )); 450 goto failure; 451 } 452 setTLSIndexAddr((LPDWORD)(sect->realvirtaddr + ((ULONG)tlsDir->AddressOfIndex - sect->virtaddr))); 453 454 if((ULONG)tlsDir->AddressOfCallBacks != 0) { 455 sect = findSectionByAddr((ULONG)tlsDir->AddressOfCallBacks); 456 if(sect == NULL) { 457 dprintf((LOG, "Couldn't find TLS AddressOfCallBacks section!!" )); 458 goto failure; 459 } 460 setTLSCallBackAddr((PIMAGE_TLS_CALLBACK *)(sect->realvirtaddr + ((ULONG)tlsDir->AddressOfCallBacks - sect->virtaddr))); 461 } 462 462 } 463 463 464 464 if(realBaseAddress != oh.ImageBase) { 465 466 465 pFixups = (PIMAGE_BASE_RELOCATION)ImageDirectoryOffset(win32file, IMAGE_DIRECTORY_ENTRY_BASERELOC); 466 commitPage((ULONG)pFixups, FALSE); 467 467 } 468 468 #ifdef COMMIT_ALL 469 469 for (i=0; i<nSections; i++) { 470 470 commitPage((ULONG)section[i].realvirtaddr, FALSE, COMPLETE_SECTION); 471 471 } 472 472 #else 473 473 for (i=0; i<nSections; i++) { 474 475 476 477 478 479 480 481 474 switch(section[i].type) 475 { 476 case SECTION_IMPORT: 477 case SECTION_RELOC: 478 case SECTION_EXPORT: 479 commitPage((ULONG)section[i].realvirtaddr, FALSE, COMPLETE_SECTION); 480 break; 481 } 482 482 } 483 483 #endif 484 484 if(processExports((char *)win32file) == FALSE) { 485 486 485 dprintf((LOG, "Failed to process exported apis" )); 486 goto failure; 487 487 } 488 488 } 489 489 #ifdef COMMIT_ALL 490 490 else { 491 491 commitPage((ULONG)section[0].realvirtaddr, FALSE, COMPLETE_SECTION); 492 492 } 493 493 #endif … … 502 502 // implicitly call functions depending on it. 503 503 if(GetSectionHdrByName (win32file, &sh, ".rsrc")) { 504 505 504 //get offset in resource object of directory entry 505 pResDir = (PIMAGE_RESOURCE_DIRECTORY)(sh.VirtualAddress + realBaseAddress); 506 506 ulRVAResourceSection = sh.VirtualAddress; 507 507 } … … 510 510 { 511 511 if(processImports((char *)win32file) == FALSE) { 512 513 512 dprintf((LOG, "Failed to process imports!" )); 513 goto failure; 514 514 } 515 515 } … … 518 518 failure: 519 519 if(memmap) { 520 521 520 delete memmap; 521 memmap = NULL; 522 522 } 523 523 if(hFile) { 524 525 524 OSLibDosClose(hFile); 525 hFile = 0; 526 526 } 527 527 errorState = ERROR_INTERNAL; … … 541 541 //Round down to nearest page boundary 542 542 virtAddress = virtAddress & ~0xFFF; 543 543 544 544 section = findSectionByOS2Addr(virtAddress); 545 545 if(section == NULL) { 546 547 548 549 550 551 552 553 554 555 556 557 546 size = 4096; 547 sectionsize = 4096; 548 protflags = PAG_READ|PAG_WRITE; //readonly? 549 section = findPreviousSectionByOS2Addr(virtAddress); 550 if(section == NULL) {//access to header 551 offset = 0; 552 fileoffset = virtAddress - realBaseAddress; 553 } 554 else { 555 offset = virtAddress - (section->realvirtaddr + section->virtualsize); 556 fileoffset = section->rawoffset + section->rawsize + offset; 557 } 558 558 } 559 559 else { 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 560 protflags = section->pageflags; 561 offset = virtAddress - section->realvirtaddr; 562 sectionsize = section->virtualsize - offset; 563 564 if(offset > section->rawsize || section->type == SECTION_UNINITDATA) { 565 //unintialized data (set to 0) 566 size = 0; 567 fileoffset = -1; 568 } 569 else { 570 size = section->rawsize-offset; 571 fileoffset = section->rawoffset + offset; 572 } 573 if(fWriteAccess & !(section->pageflags & PAG_WRITE)) { 574 dprintf((LOG, "Win32PeLdrImage::commitPage: No write access to 0%x!", virtAddress)); 575 return FALSE; 576 } 577 577 } 578 578 //Check range of pages with the same attributes starting at virtAddress … … 581 581 rc = DosQueryMem((PVOID)virtAddress, &range, &attr); 582 582 if(rc) { 583 584 583 dprintf((LOG, "Win32PeLdrImage::commitPage: DosQueryMem for %x returned %d", virtAddress, rc)); 584 return FALSE; 585 585 } 586 586 if(attr & PAG_COMMIT) { 587 588 587 dprintf((LOG, "Win32PeLdrImage::commitPage: Memory at 0x%x already committed!", virtAddress)); 588 return FALSE; 589 589 } 590 590 591 591 if(fPageCmd == SINGLE_PAGE) { 592 593 592 size = min(size, PAGE_SIZE); 593 sectionsize = min(sectionsize, PAGE_SIZE); 594 594 } 595 595 else 596 596 if(fPageCmd == SECTION_PAGES) { 597 598 597 size = min(size, DEFAULT_NR_PAGES*PAGE_SIZE); 598 sectionsize = min(sectionsize, DEFAULT_NR_PAGES*PAGE_SIZE); 599 599 } 600 600 size = min(size, range); … … 602 602 603 603 if(fileoffset != -1) { 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 604 rc = DosSetMem((PVOID)virtAddress, sectionsize, PAG_READ|PAG_WRITE|PAG_COMMIT); 605 if(rc) { 606 dprintf((LOG, "Win32PeLdrImage::commitPage: DosSetMem failed (%d)!", rc)); 607 return FALSE; 608 } 609 610 if(DosSetFilePtr(hFile, fileoffset, FILE_BEGIN, &ulNewPos) == -1) { 611 dprintf((LOG, "Win32PeLdrImage::commitPage: DosSetFilePtr failed for 0x%x!", fileoffset)); 612 return FALSE; 613 } 614 if(DosRead(hFile, (PVOID)virtAddress, size, &ulRead)) { 615 dprintf((LOG, "Win32PeLdrImage::commitPage: DosRead failed for 0x%x!", virtAddress)); 616 return FALSE; 617 } 618 if(ulRead != size) { 619 dprintf((LOG, "Win32PeLdrImage::commitPage: DosRead failed to read %x (%x) bytes at %x for 0x%x!", size, ulRead, fileoffset, virtAddress)); 620 return FALSE; 621 } 622 if(realBaseAddress != oh.ImageBase) { 623 setFixups(virtAddress, sectionsize); 624 } 625 626 rc = DosSetMem((PVOID)virtAddress, sectionsize, protflags); 627 if(rc) { 628 dprintf((LOG, "Win32PeLdrImage::commitPage: DosSetMem failed (%d)!", rc)); 629 return FALSE; 630 } 631 631 } 632 632 else { 633 634 635 636 637 638 639 640 641 642 643 644 645 633 rc = DosSetMem((PVOID)virtAddress, sectionsize, PAG_READ|PAG_WRITE|PAG_COMMIT); 634 if(rc) { 635 dprintf((LOG, "Win32PeLdrImage::commitPage: DosSetMem failed (%d)!", rc)); 636 return FALSE; 637 } 638 if(realBaseAddress != oh.ImageBase) { 639 setFixups(virtAddress, sectionsize); 640 } 641 rc = DosSetMem((PVOID)virtAddress, sectionsize, protflags); 642 if(rc) { 643 dprintf((LOG, "Win32PeLdrImage::commitPage: DosSetMem failed (%d)!", rc)); 644 return FALSE; 645 } 646 646 } 647 647 return TRUE; … … 664 664 665 665 if(virtaddress < imageVirtBase) 666 666 imageVirtBase = virtaddress; 667 667 if(virtaddress + virtsize > imageVirtEnd) 668 668 imageVirtEnd = virtaddress + virtsize; 669 669 670 670 nrsections++; … … 679 679 //SvL: We don't care where the image is loaded for resource lookup 680 680 if(fh.Characteristics & IMAGE_FILE_RELOCS_STRIPPED && loadType == REAL_LOAD) { 681 681 return allocFixedMem(reservedMem); 682 682 } 683 683 rc = DosAllocMem((PPVOID)&baseAddress, imageSize, PAG_READ | PAG_WRITE | flAllocMem); 684 684 if(rc) { 685 686 687 685 dprintf((LOG, "Win32PeLdrImage::allocSections, DosAllocMem returned %d", rc)); 686 errorState = rc; 687 return(FALSE); 688 688 } 689 689 realBaseAddress = baseAddress; … … 695 695 { 696 696 for(int i=0;i<nrsections;i++) { 697 698 699 697 if(section[i].type == type) { 698 return §ion[i]; 699 } 700 700 } 701 701 return NULL; … … 706 706 { 707 707 for(int i=0;i<nrsections;i++) { 708 709 710 708 if(section[i].virtaddr <= addr && section[i].virtaddr + section[i].virtualsize > addr) { 709 return §ion[i]; 710 } 711 711 } 712 712 return NULL; … … 717 717 { 718 718 for(int i=0;i<nrsections;i++) { 719 720 721 719 if(section[i].realvirtaddr <= addr && section[i].realvirtaddr + section[i].virtualsize > addr) { 720 return §ion[i]; 721 } 722 722 } 723 723 return NULL; … … 731 731 732 732 for(int i=0;i<nrsections;i++) { 733 734 735 736 737 738 733 if(section[i].realvirtaddr > addr) { 734 if(section[i].realvirtaddr < lowestAddr) { 735 lowestAddr = section[i].realvirtaddr; 736 index = i; 737 } 738 } 739 739 } 740 740 if(index == -1) 741 741 return NULL; 742 742 743 743 return §ion[index]; … … 761 761 //Allocated in peldr.dll 762 762 if(reservedMem && reservedMem == oh.ImageBase) { 763 764 763 realBaseAddress = oh.ImageBase; 764 return TRUE; 765 765 } 766 766 … … 768 768 memallocs = (ULONG *)malloc(4096*sizeof(ULONG *)); 769 769 if(memallocs == NULL) { 770 771 770 dprintf((LOG, "allocFixedMem: MALLOC FAILED for memallocs" )); 771 return FALSE; 772 772 } 773 773 774 774 if(oh.ImageBase < 512*1024*1024) { 775 775 allocFlags = 0; 776 776 } 777 777 while(TRUE) { 778 779 780 781 782 783 784 785 786 787 788 789 790 791 792 793 794 795 796 797 798 799 800 801 802 803 778 rc = DosAllocMem((PPVOID)&address, FALLOC_SIZE, PAG_READ | allocFlags); 779 if(rc) break; 780 781 dprintf((LOG, "DosAllocMem returned %x", address )); 782 if(address + FALLOC_SIZE >= oh.ImageBase) { 783 if(address > oh.ImageBase) {//we've passed it! 784 DosFreeMem((PVOID)address); 785 break; 786 } 787 //found the right address 788 DosFreeMem((PVOID)address); 789 790 diff = oh.ImageBase - address; 791 if(diff) { 792 rc = DosAllocMem((PPVOID)&address, diff, PAG_READ | allocFlags); 793 if(rc) break; 794 } 795 rc = DosAllocMem((PPVOID)&baseAddress, imageSize, PAG_READ | PAG_WRITE | allocFlags); 796 if(rc) break; 797 798 if(diff) DosFreeMem((PVOID)address); 799 800 realBaseAddress = baseAddress; 801 break; 802 } 803 memallocs[alloccnt++] = address; 804 804 } 805 805 for(i=0;i<alloccnt;i++) { 806 806 DosFreeMem((PVOID)memallocs[i]); 807 807 } 808 808 free(memallocs); 809 809 810 810 if(realBaseAddress == 0) //Let me guess.. MS Office app? 811 811 return(FALSE); 812 812 813 813 return(TRUE); … … 827 827 // Process all the image sections 828 828 for(i=0;i<nrsections;i++) { 829 829 section[i].realvirtaddr = realBaseAddress + (section[i].virtaddr - oh.ImageBase); 830 830 } 831 831 832 832 for(i=0;i<nrsections;i++) { 833 834 833 switch(section[i].type) 834 { 835 835 case SECTION_CODE: 836 836 case (SECTION_CODE | SECTION_IMPORT): 837 838 if(section[i].flags & IMAGE_SCN_MEM_WRITE) 839 840 837 section[i].pageflags = PAG_EXECUTE | PAG_READ; 838 if(section[i].flags & IMAGE_SCN_MEM_WRITE) 839 section[i].pageflags |= PAG_WRITE; 840 break; 841 841 case SECTION_INITDATA: 842 842 case SECTION_UNINITDATA: 843 843 case SECTION_IMPORT: //TODO: read only? 844 845 844 section[i].pageflags = PAG_WRITE | PAG_READ; 845 break; 846 846 case SECTION_READONLYDATA: 847 847 case SECTION_RESOURCE: 848 848 case SECTION_TLS: 849 849 default: 850 851 852 850 section[i].pageflags = PAG_READ; 851 break; 852 } 853 853 } 854 854 return(TRUE); … … 865 865 866 866 if(fh.Characteristics & IMAGE_FILE_RELOCS_STRIPPED) { 867 867 return(TRUE); 868 868 } 869 869 … … 872 872 size = (size-1) & ~0xFFF; 873 873 size += PAGE_SIZE; 874 874 875 875 if(prel) { 876 877 878 879 880 881 882 883 884 885 886 887 888 889 890 891 892 893 894 895 896 897 898 899 900 901 902 903 904 905 906 907 908 909 910 911 912 913 914 915 916 917 918 919 920 921 922 923 924 925 926 927 928 929 930 931 932 933 934 935 936 937 938 939 940 941 942 943 944 876 j = 1; 877 while(prel->VirtualAddress && prel->VirtualAddress < virtAddress) { 878 prel = (PIMAGE_BASE_RELOCATION)((char*)prel + prel->SizeOfBlock); 879 } 880 while(prel->VirtualAddress && prel->VirtualAddress < virtAddress + size) { 881 page = (char *)((char *)prel + (ULONG)prel->VirtualAddress); 882 count = (prel->SizeOfBlock - 8)/2; 883 j++; 884 for(i=0;i<count;i++) { 885 int type = prel->TypeOffset[i] >> 12; 886 int offset = prel->TypeOffset[i] & 0xFFF; 887 int fixupsize = 0; 888 889 switch(type) 890 { 891 case IMAGE_REL_BASED_HIGHLOW: 892 fixupsize = 4; 893 break; 894 case IMAGE_REL_BASED_HIGH: 895 case IMAGE_REL_BASED_LOW: 896 fixupsize = 2; 897 break; 898 } 899 //If the fixup crosses the final page boundary, 900 //then we have to load another page 901 if(prel->VirtualAddress + offset + fixupsize > virtAddress + size) 902 { 903 newpage = realBaseAddress + prel->VirtualAddress + offset + fixupsize; 904 newpage &= ~0xFFF; 905 906 section = findSectionByOS2Addr(newpage); 907 if(section == NULL) { 908 //should never happen 909 dprintf((LOG, "::setFixups -> section == NULL!!")); 910 return FALSE; 911 } 912 //SvL: Read page from disk 913 commitPage(newpage, FALSE, SINGLE_PAGE); 914 915 //SvL: Enable write access 916 DosSetMem((PVOID)newpage, PAGE_SIZE, PAG_READ|PAG_WRITE); 917 } 918 919 switch(type) 920 { 921 case IMAGE_REL_BASED_ABSOLUTE: 922 break; //skip 923 case IMAGE_REL_BASED_HIGHLOW: 924 AddOff32Fixup(prel->VirtualAddress + offset); 925 break; 926 case IMAGE_REL_BASED_HIGH: 927 AddOff16Fixup(prel->VirtualAddress + offset, TRUE); 928 break; 929 case IMAGE_REL_BASED_LOW: 930 AddOff16Fixup(prel->VirtualAddress + offset, FALSE); 931 break; 932 case IMAGE_REL_BASED_HIGHADJ: 933 case IMAGE_REL_BASED_MIPS_JMPADDR: 934 default: 935 break; 936 } 937 if(prel->VirtualAddress + offset + fixupsize > virtAddress + size) 938 { 939 //SvL: Restore original page protection flags 940 DosSetMem((PVOID)newpage, PAGE_SIZE, section->pageflags); 941 } 942 } 943 prel = (PIMAGE_BASE_RELOCATION)((char*)prel + prel->SizeOfBlock); 944 }//while 945 945 } 946 946 else { 947 948 947 dprintf((LOG, "Win32PeLdrImage::setFixups, no fixups at %x, %d", virtAddress, size)); 948 return(FALSE); 949 949 } 950 950 return(TRUE); … … 959 959 960 960 if(fh.Characteristics & IMAGE_FILE_RELOCS_STRIPPED) { 961 961 return(TRUE); 962 962 } 963 963 … … 981 981 break; 982 982 case IMAGE_REL_BASED_HIGH: 983 984 983 AddOff16Fixup(prel->VirtualAddress + offset, TRUE); 984 break; 985 985 case IMAGE_REL_BASED_LOW: 986 987 986 AddOff16Fixup(prel->VirtualAddress + offset, FALSE); 987 break; 988 988 case IMAGE_REL_BASED_HIGHADJ: 989 989 case IMAGE_REL_BASED_MIPS_JMPADDR: … … 1025 1025 orgaddr = *fixup; 1026 1026 if(fHighFixup) { 1027 1027 *fixup += (USHORT)((realBaseAddress - oh.ImageBase) >> 16); 1028 1028 // dprintf((LOG, "AddOff16FixupH 0x%x org 0x%x -> new 0x%x", fixup, orgaddr, *fixup)); 1029 1029 } 1030 1030 else { 1031 1031 *fixup += (USHORT)((realBaseAddress - oh.ImageBase) & 0xFFFF); 1032 1032 // dprintf((LOG, "AddOff16FixupL 0x%x org 0x%x -> new 0x%x", fixup, orgaddr, *fixup)); 1033 1033 } … … 1044 1044 if(apiaddr == 0) 1045 1045 { 1046 1046 dprintf((LOG, "KERNEL32:Win32PeLdrImage - %s.%u not found\n", 1047 1047 WinDll->getName(), 1048 1048 ordinal)); 1049 1049 1050 1051 1050 dprintf((LOG, "--->>> NOT FOUND!" )); 1051 *import = (ULONG)MissingApi; 1052 1052 } 1053 1053 else *import = apiaddr; … … 1064 1064 if(apiaddr == 0) 1065 1065 { 1066 1066 dprintf((LOG, "KERNEL32:Win32PeLdrImage - %s.%s not found\n", 1067 1067 WinDll->getName(), 1068 1068 impname)); 1069 1069 1070 1071 1070 dprintf((LOG, "--->>> NOT FOUND!" )); 1071 *import = (ULONG)MissingApi; 1072 1072 } 1073 1073 else *import = apiaddr; … … 1149 1149 1150 1150 if(nameexports == NULL) { 1151 1152 1153 1151 nameExportSize= 4096; 1152 nameexports = (NameExport *)malloc(nameExportSize); 1153 curnameexport = nameexports; 1154 1154 } 1155 1155 nsize = (ULONG)curnameexport - (ULONG)nameexports; 1156 1156 if(nsize + sizeof(NameExport) + strlen(apiname) > nameExportSize) { 1157 1158 1159 1160 1161 1162 1157 nameExportSize += 4096; 1158 char *tmp = (char *)nameexports; 1159 nameexports = (NameExport *)malloc(nameExportSize); 1160 memcpy(nameexports, tmp, nsize); 1161 curnameexport = (NameExport *)((ULONG)nameexports + nsize); 1162 free(tmp); 1163 1163 } 1164 1164 curnameexport->virtaddr = realBaseAddress + (virtaddr - oh.ImageBase); … … 1169 1169 curnameexport->nlength = strlen(apiname) + 1; 1170 1170 if(curnameexport->nlength < sizeof(curnameexport->name)) 1171 1171 curnameexport->nlength = sizeof(curnameexport->name); 1172 1172 1173 1173 curnameexport = (NameExport *)((ULONG)curnameexport->name + curnameexport->nlength); … … 1178 1178 { 1179 1179 if(ordexports == NULL) { 1180 1181 1180 ordexports = (OrdExport *)malloc(nrOrdExports * sizeof(OrdExport)); 1181 curordexport = ordexports; 1182 1182 } 1183 1183 curordexport->virtaddr = realBaseAddress + (virtaddr - oh.ImageBase); … … 1329 1329 if(WinDll == NULL) 1330 1330 { //not found, so load it 1331 1332 1333 1334 1335 1336 1337 1338 1339 1340 1341 1342 1343 1344 1345 1346 1347 1348 1349 1350 1351 1352 1353 1354 1355 1356 1357 1358 1359 1360 1361 1362 1363 1364 1365 1366 1367 1368 1369 1370 1371 1372 1373 1374 1375 1376 1377 1378 1379 1380 1331 char modname[CCHMAXPATH]; 1332 1333 strcpy(modname, pszCurModule); 1334 //rename dll if necessary (i.e. OLE32 -> OLE32OS2) 1335 Win32DllBase::renameDll(modname); 1336 1337 if(isPEImage(modname) == FALSE) 1338 {//LX image, so let OS/2 do all the work for us 1339 APIRET rc; 1340 char szModuleFailure[CCHMAXPATH] = ""; 1341 ULONG hInstanceNewDll; 1342 1343 char *dot = strchr(modname, '.'); 1344 if(dot) { 1345 *dot = 0; 1346 } 1347 strcat(modname, ".DLL"); 1348 rc = DosLoadModule(szModuleFailure, sizeof(szModuleFailure), modname, (HMODULE *)&hInstanceNewDll); 1349 if(rc) { 1350 dprintf((LOG, "DosLoadModule returned %X for %s\n", rc, szModuleFailure)); 1351 sprintf(szErrorModule, "%s.DLL", szModuleFailure); 1352 errorState = rc; 1353 return(FALSE); 1354 } 1355 WinDll = (Win32PeLdrDll *)Win32DllBase::findModule(hInstanceNewDll); 1356 if(WinDll == NULL) {//shouldn't happen! 1357 dprintf((LOG, "Just loaded the dll, but can't find it anywhere?!!?")); 1358 errorState = ERROR_INTERNAL; 1359 return(FALSE); 1360 } 1361 //Mark this dll as loaded by DosLoadModule 1362 WinDll->setLoadLibrary(); 1363 WinDll->AddRef(); 1364 } 1365 else { 1366 WinDll = new Win32PeLdrDll(modname, this); 1367 1368 if(WinDll == NULL) { 1369 dprintf((LOG, "WinDll: Error allocating memory" )); 1370 WinMessageBox(HWND_DESKTOP, HWND_DESKTOP, szMemErrorMsg, szErrorTitle, 0, MB_OK | MB_ERROR | MB_MOVEABLE); 1371 errorState = ERROR_INTERNAL; 1372 return(FALSE); 1373 } 1374 dprintf((LOG, "**********************************************************************" )); 1375 dprintf((LOG, "********************** Loading Module *********************" )); 1376 dprintf((LOG, "**********************************************************************" )); 1377 if(WinDll->init(0) == FALSE) { 1378 dprintf((LOG, "Internal WinDll error ", WinDll->getError() )); 1379 return(FALSE); 1380 } 1381 1381 #ifdef DEBUG 1382 1382 WinDll->AddRef(getModuleName()); 1383 1383 #else 1384 1384 WinDll->AddRef(); 1385 1385 #endif 1386 1387 1388 1389 1390 1391 1392 1393 1394 1395 1386 if(WinDll->attachProcess() == FALSE) { 1387 dprintf((LOG, "attachProcess failed!" )); 1388 delete WinDll; 1389 errorState = ERROR_INTERNAL; 1390 return(FALSE); 1391 } 1392 } 1393 1394 dprintf((LOG, "**********************************************************************" )); 1395 dprintf((LOG, "********************** Finished Loading Module *********************" )); 1396 1396 dprintf((LOG, "**********************************************************************" )); 1397 1397 } 1398 1398 else { 1399 1400 1401 1402 1399 if(WinDll->isLxDll() && !WinDll->isLoaded()) { 1400 //can happen with i.e. wininet 1401 //wininet depends on wsock32; when the app loads wsock32 afterwards 1402 //with LoadLibrary or as a child of another dll, we need to make 1403 1403 //sure it's loaded once with DosLoadModule 1404 1405 1406 1407 1408 1404 WinDll->loadLibrary(); 1405 } 1406 WinDll->AddRef(); 1407 1408 dprintf((LOG, "Already found ", pszCurModule)); 1409 1409 } 1410 1410 //add the dll we just loaded to dependency list for this image … … 1422 1422 section = findSectionByOS2Addr(ulCurFixup); 1423 1423 if(section == NULL) { 1424 1425 1424 dprintf((LOG, "Unable to find section for %x", ulCurFixup )); 1425 return FALSE; 1426 1426 } 1427 1427 //SvL: Read page from disk … … 1452 1452 ulCurFixup += sizeof(IMAGE_THUNK_DATA); 1453 1453 j++; 1454 1455 1456 1457 1458 1454 if((ulCurFixup & 0xfff) == 0) { 1455 commitPage(ulCurFixup & ~0xfff, FALSE, SINGLE_PAGE); 1456 DosSetMem((PVOID)(ulCurFixup & ~0xfff), PAGE_SIZE, PAG_READ|PAG_WRITE); 1457 nrPages++; 1458 } 1459 1459 } 1460 1460 //SvL: And restore original protection flags … … 1485 1485 if(apilen < 4) 1486 1486 { 1487 1488 1489 1490 1491 } 1492 else 1487 *(ULONG *)tmp = 0; 1488 strcpy(tmp, name); 1489 apiname = tmp; 1490 apilen = 4; 1491 } 1492 else apiname = name; 1493 1493 1494 1494 curexport = nameexports; … … 1498 1498 *(ULONG *)curexport->name == *(ULONG *)apiname) 1499 1499 { 1500 1501 1500 if(strcmp(curexport->name, apiname) == 0) 1501 return(curexport->virtaddr); 1502 1502 } 1503 1503 curexport = (NameExport *)((ULONG)curexport->name + curexport->nlength); … … 1515 1515 curexport = ordexports; 1516 1516 for(i=0;i<nrOrdExports;i++) { 1517 1518 1519 1517 if(curexport->ordinal == ordinal) 1518 return(curexport->virtaddr); 1519 curexport++; 1520 1520 } 1521 1521 //Name exports also contain an ordinal, so check this 1522 1522 nexport = nameexports; 1523 1523 for(i=0;i<nrNameExports;i++) { 1524 1525 1526 1527 1524 if(nexport->ordinal == ordinal) 1525 return(nexport->virtaddr); 1526 1527 nexport = (NameExport *)((ULONG)nexport->name + nexport->nlength); 1528 1528 } 1529 1529 return(0); … … 1554 1554 1555 1555 if( r != MBID_IGNORE ) 1556 1556 ExitProcess(987); 1557 1557 1558 1558 fIgnore = TRUE;
Note:
See TracChangeset
for help on using the changeset viewer.