Changeset 4489 for trunk/src/kernel32/winimagepeldr.cpp
- Timestamp:
- Oct 16, 2000, 9:15:16 PM (25 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/kernel32/winimagepeldr.cpp
r4481 r4489 1 /* $Id: winimagepeldr.cpp,v 1.6 1 2000-10-11 07:22:28sandervl Exp $ */1 /* $Id: winimagepeldr.cpp,v 1.62 2000-10-16 19:15:16 sandervl Exp $ */ 2 2 3 3 /* … … 80 80 char logname[CCHMAXPATH]; 81 81 82 83 84 85 86 87 88 82 sprintf(logname, "pe_%d.log", loadNr); 83 _privateLogFile = fopen(logname, "w"); 84 if(_privateLogFile == NULL) { 85 sprintf(logname, "%spe_%d.log", kernel32Path, loadNr); 86 _privateLogFile = fopen(logname, "w"); 87 } 88 dprintfGlobal(("PE LOGFILE : %s", logname)); 89 89 #endif 90 90 } … … 94 94 { 95 95 #ifdef DEBUG 96 97 98 99 96 if(_privateLogFile) { 97 fclose(_privateLogFile); 98 _privateLogFile = NULL; 99 } 100 100 #endif 101 101 } … … 114 114 strupr(szFileName); 115 115 if(isExe) { 116 117 118 119 120 121 122 123 124 125 126 127 128 129 elseOSLibDosClose(dllfile);116 if(!strchr(szFileName, '.')) { 117 strcat(szFileName,".EXE"); 118 } 119 dllfile = OSLibDosOpen(szFileName, OSLIB_ACCESS_READONLY|OSLIB_ACCESS_SHAREDENYNONE); 120 if(dllfile == NULL) { 121 if(!strstr(szFileName, ".EXE")) { 122 strcat(szFileName,".EXE"); 123 } 124 dllfile = OSLibDosOpen(szFileName, OSLIB_ACCESS_READONLY|OSLIB_ACCESS_SHAREDENYNONE); 125 if(dllfile == NULL) { 126 OSLibDosSearchPath(OSLIB_SEARCHENV, "PATH", szFileName, szFileName, sizeof(szFileName)); 127 } 128 } 129 else OSLibDosClose(dllfile); 130 130 } 131 131 else { 132 133 132 findDll(szFileName, szModule, sizeof(szModule)); 133 strcpy(szFileName, szModule); 134 134 } 135 135 strcpy(szModule, OSLibStripPath(szFileName)); … … 137 137 char *dot = strstr(szModule, "."); 138 138 while(dot) { 139 140 if(newdot == NULL)break;141 139 char *newdot = strstr(dot+1, "."); 140 if(newdot == NULL) break; 141 dot = newdot; 142 142 } 143 143 if(dot) 144 144 *dot = 0; 145 145 } 146 146 //****************************************************************************** … … 149 149 { 150 150 if(memmap) 151 151 delete memmap; 152 152 153 153 if(hFile) { 154 155 154 OSLibDosClose(hFile); 155 hFile = 0; 156 156 } 157 157 158 158 if(realBaseAddress) 159 159 DosFreeMem((PVOID)realBaseAddress); 160 160 161 161 if(nameexports) 162 162 free(nameexports); 163 163 164 164 if(ordexports) 165 165 free(ordexports); 166 166 } 167 167 //****************************************************************************** … … 184 184 strcpy(szErrorModule, OSLibStripPath(szFileName)); 185 185 if(hFile == NULL) { 186 186 goto failure; 187 187 } 188 188 //read dos header 189 189 if(DosRead(hFile, (LPVOID)&doshdr, sizeof(doshdr), &ulRead)) { 190 190 goto failure; 191 191 } 192 192 if(OSLibDosSetFilePtr(hFile, doshdr.e_lfanew, OSLIB_SETPTR_FILE_BEGIN) == -1) { 193 193 goto failure; 194 194 } 195 195 //read signature dword 196 196 if(DosRead(hFile, (LPVOID)&signature, sizeof(signature), &ulRead)) { 197 197 goto failure; 198 198 } 199 199 //read pe header 200 200 if(DosRead(hFile, (LPVOID)&fh, sizeof(fh), &ulRead)) { 201 201 goto failure; 202 202 } 203 203 //read optional header 204 204 if(DosRead(hFile, (LPVOID)&oh, sizeof(oh), &ulRead)) { 205 205 goto failure; 206 206 } 207 207 if(doshdr.e_magic != IMAGE_DOS_SIGNATURE || signature != IMAGE_NT_SIGNATURE) { 208 208 dprintf((LOG, "Not a valid PE file (probably a 16 bits windows exe/dll)!")); 209 209 WinMessageBox(HWND_DESKTOP, HWND_DESKTOP, szPEErrorMsg, szErrorTitle, 0, MB_OK | MB_ERROR | MB_MOVEABLE); 210 210 goto failure; 211 211 } 212 212 213 213 if(oh.SizeOfImage == 0) {//just in case 214 214 oh.SizeOfImage = OSLibDosGetFileSize(hFile, NULL); 215 215 } 216 216 … … 218 218 //Allocate memory to hold the entire image 219 219 if(allocSections(reservedMem) == FALSE) { 220 221 220 dprintf((LOG, "Failed to allocate image memory for %s at %x, rc %d", szFileName, oh.ImageBase, errorState));; 221 goto failure; 222 222 } 223 223 224 224 memmap = new Win32MemMap(this, realBaseAddress, imageSize); 225 225 if(memmap == NULL || !memmap->Init(0)) { 226 226 goto failure; 227 227 } 228 228 win32file = memmap->mapViewOfFile(0, 0, 2); 229 229 230 230 if(DosQueryPathInfo(szFileName, FIL_QUERYFULLNAME, szFullPath, sizeof(szFullPath)) == 0) { 231 231 setFullPath(szFullPath); 232 232 } 233 233 234 234 if(!(fh.Characteristics & IMAGE_FILE_EXECUTABLE_IMAGE)) {//not valid 235 235 dprintf((LOG, "Not a valid PE file!")); 236 236 WinMessageBox(HWND_DESKTOP, HWND_DESKTOP, szPEErrorMsg, szErrorTitle, 0, MB_OK | MB_ERROR | MB_MOVEABLE); 237 237 goto failure; 238 238 } 239 239 if(fh.Machine != IMAGE_FILE_MACHINE_I386) { 240 240 dprintf((LOG, "Doesn't run on x86 processors!")); 241 241 WinMessageBox(HWND_DESKTOP, HWND_DESKTOP, szCPUErrorMsg, szErrorTitle, 0, MB_OK | MB_ERROR | MB_MOVEABLE); 242 242 goto failure; 243 243 } 244 244 //IMAGE_FILE_SYSTEM == only drivers (device/file system/video etc)? 245 245 if(fh.Characteristics & IMAGE_FILE_SYSTEM) { 246 246 dprintf((LOG, "Can't convert system files")); 247 247 WinMessageBox(HWND_DESKTOP, HWND_DESKTOP, szExeErrorMsg, szErrorTitle, 0, MB_OK | MB_ERROR | MB_MOVEABLE); 248 248 goto failure; 249 249 } 250 250 251 251 if(fh.Characteristics & IMAGE_FILE_RELOCS_STRIPPED) { 252 252 dprintf((LOG, "No fixups, might not run!")); 253 253 } 254 254 … … 281 281 if(!(dwFlags & FLAG_PELDR_LOADASDATAFILE)) 282 282 { 283 imageSize = 0; 284 if ((psh = (PIMAGE_SECTION_HEADER)SECTIONHDROFF (win32file)) != NULL) { 285 dprintf((LOG, "*************************PE SECTIONS START**************************" )); 286 for (i=0; i<nSections; i++) 287 { 288 dprintf((LOG, "Raw data size: %x", psh[i].SizeOfRawData )); 289 dprintf((LOG, "Virtual Address: %x", psh[i].VirtualAddress )); 290 dprintf((LOG, "Virtual Address Start:%x", psh[i].VirtualAddress+oh.ImageBase )); 291 dprintf((LOG, "Virtual Address End: %x", psh[i].VirtualAddress+oh.ImageBase+psh[i].Misc.VirtualSize )); 292 dprintf((LOG, "Virtual Size: %x", psh[i].Misc.VirtualSize )); 293 dprintf((LOG, "Pointer to raw data: %x", psh[i].PointerToRawData )); 294 dprintf((LOG, "Section flags: %x\n\n", psh[i].Characteristics )); 295 296 if(IsSectionType(win32file, &psh[i], IMAGE_DIRECTORY_ENTRY_BASERELOC)) 283 imageSize = 0; 284 if ((psh = (PIMAGE_SECTION_HEADER)SECTIONHDROFF (win32file)) != NULL) 285 { 286 dprintf((LOG, "*************************PE SECTIONS START**************************" )); 287 for (i=0; i<nSections; i++) 297 288 { 298 dprintf((LOG, ".reloc" )); 299 addSection(SECTION_RELOC, psh[i].PointerToRawData, 300 psh[i].SizeOfRawData, psh[i].VirtualAddress + oh.ImageBase, 301 psh[i].Misc.VirtualSize, psh[i].Characteristics); 302 continue; 303 } 304 if(IsSectionType(win32file, &psh[i], IMAGE_DIRECTORY_ENTRY_EXPORT)) 305 { 306 //SvL: Angus.exe has empty export section that's really an 307 // uninitialized data section 308 if(psh[i].SizeOfRawData) { 309 dprintf((LOG, ".edata" )); 310 addSection(SECTION_EXPORT, psh[i].PointerToRawData, 311 psh[i].SizeOfRawData, psh[i].VirtualAddress + oh.ImageBase, 312 psh[i].Misc.VirtualSize, psh[i].Characteristics); 313 continue; 314 } 315 } 316 if(IsSectionType(win32file, &psh[i], IMAGE_DIRECTORY_ENTRY_RESOURCE)) 317 { 318 dprintf((LOG, ".rsrc" )); 319 addSection(SECTION_RESOURCE, psh[i].PointerToRawData, 320 psh[i].SizeOfRawData, psh[i].VirtualAddress + oh.ImageBase, 321 psh[i].Misc.VirtualSize, psh[i].Characteristics); 322 continue; 323 } 324 if(IsSectionType(win32file, &psh[i], IMAGE_DIRECTORY_ENTRY_TLS)) 325 { 326 dprintf((LOG, "TLS section")); 327 tlsDir = (IMAGE_TLS_DIRECTORY *)ImageDirectoryOffset(win32file, IMAGE_DIRECTORY_ENTRY_TLS); 328 if(tlsDir) { 329 addSection(SECTION_TLS, psh[i].PointerToRawData, 330 psh[i].SizeOfRawData, psh[i].VirtualAddress + oh.ImageBase, 331 psh[i].Misc.VirtualSize, psh[i].Characteristics); 332 } 333 continue; 334 } 335 if(IsSectionType(win32file, &psh[i], IMAGE_DIRECTORY_ENTRY_DEBUG)) 336 { 337 dprintf((LOG, ".rdebug" )); 338 addSection(SECTION_DEBUG, psh[i].PointerToRawData, 339 psh[i].SizeOfRawData, psh[i].VirtualAddress + oh.ImageBase, 340 psh[i].Misc.VirtualSize, psh[i].Characteristics); 341 continue; 342 } 343 if(IsSectionType(win32file, &psh[i], IMAGE_DIRECTORY_ENTRY_IMPORT)) 344 { 345 int type = SECTION_IMPORT; 346 347 dprintf((LOG, "Import Data Section" )); 348 if(psh[i].Characteristics & IMAGE_SCN_CNT_CODE) { 349 dprintf((LOG, "Also Code Section")); 350 type |= SECTION_CODE; 351 } 352 addSection(type, psh[i].PointerToRawData, 353 psh[i].SizeOfRawData, psh[i].VirtualAddress + oh.ImageBase, 354 psh[i].Misc.VirtualSize, psh[i].Characteristics); 355 continue; 356 } 357 358 //KSO Sun 1998-08-09: Borland does not alway set the CODE flag for its "CODE" section 359 if(psh[i].Characteristics & IMAGE_SCN_CNT_CODE || 360 (psh[i].Characteristics & IMAGE_SCN_MEM_EXECUTE && 361 !(psh[i].Characteristics & (IMAGE_SCN_CNT_UNINITIALIZED_DATA | IMAGE_SCN_CNT_INITIALIZED_DATA))) //KSO: make sure its not marked as a datasection 362 ) 363 { 364 dprintf((LOG, "Code Section")); 365 addSection(SECTION_CODE, 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_MEM_WRITE)) { //read only data section 371 dprintf((LOG, "Read Only Data Section" )); 372 addSection(SECTION_READONLYDATA, 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_UNINITIALIZED_DATA) { 378 dprintf((LOG, "Uninitialized Data Section" )); 379 addSection(SECTION_UNINITDATA, 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_CNT_INITIALIZED_DATA) { 385 dprintf((LOG, "Initialized Data Section" )); 386 addSection(SECTION_INITDATA, psh[i].PointerToRawData, 387 psh[i].SizeOfRawData, psh[i].VirtualAddress + oh.ImageBase, 388 psh[i].Misc.VirtualSize, psh[i].Characteristics); 389 continue; 390 } 391 if(psh[i].Characteristics & (IMAGE_SCN_MEM_WRITE | IMAGE_SCN_MEM_READ)) { 392 dprintf((LOG, "Other Section, stored as read/write uninit data" )); 393 addSection(SECTION_UNINITDATA, psh[i].PointerToRawData, 394 psh[i].SizeOfRawData, psh[i].VirtualAddress + oh.ImageBase, 395 psh[i].Misc.VirtualSize, psh[i].Characteristics); 396 continue; 397 } 398 dprintf((LOG, "Unknown section" )); 399 goto failure; 400 } 401 } 289 dprintf((LOG, "Raw data size: %x", psh[i].SizeOfRawData )); 290 dprintf((LOG, "Virtual Address: %x", psh[i].VirtualAddress )); 291 dprintf((LOG, "Virtual Address Start:%x", psh[i].VirtualAddress+oh.ImageBase )); 292 dprintf((LOG, "Virtual Address End: %x", psh[i].VirtualAddress+oh.ImageBase+psh[i].Misc.VirtualSize )); 293 dprintf((LOG, "Virtual Size: %x", psh[i].Misc.VirtualSize )); 294 dprintf((LOG, "Pointer to raw data: %x", psh[i].PointerToRawData )); 295 dprintf((LOG, "Section flags: %x\n\n", psh[i].Characteristics )); 296 297 if(IsSectionType(win32file, &psh[i], IMAGE_DIRECTORY_ENTRY_BASERELOC)) 298 { 299 dprintf((LOG, ".reloc" )); 300 addSection(SECTION_RELOC, psh[i].PointerToRawData, 301 psh[i].SizeOfRawData, psh[i].VirtualAddress + oh.ImageBase, 302 psh[i].Misc.VirtualSize, psh[i].Characteristics); 303 continue; 304 } 305 if(IsSectionType(win32file, &psh[i], IMAGE_DIRECTORY_ENTRY_EXPORT)) 306 { 307 //SvL: Angus.exe has empty export section that's really an 308 // uninitialized data section 309 if(psh[i].SizeOfRawData) { 310 dprintf((LOG, ".edata" )); 311 addSection(SECTION_EXPORT, psh[i].PointerToRawData, 312 psh[i].SizeOfRawData, psh[i].VirtualAddress + oh.ImageBase, 313 psh[i].Misc.VirtualSize, psh[i].Characteristics); 314 continue; 315 } 316 } 317 if(IsSectionType(win32file, &psh[i], IMAGE_DIRECTORY_ENTRY_RESOURCE)) 318 { 319 dprintf((LOG, ".rsrc" )); 320 addSection(SECTION_RESOURCE, psh[i].PointerToRawData, 321 psh[i].SizeOfRawData, psh[i].VirtualAddress + oh.ImageBase, 322 psh[i].Misc.VirtualSize, psh[i].Characteristics); 323 continue; 324 } 325 if(IsSectionType(win32file, &psh[i], IMAGE_DIRECTORY_ENTRY_TLS)) 326 { 327 dprintf((LOG, "TLS section")); 328 tlsDir = (IMAGE_TLS_DIRECTORY *)ImageDirectoryOffset(win32file, IMAGE_DIRECTORY_ENTRY_TLS); 329 if(tlsDir) { 330 addSection(SECTION_TLS, psh[i].PointerToRawData, 331 psh[i].SizeOfRawData, psh[i].VirtualAddress + oh.ImageBase, 332 psh[i].Misc.VirtualSize, psh[i].Characteristics); 333 } 334 continue; 335 } 336 if(IsSectionType(win32file, &psh[i], IMAGE_DIRECTORY_ENTRY_DEBUG)) 337 { 338 dprintf((LOG, ".rdebug" )); 339 addSection(SECTION_DEBUG, psh[i].PointerToRawData, 340 psh[i].SizeOfRawData, psh[i].VirtualAddress + oh.ImageBase, 341 psh[i].Misc.VirtualSize, psh[i].Characteristics); 342 continue; 343 } 344 if(IsSectionType(win32file, &psh[i], IMAGE_DIRECTORY_ENTRY_IMPORT)) 345 { 346 int type = SECTION_IMPORT; 347 348 dprintf((LOG, "Import Data Section" )); 349 if(psh[i].Characteristics & IMAGE_SCN_CNT_CODE) { 350 dprintf((LOG, "Also Code Section")); 351 type |= SECTION_CODE; 352 } 353 addSection(type, psh[i].PointerToRawData, 354 psh[i].SizeOfRawData, psh[i].VirtualAddress + oh.ImageBase, 355 psh[i].Misc.VirtualSize, psh[i].Characteristics); 356 continue; 357 } 358 359 //KSO Sun 1998-08-09: Borland does not alway set the CODE flag for its "CODE" section 360 if(psh[i].Characteristics & IMAGE_SCN_CNT_CODE || 361 (psh[i].Characteristics & IMAGE_SCN_MEM_EXECUTE && 362 !(psh[i].Characteristics & (IMAGE_SCN_CNT_UNINITIALIZED_DATA | IMAGE_SCN_CNT_INITIALIZED_DATA))) //KSO: make sure its not marked as a datasection 363 ) 364 { 365 dprintf((LOG, "Code Section")); 366 addSection(SECTION_CODE, psh[i].PointerToRawData, 367 psh[i].SizeOfRawData, psh[i].VirtualAddress + oh.ImageBase, 368 psh[i].Misc.VirtualSize, psh[i].Characteristics); 369 continue; 370 } 371 if(!(psh[i].Characteristics & IMAGE_SCN_MEM_WRITE)) { //read only data section 372 dprintf((LOG, "Read Only Data Section" )); 373 addSection(SECTION_READONLYDATA, psh[i].PointerToRawData, 374 psh[i].SizeOfRawData, psh[i].VirtualAddress + oh.ImageBase, 375 psh[i].Misc.VirtualSize, psh[i].Characteristics); 376 continue; 377 } 378 if(psh[i].Characteristics & IMAGE_SCN_CNT_UNINITIALIZED_DATA) { 379 dprintf((LOG, "Uninitialized Data Section" )); 380 addSection(SECTION_UNINITDATA, psh[i].PointerToRawData, 381 psh[i].SizeOfRawData, psh[i].VirtualAddress + oh.ImageBase, 382 psh[i].Misc.VirtualSize, psh[i].Characteristics); 383 continue; 384 } 385 if(psh[i].Characteristics & IMAGE_SCN_CNT_INITIALIZED_DATA) { 386 dprintf((LOG, "Initialized Data Section" )); 387 addSection(SECTION_INITDATA, psh[i].PointerToRawData, 388 psh[i].SizeOfRawData, psh[i].VirtualAddress + oh.ImageBase, 389 psh[i].Misc.VirtualSize, psh[i].Characteristics); 390 continue; 391 } 392 if(psh[i].Characteristics & (IMAGE_SCN_MEM_WRITE | IMAGE_SCN_MEM_READ)) { 393 dprintf((LOG, "Other Section, stored as read/write uninit data" )); 394 addSection(SECTION_UNINITDATA, psh[i].PointerToRawData, 395 psh[i].SizeOfRawData, psh[i].VirtualAddress + oh.ImageBase, 396 psh[i].Misc.VirtualSize, psh[i].Characteristics); 397 continue; 398 } 399 dprintf((LOG, "Unknown section" )); 400 goto failure; 401 } 402 } 402 403 } 403 404 else { 404 405 if(GetSectionHdrByImageDir(win32file, IMAGE_DIRECTORY_ENTRY_RESOURCE, &sh)) 405 406 { 406 407 addSection(SECTION_RESOURCE, sh.PointerToRawData, 407 408 sh.SizeOfRawData, sh.VirtualAddress + oh.ImageBase, 408 409 sh.Misc.VirtualSize, sh.Characteristics); 409 410 } 410 411 } 411 412 dprintf((LOG, "*************************PE SECTIONS END **************************" )); … … 417 418 418 419 //In case there are any gaps between sections, adjust size 419 if(imageSize != imageVirtEnd - oh.ImageBase) { 420 dprintf((LOG, "imageSize != imageVirtEnd - oh.ImageBase!" )); 421 imageSize = imageVirtEnd - oh.ImageBase; 420 if(imageSize != imageVirtEnd - oh.ImageBase) 421 { 422 dprintf((LOG, "imageSize != imageVirtEnd - oh.ImageBase!" )); 423 imageSize = imageVirtEnd - oh.ImageBase; 422 424 } 423 425 if(imageSize < oh.SizeOfImage) { 424 426 imageSize = oh.SizeOfImage; 425 427 } 426 428 427 429 dprintf((LOG, "OS/2 base address %x", realBaseAddress )); 428 430 if(oh.AddressOfEntryPoint) { 429 431 entryPoint = realBaseAddress + oh.AddressOfEntryPoint; 430 432 } 431 433 else { 432 433 434 dprintf((LOG, "EntryPoint == NULL" )); 435 entryPoint = NULL; 434 436 } 435 437 436 438 //set memory protection flags 437 439 if(setMemFlags() == FALSE) { 438 dprintf((LOG, "Failed to set memory protection" )); 439 goto failure; 440 dprintf((LOG, "Failed to set memory protection" )); 441 goto failure; 442 } 443 444 if(realBaseAddress != oh.ImageBase) { 445 pFixups = (PIMAGE_BASE_RELOCATION)ImageDirectoryOffset(win32file, IMAGE_DIRECTORY_ENTRY_BASERELOC); 446 dwFixupSize = ImageDirectorySize(win32file, IMAGE_DIRECTORY_ENTRY_BASERELOC); 447 commitPage((ULONG)pFixups, FALSE); 440 448 } 441 449 442 450 if(!(dwFlags & FLAG_PELDR_LOADASDATAFILE)) 443 451 { 444 if(tlsDir = (IMAGE_TLS_DIRECTORY *)ImageDirectoryOffset(win32file, IMAGE_DIRECTORY_ENTRY_TLS)) 445 { 446 Section *sect = findSectionByAddr(tlsDir->StartAddressOfRawData); 447 448 dprintf((LOG, "TLS Directory" )); 449 dprintf((LOG, "TLS Address of Index %x", tlsDir->AddressOfIndex )); 450 dprintf((LOG, "TLS Address of Callbacks %x", tlsDir->AddressOfCallBacks )); 451 dprintf((LOG, "TLS SizeOfZeroFill %x", tlsDir->SizeOfZeroFill )); 452 dprintf((LOG, "TLS Characteristics %x", tlsDir->Characteristics )); 453 if(sect == NULL) { 454 dprintf((LOG, "Couldn't find TLS section!!" )); 455 goto failure; 456 } 457 setTLSAddress((char *)sect->realvirtaddr); 458 setTLSInitSize(tlsDir->EndAddressOfRawData - tlsDir->StartAddressOfRawData); 459 setTLSTotalSize(tlsDir->EndAddressOfRawData - tlsDir->StartAddressOfRawData + tlsDir->SizeOfZeroFill); 460 461 sect = findSectionByAddr((ULONG)tlsDir->AddressOfIndex); 462 if(sect == NULL) { 463 dprintf((LOG, "Couldn't find TLS AddressOfIndex section!!" )); 464 goto failure; 465 } 466 setTLSIndexAddr((LPDWORD)(sect->realvirtaddr + ((ULONG)tlsDir->AddressOfIndex - sect->virtaddr))); 467 468 if((ULONG)tlsDir->AddressOfCallBacks != 0) { 469 sect = findSectionByAddr((ULONG)tlsDir->AddressOfCallBacks); 470 if(sect == NULL) { 471 dprintf((LOG, "Couldn't find TLS AddressOfCallBacks section!!" )); 472 goto failure; 473 } 474 setTLSCallBackAddr((PIMAGE_TLS_CALLBACK *)(sect->realvirtaddr + ((ULONG)tlsDir->AddressOfCallBacks - sect->virtaddr))); 475 //modify tls callback pointers for new image base address 476 int i = 0; 477 while(tlsCallBackAddr[i]) { 478 tlsCallBackAddr[i] = (PIMAGE_TLS_CALLBACK)(realBaseAddress + ((ULONG)*tlsCallBackAddr - oh.ImageBase)); 479 i++; 452 if(tlsDir = (IMAGE_TLS_DIRECTORY *)ImageDirectoryOffset(win32file, IMAGE_DIRECTORY_ENTRY_TLS)) 453 { 454 Section *sect; 455 BOOL fTLSFixups = FALSE; 456 457 sect = findSectionByAddr(tlsDir->StartAddressOfRawData); 458 //There might be fixups for the TLS structure, so search the sections 459 //by the OS/2 virtual address too 460 if(sect == NULL) { 461 sect = findSectionByOS2Addr(tlsDir->StartAddressOfRawData); 462 fTLSFixups = TRUE; 463 } 464 465 dprintf((LOG, "TLS Directory" )); 466 dprintf((LOG, "TLS Address of Index %x", tlsDir->AddressOfIndex )); 467 dprintf((LOG, "TLS Address of Callbacks %x", tlsDir->AddressOfCallBacks )); 468 dprintf((LOG, "TLS SizeOfZeroFill %x", tlsDir->SizeOfZeroFill )); 469 dprintf((LOG, "TLS Characteristics %x", tlsDir->Characteristics )); 470 if(sect == NULL) { 471 dprintf((LOG, "Couldn't find TLS section!!" )); 472 goto failure; 473 } 474 setTLSAddress((char *)sect->realvirtaddr); 475 setTLSInitSize(tlsDir->EndAddressOfRawData - tlsDir->StartAddressOfRawData); 476 setTLSTotalSize(tlsDir->EndAddressOfRawData - tlsDir->StartAddressOfRawData + tlsDir->SizeOfZeroFill); 477 478 fTLSFixups = FALSE; 479 sect = findSectionByAddr((ULONG)tlsDir->AddressOfIndex); 480 //There might be fixups for the TLS structure, so search the sections 481 //by the OS/2 virtual address too 482 if(sect == NULL) { 483 sect = findSectionByOS2Addr((ULONG)tlsDir->AddressOfIndex); 484 fTLSFixups = TRUE; 485 } 486 if(sect == NULL) { 487 dprintf((LOG, "Couldn't find TLS AddressOfIndex section!!" )); 488 goto failure; 489 } 490 if(fTLSFixups) { 491 setTLSIndexAddr((LPDWORD)tlsDir->AddressOfIndex); //no fixup required 492 } 493 else {//need to add a manual fixup 494 setTLSIndexAddr((LPDWORD)(sect->realvirtaddr + ((ULONG)tlsDir->AddressOfIndex - sect->virtaddr))); 495 } 496 497 if((ULONG)tlsDir->AddressOfCallBacks != 0) 498 { 499 fTLSFixups = FALSE; 500 501 sect = findSectionByAddr((ULONG)tlsDir->AddressOfCallBacks); 502 //There might be fixups for the TLS structure, so search the sections 503 //by the OS/2 virtual address too 504 if(sect == NULL) { 505 sect = findSectionByOS2Addr((ULONG)tlsDir->AddressOfIndex); 506 fTLSFixups = TRUE; 507 } 508 if(sect == NULL) { 509 dprintf((LOG, "Couldn't find TLS AddressOfCallBacks section!!" )); 510 goto failure; 511 } 512 if(fTLSFixups) { 513 setTLSCallBackAddr((PIMAGE_TLS_CALLBACK *)tlsDir->AddressOfCallBacks); //no fixup required 514 } 515 else {//need to add a manual fixup 516 setTLSCallBackAddr((PIMAGE_TLS_CALLBACK *)(sect->realvirtaddr + ((ULONG)tlsDir->AddressOfCallBacks - sect->virtaddr))); 517 } 518 //modify tls callback pointers for new image base address 519 int i = 0; 520 while(tlsCallBackAddr[i]) 521 { 522 fTLSFixups = FALSE; 523 524 sect = findSectionByAddr((ULONG)tlsCallBackAddr[i]); 525 //There might be fixups for the TLS structure, so search the sections 526 //by the OS/2 virtual address too 527 if(sect == NULL) { 528 sect = findSectionByOS2Addr((ULONG)tlsCallBackAddr[i]); 529 fTLSFixups = TRUE; 480 530 } 481 } 531 if(sect == NULL) { 532 dprintf((LOG, "Couldn't find TLS callback section!!" )); 533 goto failure; 534 } 535 if(fTLSFixups) { 536 tlsCallBackAddr[i] = tlsCallBackAddr[i]; 537 } 538 else tlsCallBackAddr[i] = (PIMAGE_TLS_CALLBACK)(realBaseAddress + ((ULONG)tlsCallBackAddr[i] - oh.ImageBase)); 539 i++; 540 } 541 } 482 542 } 483 543 … … 488 548 char *pszName; 489 549 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 }514 dprintf((LOG, "\n\n"));550 if(oh.DataDirectory[i].VirtualAddress && oh.DataDirectory[i].Size) { 551 switch (i) 552 { 553 case IMAGE_DIRECTORY_ENTRY_EXPORT: pszName = "Export Directory (IMAGE_DIRECTORY_ENTRY_EXPORT)"; break; 554 case IMAGE_DIRECTORY_ENTRY_IMPORT: pszName = "Import Directory (IMAGE_DIRECTORY_ENTRY_IMPORT)"; break; 555 case IMAGE_DIRECTORY_ENTRY_RESOURCE: pszName = "Resource Directory (IMAGE_DIRECTORY_ENTRY_RESOURCE)"; break; 556 case IMAGE_DIRECTORY_ENTRY_EXCEPTION: pszName = "Exception Directory (IMAGE_DIRECTORY_ENTRY_EXCEPTION)"; break; 557 case IMAGE_DIRECTORY_ENTRY_SECURITY: pszName = "Security Directory (IMAGE_DIRECTORY_ENTRY_SECURITY)"; break; 558 case IMAGE_DIRECTORY_ENTRY_BASERELOC: pszName = "Base Relocation Table (IMAGE_DIRECTORY_ENTRY_BASERELOC)"; break; 559 case IMAGE_DIRECTORY_ENTRY_DEBUG: pszName = "Debug Directory (IMAGE_DIRECTORY_ENTRY_DEBUG)"; break; 560 case IMAGE_DIRECTORY_ENTRY_COPYRIGHT: pszName = "Description String (IMAGE_DIRECTORY_ENTRY_COPYRIGHT)"; break; 561 case IMAGE_DIRECTORY_ENTRY_GLOBALPTR: pszName = "Machine Value (MIPS GP) (IMAGE_DIRECTORY_ENTRY_GLOBALPTR)"; break; 562 case IMAGE_DIRECTORY_ENTRY_TLS: pszName = "TLS Directory (IMAGE_DIRECTORY_ENTRY_TLS)"; break; 563 case IMAGE_DIRECTORY_ENTRY_LOAD_CONFIG: pszName = "Load Configuration Directory (IMAGE_DIRECTORY_ENTRY_LOAD_CONFIG)"; break; 564 case IMAGE_DIRECTORY_ENTRY_BOUND_IMPORT:pszName = "Bound Import Directory in headers (IMAGE_DIRECTORY_ENTRY_BOUND_IMPORT)"; break; 565 case IMAGE_DIRECTORY_ENTRY_IAT: pszName = "Import Address Table (IMAGE_DIRECTORY_ENTRY_IAT)"; break; 566 default: 567 pszName = "unknown"; 568 } 569 dprintf((LOG, "directory %s", pszName)); 570 dprintf((LOG, " Address 0x%08x", oh.DataDirectory[i].VirtualAddress)); 571 dprintf((LOG, " Size 0x%08x", oh.DataDirectory[i].Size)); 572 } 573 } 574 dprintf((LOG, "\n\n")); 515 575 #endif 516 576 517 if(realBaseAddress != oh.ImageBase) {518 pFixups = (PIMAGE_BASE_RELOCATION)ImageDirectoryOffset(win32file, IMAGE_DIRECTORY_ENTRY_BASERELOC);519 dwFixupSize = ImageDirectorySize(win32file, IMAGE_DIRECTORY_ENTRY_BASERELOC);520 commitPage((ULONG)pFixups, FALSE);521 }522 577 #ifdef COMMIT_ALL 523 for (i=0; i<nSections; i++) {524 525 }578 for (i=0; i<nSections; i++) { 579 commitPage((ULONG)section[i].realvirtaddr, FALSE, COMPLETE_SECTION); 580 } 526 581 #else 527 for (i=0; i<nSections; i++) {528 529 530 531 532 533 534 535 536 }582 for (i=0; i<nSections; i++) { 583 switch(section[i].type) 584 { 585 case SECTION_IMPORT: 586 case SECTION_RELOC: 587 case SECTION_EXPORT: 588 commitPage((ULONG)section[i].realvirtaddr, FALSE, COMPLETE_SECTION); 589 break; 590 } 591 } 537 592 #endif 538 if(processExports((char *)win32file) == FALSE) {539 540 541 }593 if(processExports((char *)win32file) == FALSE) { 594 dprintf((LOG, "Failed to process exported apis" )); 595 goto failure; 596 } 542 597 } 543 598 #ifdef COMMIT_ALL 544 599 else { 545 600 commitPage((ULONG)section[0].realvirtaddr, FALSE, COMPLETE_SECTION); 546 601 } 547 602 #endif … … 556 611 // implicitly call functions depending on it. 557 612 if(GetSectionHdrByImageDir(win32file, IMAGE_DIRECTORY_ENTRY_RESOURCE, &sh)) { 558 559 560 613 //get offset in resource object of directory entry 614 pResRootDir = (PIMAGE_RESOURCE_DIRECTORY)(sh.VirtualAddress + realBaseAddress); 615 ulRVAResourceSection = sh.VirtualAddress; 561 616 } 562 617 563 618 if(!(dwFlags & (FLAG_PELDR_LOADASDATAFILE | FLAG_PELDR_SKIPIMPORTS))) 564 619 { 565 566 567 568 620 if(processImports((char *)win32file) == FALSE) { 621 dprintf((LOG, "Failed to process imports!" )); 622 goto failure; 623 } 569 624 } 570 625 return(TRUE); … … 572 627 failure: 573 628 if(memmap) { 574 575 629 delete memmap; 630 memmap = NULL; 576 631 } 577 632 if(hFile) { 578 579 633 OSLibDosClose(hFile); 634 hFile = 0; 580 635 } 581 636 errorState = ERROR_INTERNAL; … … 595 650 //Round down to nearest page boundary 596 651 virtAddress = virtAddress & ~0xFFF; 597 652 598 653 section = findSectionByOS2Addr(virtAddress); 599 654 if(section == NULL) { 600 601 602 603 604 605 606 607 608 609 610 611 655 size = 4096; 656 sectionsize = 4096; 657 protflags = PAG_READ|PAG_WRITE; //readonly? 658 section = findPreviousSectionByOS2Addr(virtAddress); 659 if(section == NULL) {//access to header 660 offset = 0; 661 fileoffset = virtAddress - realBaseAddress; 662 } 663 else { 664 offset = virtAddress - (section->realvirtaddr + section->virtualsize); 665 fileoffset = section->rawoffset + section->rawsize + offset; 666 } 612 667 } 613 668 else { 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 669 protflags = section->pageflags; 670 offset = virtAddress - section->realvirtaddr; 671 sectionsize = section->virtualsize - offset; 672 673 if(offset > section->rawsize || section->type == SECTION_UNINITDATA) { 674 //unintialized data (set to 0) 675 size = 0; 676 fileoffset = -1; 677 } 678 else { 679 size = section->rawsize-offset; 680 fileoffset = section->rawoffset + offset; 681 } 682 if(fWriteAccess & !(section->pageflags & PAG_WRITE)) { 683 dprintf((LOG, "Win32PeLdrImage::commitPage: No write access to 0%x!", virtAddress)); 684 return FALSE; 685 } 631 686 } 632 687 //Check range of pages with the same attributes starting at virtAddress … … 635 690 rc = DosQueryMem((PVOID)virtAddress, &range, &attr); 636 691 if(rc) { 637 638 692 dprintf((LOG, "Win32PeLdrImage::commitPage: DosQueryMem for %x returned %d", virtAddress, rc)); 693 return FALSE; 639 694 } 640 695 if(attr & PAG_COMMIT) { 641 642 696 dprintf((LOG, "Win32PeLdrImage::commitPage: Memory at 0x%x already committed!", virtAddress)); 697 return FALSE; 643 698 } 644 699 645 700 if(fPageCmd == SINGLE_PAGE) { 646 647 701 size = min(size, PAGE_SIZE); 702 sectionsize = min(sectionsize, PAGE_SIZE); 648 703 } 649 704 else 650 705 if(fPageCmd == SECTION_PAGES) { 651 652 706 size = min(size, DEFAULT_NR_PAGES*PAGE_SIZE); 707 sectionsize = min(sectionsize, DEFAULT_NR_PAGES*PAGE_SIZE); 653 708 } 654 709 size = min(size, range); … … 656 711 657 712 if(fileoffset != -1) { 658 659 660 661 662 663 664 665 666 667 668 669 670 671 672 673 674 675 676 677 678 679 680 681 682 713 rc = DosSetMem((PVOID)virtAddress, sectionsize, PAG_READ|PAG_WRITE|PAG_COMMIT); 714 if(rc) { 715 dprintf((LOG, "Win32PeLdrImage::commitPage: DosSetMem failed (%d)!", rc)); 716 return FALSE; 717 } 718 719 if(DosSetFilePtr(hFile, fileoffset, FILE_BEGIN, &ulNewPos) == -1) { 720 dprintf((LOG, "Win32PeLdrImage::commitPage: DosSetFilePtr failed for 0x%x!", fileoffset)); 721 return FALSE; 722 } 723 if(DosRead(hFile, (PVOID)virtAddress, size, &ulRead)) { 724 dprintf((LOG, "Win32PeLdrImage::commitPage: DosRead failed for 0x%x!", virtAddress)); 725 return FALSE; 726 } 727 if(ulRead != size) { 728 dprintf((LOG, "Win32PeLdrImage::commitPage: DosRead failed to read %x (%x) bytes at %x for 0x%x!", size, ulRead, fileoffset, virtAddress)); 729 return FALSE; 730 } 731 setFixups(virtAddress, sectionsize); 732 733 rc = DosSetMem((PVOID)virtAddress, sectionsize, protflags); 734 if(rc) { 735 dprintf((LOG, "Win32PeLdrImage::commitPage: DosSetMem failed (%d)!", rc)); 736 return FALSE; 737 } 683 738 } 684 739 else { 685 686 687 688 689 690 691 692 693 694 695 696 740 rc = DosSetMem((PVOID)virtAddress, sectionsize, PAG_READ|PAG_WRITE|PAG_COMMIT); 741 if(rc) { 742 dprintf((LOG, "Win32PeLdrImage::commitPage: DosSetMem failed (%d)!", rc)); 743 return FALSE; 744 } 745 setFixups(virtAddress, sectionsize); 746 747 rc = DosSetMem((PVOID)virtAddress, sectionsize, protflags); 748 if(rc) { 749 dprintf((LOG, "Win32PeLdrImage::commitPage: DosSetMem failed (%d)!", rc)); 750 return FALSE; 751 } 697 752 } 698 753 return TRUE; … … 715 770 716 771 if(virtaddress < imageVirtBase) 717 772 imageVirtBase = virtaddress; 718 773 if(virtaddress + virtsize > imageVirtEnd) 719 774 imageVirtEnd = virtaddress + virtsize; 720 775 721 776 nrsections++; … … 732 787 //Allocated in peldr.dll 733 788 if(reservedMem && reservedMem == oh.ImageBase) { 734 735 789 realBaseAddress = oh.ImageBase; 790 return TRUE; 736 791 } 737 792 738 793 //SvL: We don't care where the image is loaded for resource lookup 739 794 if(fh.Characteristics & IMAGE_FILE_RELOCS_STRIPPED && !(dwFlags & FLAG_PELDR_LOADASDATAFILE)) { 740 795 return allocFixedMem(reservedMem); 741 796 } 742 797 rc = DosAllocMem((PPVOID)&baseAddress, imageSize, PAG_READ | PAG_WRITE | flAllocMem); 743 798 if(rc) { 744 745 746 799 dprintf((LOG, "Win32PeLdrImage::allocSections, DosAllocMem returned %d", rc)); 800 errorState = rc; 801 return(FALSE); 747 802 } 748 803 realBaseAddress = baseAddress; … … 754 809 { 755 810 for(int i=0;i<nrsections;i++) { 756 757 758 811 if(section[i].type == type) { 812 return §ion[i]; 813 } 759 814 } 760 815 return NULL; … … 765 820 { 766 821 for(int i=0;i<nrsections;i++) { 767 768 769 822 if(section[i].virtaddr <= addr && section[i].virtaddr + section[i].virtualsize > addr) { 823 return §ion[i]; 824 } 770 825 } 771 826 return NULL; … … 776 831 { 777 832 for(int i=0;i<nrsections;i++) { 778 779 780 833 if(section[i].realvirtaddr <= addr && section[i].realvirtaddr + section[i].virtualsize > addr) { 834 return §ion[i]; 835 } 781 836 } 782 837 return NULL; … … 790 845 791 846 for(int i=0;i<nrsections;i++) { 792 793 794 795 796 797 847 if(section[i].realvirtaddr > addr) { 848 if(section[i].realvirtaddr < lowestAddr) { 849 lowestAddr = section[i].realvirtaddr; 850 index = i; 851 } 852 } 798 853 } 799 854 if(index == -1) 800 855 return NULL; 801 856 802 857 return §ion[index]; … … 819 874 memallocs = (ULONG *)malloc(4096*sizeof(ULONG *)); 820 875 if(memallocs == NULL) { 821 822 876 dprintf((LOG, "allocFixedMem: MALLOC FAILED for memallocs" )); 877 return FALSE; 823 878 } 824 879 825 880 if(oh.ImageBase < 512*1024*1024) { 826 881 allocFlags = 0; 827 882 } 828 883 while(TRUE) { 829 830 831 832 833 834 835 836 837 838 839 840 841 842 843 844 845 846 847 848 849 850 851 852 853 854 884 rc = DosAllocMem((PPVOID)&address, FALLOC_SIZE, PAG_READ | allocFlags); 885 if(rc) break; 886 887 dprintf((LOG, "DosAllocMem returned %x", address )); 888 if(address + FALLOC_SIZE >= oh.ImageBase) { 889 if(address > oh.ImageBase) {//we've passed it! 890 DosFreeMem((PVOID)address); 891 break; 892 } 893 //found the right address 894 DosFreeMem((PVOID)address); 895 896 diff = oh.ImageBase - address; 897 if(diff) { 898 rc = DosAllocMem((PPVOID)&address, diff, PAG_READ | allocFlags); 899 if(rc) break; 900 } 901 rc = DosAllocMem((PPVOID)&baseAddress, imageSize, PAG_READ | PAG_WRITE | allocFlags); 902 if(rc) break; 903 904 if(diff) DosFreeMem((PVOID)address); 905 906 realBaseAddress = baseAddress; 907 break; 908 } 909 memallocs[alloccnt++] = address; 855 910 } 856 911 for(i=0;i<alloccnt;i++) { 857 912 DosFreeMem((PVOID)memallocs[i]); 858 913 } 859 914 free(memallocs); 860 915 861 916 if(realBaseAddress == 0) //Let me guess.. MS Office app? 862 917 return(FALSE); 863 918 864 919 return(TRUE); … … 878 933 // Process all the image sections 879 934 for(i=0;i<nrsections;i++) { 880 935 section[i].realvirtaddr = realBaseAddress + (section[i].virtaddr - oh.ImageBase); 881 936 } 882 937 883 938 for(i=0;i<nrsections;i++) { 884 885 939 switch(section[i].type) 940 { 886 941 case SECTION_CODE: 887 942 case (SECTION_CODE | SECTION_IMPORT): 888 889 if(section[i].flags & IMAGE_SCN_MEM_WRITE) 890 891 943 section[i].pageflags = PAG_EXECUTE | PAG_READ; 944 if(section[i].flags & IMAGE_SCN_MEM_WRITE) 945 section[i].pageflags |= PAG_WRITE; 946 break; 892 947 case SECTION_INITDATA: 893 948 case SECTION_UNINITDATA: 894 949 case SECTION_IMPORT: 895 896 897 950 case SECTION_TLS: 951 section[i].pageflags = PAG_WRITE | PAG_READ; 952 break; 898 953 899 954 case SECTION_RESOURCE: 900 955 //TODO: GDI32 changes some bitmap structures to avoid problems in Open32 901 956 // -> causes crashes if resource section is readonly 902 957 // -> make it readonly again when gdi32 has been rewritten 903 904 958 section[i].pageflags = PAG_WRITE | PAG_READ; 959 break; 905 960 906 961 case SECTION_READONLYDATA: 907 962 case SECTION_EXPORT: 908 963 default: 909 910 911 912 913 964 section[i].pageflags = PAG_READ; 965 break; 966 } 967 if(section[i].flags & (IMAGE_SCN_CNT_INITIALIZED_DATA|IMAGE_SCN_CNT_UNINITIALIZED_DATA)) { 968 //SvL: sometimes i.e. import/export sections also contain data 914 969 // must make them read/write 915 970 section[i].pageflags = PAG_WRITE; 916 971 } 917 972 … … 930 985 931 986 if(realBaseAddress == oh.ImageBase || fh.Characteristics & IMAGE_FILE_RELOCS_STRIPPED) { 932 987 return(TRUE); 933 988 } 934 989 … … 937 992 size = (size-1) & ~0xFFF; 938 993 size += PAGE_SIZE; 939 994 940 995 if(prel) { 941 942 while(((ULONG)prel < (ULONG)pFixups+dwFixupSize) && 943 prel->VirtualAddress && prel->VirtualAddress < virtAddress) 996 j = 1; 997 while(((ULONG)prel < (ULONG)pFixups+dwFixupSize) && 998 prel->VirtualAddress && prel->VirtualAddress < virtAddress) 944 999 { 945 946 947 while(((ULONG)prel < (ULONG)pFixups+dwFixupSize) && 948 prel->VirtualAddress && prel->VirtualAddress < virtAddress + size) 1000 prel = (PIMAGE_BASE_RELOCATION)((char*)prel + prel->SizeOfBlock); 1001 } 1002 while(((ULONG)prel < (ULONG)pFixups+dwFixupSize) && 1003 prel->VirtualAddress && prel->VirtualAddress < virtAddress + size) 949 1004 { 950 951 952 953 954 955 956 957 958 959 960 961 962 963 964 965 966 967 968 969 970 971 972 973 974 975 976 977 978 979 980 981 982 983 984 985 986 987 988 989 990 991 992 993 994 995 996 997 998 999 1000 1001 1002 1003 1004 1005 1006 1007 1008 1009 1010 1011 1012 1013 1005 page = (char *)((char *)prel + (ULONG)prel->VirtualAddress); 1006 count = (prel->SizeOfBlock - 8)/2; 1007 j++; 1008 for(i=0;i<count;i++) { 1009 int type = prel->TypeOffset[i] >> 12; 1010 int offset = prel->TypeOffset[i] & 0xFFF; 1011 int fixupsize = 0; 1012 1013 switch(type) 1014 { 1015 case IMAGE_REL_BASED_HIGHLOW: 1016 fixupsize = 4; 1017 break; 1018 case IMAGE_REL_BASED_HIGH: 1019 case IMAGE_REL_BASED_LOW: 1020 fixupsize = 2; 1021 break; 1022 } 1023 //If the fixup crosses the final page boundary, 1024 //then we have to load another page 1025 if(prel->VirtualAddress + offset + fixupsize > virtAddress + size) 1026 { 1027 newpage = realBaseAddress + prel->VirtualAddress + offset + fixupsize; 1028 newpage &= ~0xFFF; 1029 1030 section = findSectionByOS2Addr(newpage); 1031 if(section == NULL) { 1032 //should never happen 1033 dprintf((LOG, "::setFixups -> section == NULL!!")); 1034 return FALSE; 1035 } 1036 //SvL: Read page from disk 1037 commitPage(newpage, FALSE, SINGLE_PAGE); 1038 1039 //SvL: Enable write access 1040 DosSetMem((PVOID)newpage, PAGE_SIZE, PAG_READ|PAG_WRITE); 1041 } 1042 1043 switch(type) 1044 { 1045 case IMAGE_REL_BASED_ABSOLUTE: 1046 break; //skip 1047 case IMAGE_REL_BASED_HIGHLOW: 1048 AddOff32Fixup(prel->VirtualAddress + offset); 1049 break; 1050 case IMAGE_REL_BASED_HIGH: 1051 AddOff16Fixup(prel->VirtualAddress + offset, TRUE); 1052 break; 1053 case IMAGE_REL_BASED_LOW: 1054 AddOff16Fixup(prel->VirtualAddress + offset, FALSE); 1055 break; 1056 case IMAGE_REL_BASED_HIGHADJ: 1057 case IMAGE_REL_BASED_MIPS_JMPADDR: 1058 default: 1059 break; 1060 } 1061 if(prel->VirtualAddress + offset + fixupsize > virtAddress + size) 1062 { 1063 //SvL: Restore original page protection flags 1064 DosSetMem((PVOID)newpage, PAGE_SIZE, section->pageflags); 1065 } 1066 } 1067 prel = (PIMAGE_BASE_RELOCATION)((char*)prel + prel->SizeOfBlock); 1068 }//while 1014 1069 } 1015 1070 else { 1016 1017 1071 dprintf((LOG, "Win32PeLdrImage::setFixups, no fixups at %x, %d", virtAddress, size)); 1072 return(FALSE); 1018 1073 } 1019 1074 return(TRUE); … … 1028 1083 1029 1084 if(fh.Characteristics & IMAGE_FILE_RELOCS_STRIPPED) { 1030 1085 return(TRUE); 1031 1086 } 1032 1087 … … 1050 1105 break; 1051 1106 case IMAGE_REL_BASED_HIGH: 1052 1053 1107 AddOff16Fixup(prel->VirtualAddress + offset, TRUE); 1108 break; 1054 1109 case IMAGE_REL_BASED_LOW: 1055 1056 1110 AddOff16Fixup(prel->VirtualAddress + offset, FALSE); 1111 break; 1057 1112 case IMAGE_REL_BASED_HIGHADJ: 1058 1113 case IMAGE_REL_BASED_MIPS_JMPADDR: … … 1094 1149 orgaddr = *fixup; 1095 1150 if(fHighFixup) { 1096 1151 *fixup += (USHORT)((realBaseAddress - oh.ImageBase) >> 16); 1097 1152 // dprintf((LOG, "AddOff16FixupH 0x%x org 0x%x -> new 0x%x", fixup, orgaddr, *fixup)); 1098 1153 } 1099 1154 else { 1100 1155 *fixup += (USHORT)((realBaseAddress - oh.ImageBase) & 0xFFFF); 1101 1156 // dprintf((LOG, "AddOff16FixupL 0x%x org 0x%x -> new 0x%x", fixup, orgaddr, *fixup)); 1102 1157 } … … 1113 1168 if(apiaddr == 0) 1114 1169 { 1115 1170 dprintf((LOG, "KERNEL32:Win32PeLdrImage - %s.%u not found\n", 1116 1171 WinDll->getName(), 1117 1172 ordinal)); 1118 1173 1119 1120 1174 dprintf((LOG, "--->>> NOT FOUND!" )); 1175 *import = (ULONG)MissingApi; 1121 1176 } 1122 1177 else *import = apiaddr; … … 1133 1188 if(apiaddr == 0) 1134 1189 { 1135 1190 dprintf((LOG, "KERNEL32:Win32PeLdrImage - %s.%s not found\n", 1136 1191 WinDll->getName(), 1137 1192 impname)); 1138 1193 1139 1140 1194 dprintf((LOG, "--->>> NOT FOUND!" )); 1195 *import = (ULONG)MissingApi; 1141 1196 } 1142 1197 else *import = apiaddr; … … 1170 1225 int ord, RVAExport; 1171 1226 char *name; 1172 for(i=0;i<ped->NumberOfNames;i++) 1227 for(i=0;i<ped->NumberOfNames;i++) 1173 1228 { 1174 1229 fForwarder = FALSE; 1175 1230 ord = ptrOrd[i] + ped->Base; 1176 1231 name = (char *)((ULONG)ptrNames[i] + (ULONG)win32file); … … 1180 1235 if(RVAExport > oh.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].VirtualAddress && 1181 1236 RVAExport < oh.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].VirtualAddress 1182 + oh.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].Size) 1237 + oh.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].Size) 1183 1238 { 1184 1239 fForwarder = AddForwarder(oh.ImageBase + RVAExport, name, ord); 1185 1240 } 1186 1241 if(!fForwarder) { 1187 1242 //points to code (virtual address relative to oh.ImageBase 1188 1243 AddNameExport(oh.ImageBase + RVAExport, name, ord); … … 1190 1245 } 1191 1246 } 1192 for(i=0;i<max(ped->NumberOfNames,ped->NumberOfFunctions);i++) 1247 for(i=0;i<max(ped->NumberOfNames,ped->NumberOfFunctions);i++) 1193 1248 { 1194 1249 fForwarder = FALSE; 1195 1250 ord = ped->Base + i; //Correct?? 1196 1251 RVAExport = ptrAddress[i]; … … 1198 1253 if(RVAExport > oh.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].VirtualAddress && 1199 1254 RVAExport < oh.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].VirtualAddress 1200 + oh.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].Size) 1255 + oh.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].Size) 1201 1256 { 1202 1257 fForwarder = AddForwarder(oh.ImageBase + RVAExport, NULL, ord); 1203 1258 } 1204 1259 if(!fForwarder && RVAExport) { 1205 1260 //points to code (virtual address relative to oh.ImageBase 1206 1261 dprintf((LOG, "ord %d at 0x%08x (0x%08x)", ord, RVAExport, realBaseAddress + RVAExport)); … … 1218 1273 1219 1274 if(nameexports == NULL) { 1220 1221 1222 1275 nameExportSize= 4096; 1276 nameexports = (NameExport *)malloc(nameExportSize); 1277 curnameexport = nameexports; 1223 1278 } 1224 1279 nsize = (ULONG)curnameexport - (ULONG)nameexports; 1225 1280 if(nsize + sizeof(NameExport) + strlen(apiname) > nameExportSize) { 1226 1227 1228 1229 1230 1231 1281 nameExportSize += 4096; 1282 char *tmp = (char *)nameexports; 1283 nameexports = (NameExport *)malloc(nameExportSize); 1284 memcpy(nameexports, tmp, nsize); 1285 curnameexport = (NameExport *)((ULONG)nameexports + nsize); 1286 free(tmp); 1232 1287 } 1233 1288 if(fAbsoluteAddress) {//forwarders use absolute address 1234 1235 } 1236 else 1289 curnameexport->virtaddr = virtaddr; 1290 } 1291 else curnameexport->virtaddr = realBaseAddress + (virtaddr - oh.ImageBase); 1237 1292 curnameexport->ordinal = ordinal; 1238 1293 *(ULONG *)curnameexport->name = 0; … … 1241 1296 curnameexport->nlength = strlen(apiname) + 1; 1242 1297 if(curnameexport->nlength < sizeof(curnameexport->name)) 1243 1298 curnameexport->nlength = sizeof(curnameexport->name); 1244 1299 1245 1300 curnameexport = (NameExport *)((ULONG)curnameexport->name + curnameexport->nlength); … … 1250 1305 { 1251 1306 if(ordexports == NULL) { 1252 1253 1307 ordexports = (OrdExport *)malloc(nrOrdExports * sizeof(OrdExport)); 1308 curordexport = ordexports; 1254 1309 } 1255 1310 if(fAbsoluteAddress) {//forwarders use absolute address 1256 1257 } 1258 else 1311 curordexport->virtaddr = virtaddr; 1312 } 1313 else curordexport->virtaddr = realBaseAddress + (virtaddr - oh.ImageBase); 1259 1314 curordexport->ordinal = ordinal; 1260 1315 curordexport++; … … 1269 1324 DWORD exportaddr; 1270 1325 int forwardord; 1271 1326 1272 1327 forwarddll = strdup(forward); 1273 1328 if(forwarddll == NULL) { 1274 1329 return FALSE; 1275 1330 } 1276 1331 forwardapi = strchr(forwarddll, '.'); 1277 1332 if(forwardapi == NULL) { 1278 1333 goto fail; 1279 1334 } 1280 1335 *forwardapi++ = 0; 1281 1336 if(strlen(forwarddll) == 0 || strlen(forwardapi) == 0) { 1282 1337 goto fail; 1283 1338 } 1284 1339 WinDll = Win32DllBase::findModule(forwarddll); 1285 1340 if(WinDll == NULL) { 1286 1287 1288 1289 1290 1341 WinDll = loadDll(forwarddll); 1342 if(WinDll == NULL) { 1343 dprintf((LOG, "ERROR: couldn't find forwarder %s.%s", forwarddll, forwardapi)); 1344 goto fail; 1345 } 1291 1346 } 1292 1347 //check if name or ordinal forwarder 1293 1348 forwardord = 0; 1294 1349 if(*forwardapi >= '0' && *forwardapi <= '9') { 1295 1350 forwardord = atoi(forwardapi); 1296 1351 } 1297 1352 if(forwardord != 0 || (strlen(forwardapi) == 1 && *forwardapi == '0')) { 1298 1299 } 1300 else 1353 exportaddr = WinDll->getApi(forwardord); 1354 } 1355 else exportaddr = WinDll->getApi(forwardapi); 1301 1356 1302 1357 if(apiname) { 1303 1358 dprintf((LOG, "address 0x%x %s @%d (0x%08x) forwarder %s.%s", virtaddr - oh.ImageBase, apiname, ordinal, virtaddr, forwarddll, forwardapi)); 1304 1359 AddNameExport(exportaddr, apiname, ordinal, TRUE); 1305 1360 } 1306 1361 else { … … 1322 1377 char modname[CCHMAXPATH]; 1323 1378 1324 1325 1326 1327 1328 1329 1330 1331 1332 1379 strcpy(modname, pszCurModule); 1380 //rename dll if necessary (i.e. OLE32 -> OLE32OS2) 1381 Win32DllBase::renameDll(modname); 1382 1383 if(isPEImage(modname) != ERROR_SUCCESS_W) 1384 {//LX image, so let OS/2 do all the work for us 1385 APIRET rc; 1386 char szModuleFailure[CCHMAXPATH] = ""; 1387 ULONG hInstanceNewDll; 1333 1388 Win32LxDll *lxdll; 1334 1389 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 1390 char *dot = strchr(modname, '.'); 1391 if(dot) { 1392 *dot = 0; 1393 } 1394 strcat(modname, ".DLL"); 1395 rc = DosLoadModule(szModuleFailure, sizeof(szModuleFailure), modname, (HMODULE *)&hInstanceNewDll); 1396 if(rc) { 1397 dprintf((LOG, "DosLoadModule returned %X for %s\n", rc, szModuleFailure)); 1398 sprintf(szErrorModule, "%s.DLL", szModuleFailure); 1399 errorState = rc; 1400 return NULL; 1401 } 1402 lxdll = Win32LxDll::findModuleByOS2Handle(hInstanceNewDll); 1403 if(lxdll == NULL) {//shouldn't happen! 1404 dprintf((LOG, "Just loaded the dll, but can't find it anywhere?!!?")); 1405 errorState = ERROR_INTERNAL; 1406 return NULL; 1407 } 1408 lxdll->setDllHandleOS2(hInstanceNewDll); 1409 if(lxdll->AddRef() == -1) {//-1 -> load failed (attachProcess) 1410 dprintf((LOG, "Dll %s refused to be loaded; aborting", modname)); 1411 delete lxdll; 1412 errorState = ERROR_INTERNAL; 1413 return NULL; 1414 } 1360 1415 WinDll = (Win32DllBase*)lxdll; 1361 1362 1416 } 1417 else { 1363 1418 Win32PeLdrDll *pedll; 1364 1419 1365 1366 1367 1368 1369 1370 1371 1372 1373 1374 1375 1376 1377 1378 1379 1420 pedll = new Win32PeLdrDll(modname, this); 1421 if(pedll == NULL) { 1422 dprintf((LOG, "pedll: Error allocating memory" )); 1423 WinMessageBox(HWND_DESKTOP, HWND_DESKTOP, szMemErrorMsg, szErrorTitle, 0, MB_OK | MB_ERROR | MB_MOVEABLE); 1424 errorState = ERROR_INTERNAL; 1425 return NULL; 1426 } 1427 dprintf((LOG, "**********************************************************************" )); 1428 dprintf((LOG, "********************** Loading Module *********************" )); 1429 dprintf((LOG, "**********************************************************************" )); 1430 if(pedll->init(0) == FALSE) { 1431 dprintf((LOG, "Internal WinDll error ", pedll->getError() )); 1432 delete pedll; 1433 return NULL; 1434 } 1380 1435 #ifdef DEBUG 1381 1436 pedll->AddRef(getModuleName()); 1382 1437 #else 1383 1438 pedll->AddRef(); 1384 1439 #endif 1385 1386 1387 1388 1389 1390 1391 1392 1393 1394 1395 1440 if(pedll->attachProcess() == FALSE) { 1441 dprintf((LOG, "attachProcess failed!" )); 1442 delete pedll; 1443 errorState = ERROR_INTERNAL; 1444 return NULL; 1445 } 1446 WinDll = (Win32DllBase*)pedll; 1447 } 1448 1449 dprintf((LOG, "**********************************************************************" )); 1450 dprintf((LOG, "********************** Finished Loading Module %s ", modname )); 1396 1451 dprintf((LOG, "**********************************************************************" )); 1397 1452 1398 1453 return WinDll; 1399 1454 } 1400 1455 //****************************************************************************** … … 1545 1600 if(WinDll == NULL) 1546 1601 { //not found, so load it 1547 1548 1549 1550 1602 WinDll = loadDll(pszCurModule); 1603 if(WinDll == NULL) { 1604 return FALSE; 1605 } 1551 1606 } 1552 1607 else { 1553 1554 1555 1608 WinDll->AddRef(); 1609 1610 dprintf((LOG, "Already found ", pszCurModule)); 1556 1611 } 1557 1612 //add the dll we just loaded to dependency list for this image … … 1569 1624 section = findSectionByOS2Addr(ulCurFixup); 1570 1625 if(section == NULL) { 1571 1572 1626 dprintf((LOG, "Unable to find section for %x", ulCurFixup )); 1627 return FALSE; 1573 1628 } 1574 1629 //SvL: Read page from disk … … 1599 1654 ulCurFixup += sizeof(IMAGE_THUNK_DATA); 1600 1655 j++; 1601 1602 1603 1604 1605 1656 if((ulCurFixup & 0xfff) == 0) { 1657 commitPage(ulCurFixup & ~0xfff, FALSE, SINGLE_PAGE); 1658 DosSetMem((PVOID)(ulCurFixup & ~0xfff), PAGE_SIZE, PAG_READ|PAG_WRITE); 1659 nrPages++; 1660 } 1606 1661 } 1607 1662 //SvL: And restore original protection flags … … 1624 1679 { 1625 1680 if((address >= realBaseAddress) && (address < realBaseAddress + imageSize)) { 1626 1681 return TRUE; 1627 1682 } 1628 1683 return FALSE; … … 1636 1691 sect = findSectionByOS2Addr(address); 1637 1692 if(sect && (sect->pageflags & PAG_EXECUTE)) { 1638 1693 return TRUE; 1639 1694 } 1640 1695 return FALSE; … … 1659 1714 if(apilen < 4) 1660 1715 { 1661 1662 1663 1664 1665 } 1666 else 1716 *(ULONG *)tmp = 0; 1717 strcpy(tmp, name); 1718 apiname = tmp; 1719 apilen = 4; 1720 } 1721 else apiname = name; 1667 1722 1668 1723 curexport = nameexports; … … 1672 1727 *(ULONG *)curexport->name == *(ULONG *)apiname) 1673 1728 { 1674 1675 1729 if(strcmp(curexport->name, apiname) == 0) 1730 return(curexport->virtaddr); 1676 1731 } 1677 1732 curexport = (NameExport *)((ULONG)curexport->name + curexport->nlength); … … 1689 1744 curexport = ordexports; 1690 1745 for(i=0;i<nrOrdExports;i++) { 1691 1692 1693 1746 if(curexport->ordinal == ordinal) 1747 return(curexport->virtaddr); 1748 curexport++; 1694 1749 } 1695 1750 //Name exports also contain an ordinal, so check this 1696 1751 nexport = nameexports; 1697 1752 for(i=0;i<nrNameExports;i++) { 1698 1699 1700 1701 1753 if(nexport->ordinal == ordinal) 1754 return(nexport->virtaddr); 1755 1756 nexport = (NameExport *)((ULONG)nexport->name + nexport->nlength); 1702 1757 } 1703 1758 return(0); … … 1728 1783 1729 1784 if( r != MBID_IGNORE ) 1730 1785 ExitProcess(987); 1731 1786 1732 1787 fIgnore = TRUE;
Note:
See TracChangeset
for help on using the changeset viewer.