Changeset 5011 for trunk/src/kernel32/winimagepeldr.cpp
- Timestamp:
- Jan 22, 2001, 7:26:52 PM (25 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/kernel32/winimagepeldr.cpp
r4758 r5011 1 /* $Id: winimagepeldr.cpp,v 1.6 5 2000-12-05 20:41:43sandervl Exp $ */1 /* $Id: winimagepeldr.cpp,v 1.66 2001-01-22 18:26:51 sandervl Exp $ */ 2 2 3 3 /* … … 13 13 * TODO: Loading of forwarder dlls before handling imports might not be correct 14 14 * (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) 15 16 * 16 17 * NOTE: FLAG_PELDR_LOADASDATAFILE is a special flag to only load the resource directory … … 56 57 //This is very useful during debugging as you'll get lots of exceptions 57 58 //otherwise. 59 //#ifdef DEBUG 58 60 #define COMMIT_ALL 61 //#endif 59 62 60 63 char szErrorTitle[] = "Odin"; … … 104 107 Win32PeLdrImage::Win32PeLdrImage(char *pszFileName, BOOL isExe) : 105 108 Win32ImageBase(-1), 106 nrsections(0), imageSize(0), dwFlags(0), 109 nrsections(0), imageSize(0), dwFlags(0), section(NULL), 107 110 imageVirtBase(-1), realBaseAddress(0), imageVirtEnd(0), 108 111 nrNameExports(0), nrOrdExports(0), nameexports(NULL), ordexports(NULL), … … 140 143 Win32PeLdrImage::~Win32PeLdrImage() 141 144 { 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) 151 154 DosFreeMem((PVOID)realBaseAddress); 152 155 153 if(nameexports)156 if(nameexports) 154 157 free(nameexports); 155 158 156 if(ordexports)159 if(ordexports) 157 160 free(ordexports); 161 162 if(section) 163 free(section); 158 164 } 159 165 //****************************************************************************** … … 171 177 ULONG signature; 172 178 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) { 178 184 goto failure; 179 }180 //read dos header181 if(DosRead(hFile, (LPVOID)&doshdr, sizeof(doshdr), &ulRead)) {185 } 186 //read dos header 187 if(DosRead(hFile, (LPVOID)&doshdr, sizeof(doshdr), &ulRead)) { 182 188 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) { 185 191 goto failure; 186 }187 //read signature dword188 if(DosRead(hFile, (LPVOID)&signature, sizeof(signature), &ulRead)) {192 } 193 //read signature dword 194 if(DosRead(hFile, (LPVOID)&signature, sizeof(signature), &ulRead)) { 189 195 goto failure; 190 }191 //read pe header192 if(DosRead(hFile, (LPVOID)&fh, sizeof(fh), &ulRead)) {196 } 197 //read pe header 198 if(DosRead(hFile, (LPVOID)&fh, sizeof(fh), &ulRead)) { 193 199 goto failure; 194 }195 //read optional header196 if(DosRead(hFile, (LPVOID)&oh, sizeof(oh), &ulRead)) {200 } 201 //read optional header 202 if(DosRead(hFile, (LPVOID)&oh, sizeof(oh), &ulRead)) { 197 203 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) { 200 206 dprintf((LOG, "Not a valid PE file (probably a 16 bits windows exe/dll)!")); 201 207 WinMessageBox(HWND_DESKTOP, HWND_DESKTOP, szPEErrorMsg, szErrorTitle, 0, MB_OK | MB_ERROR | MB_MOVEABLE); 202 208 goto failure; 203 }204 205 if(oh.SizeOfImage == 0) {//just in case206 oh.SizeOfImage = OSLibDosGetFileSize(hFile, NULL);207 }208 209 imageSize = oh.SizeOfImage;210 //Allocate memory to hold the entire image211 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) { 212 218 dprintf((LOG, "Failed to allocate image memory for %s at %x, rc %d", szFileName, oh.ImageBase, errorState));; 213 219 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()) { 218 224 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 valid225 } 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 227 233 dprintf((LOG, "Not a valid PE file!")); 228 234 WinMessageBox(HWND_DESKTOP, HWND_DESKTOP, szPEErrorMsg, szErrorTitle, 0, MB_OK | MB_ERROR | MB_MOVEABLE); 229 235 goto failure; 230 }231 if(fh.Machine != IMAGE_FILE_MACHINE_I386) {236 } 237 if(fh.Machine != IMAGE_FILE_MACHINE_I386) { 232 238 dprintf((LOG, "Doesn't run on x86 processors!")); 233 239 WinMessageBox(HWND_DESKTOP, HWND_DESKTOP, szCPUErrorMsg, szErrorTitle, 0, MB_OK | MB_ERROR | MB_MOVEABLE); 234 240 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) { 238 244 dprintf((LOG, "Can't convert system files")); 239 245 WinMessageBox(HWND_DESKTOP, HWND_DESKTOP, szExeErrorMsg, szErrorTitle, 0, MB_OK | MB_ERROR | MB_MOVEABLE); 240 246 goto failure; 241 }242 243 if(fh.Characteristics & IMAGE_FILE_RELOCS_STRIPPED) {247 } 248 249 if(fh.Characteristics & IMAGE_FILE_RELOCS_STRIPPED) { 244 250 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)) 277 286 { 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) 280 289 { 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++) 290 292 { 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) { 322 334 addSection(SECTION_TLS, psh[i].PointerToRawData, 323 335 psh[i].SizeOfRawData, psh[i].VirtualAddress + oh.ImageBase, 324 336 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" section352 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 datasection355 )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 section364 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 { 397 409 if(GetSectionHdrByImageDir(win32file, IMAGE_DIRECTORY_ENTRY_RESOURCE, &sh)) 398 410 { … … 401 413 sh.Misc.VirtualSize, sh.Characteristics); 402 414 } 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) 445 425 { 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)) 490 457 { 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 491 482 fTLSFixups = FALSE; 492 493 sect = findSectionByAddr((ULONG)tlsDir->AddressOfCallBacks); 483 sect = findSectionByAddr((ULONG)tlsDir->AddressOfIndex); 494 484 //There might be fixups for the TLS structure, so search the sections 495 485 //by the OS/2 virtual address too … … 499 489 } 500 490 if(sect == NULL) { 501 dprintf((LOG, "Couldn't find TLS AddressOf CallBackssection!!" ));491 dprintf((LOG, "Couldn't find TLS AddressOfIndex section!!" )); 502 492 goto failure; 503 493 } 504 494 if(fTLSFixups) { 505 setTLS CallBackAddr((PIMAGE_TLS_CALLBACK *)tlsDir->AddressOfCallBacks);//no fixup required495 setTLSIndexAddr((LPDWORD)tlsDir->AddressOfIndex); //no fixup required 506 496 } 507 497 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) 513 502 { 514 503 fTLSFixups = FALSE; 515 504 516 sect = findSectionByAddr((ULONG)tls CallBackAddr[i]);505 sect = findSectionByAddr((ULONG)tlsDir->AddressOfCallBacks); 517 506 //There might be fixups for the TLS structure, so search the sections 518 507 //by the OS/2 virtual address too 519 508 if(sect == NULL) { 520 sect = findSectionByOS2Addr((ULONG)tls CallBackAddr[i]);509 sect = findSectionByOS2Addr((ULONG)tlsDir->AddressOfIndex); 521 510 fTLSFixups = TRUE; 522 511 } 523 512 if(sect == NULL) { 524 dprintf((LOG, "Couldn't find TLS callbacksection!!" ));513 dprintf((LOG, "Couldn't find TLS AddressOfCallBacks section!!" )); 525 514 goto failure; 526 515 } 527 516 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 } 535 547 536 548 #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) 544 588 { 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 } 567 596 #endif 568 597 if(processExports((char *)win32file) == FALSE) { 598 dprintf((LOG, "Failed to process exported apis" )); 599 goto failure; 600 } 601 } 569 602 #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); 583 605 } 584 606 #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 } 594 613 #endif 595 614 596 //SvL: Use pointer to image header as module handle now. Some apps needs this597 hinstance = (HINSTANCE)realBaseAddress;598 599 //SvL: Set instance handle in process database structure600 SetPDBInstance(hinstance);601 602 //PH: get pResRootDir pointer correct first, since processImports may603 // 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 entry607 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); 619 638 620 639 failure: 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 // 635 674 //****************************************************************************** 636 675 BOOL Win32PeLdrImage::commitPage(ULONG virtAddress, BOOL fWriteAccess, int fPageCmd) … … 641 680 APIRET rc; 642 681 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 } 655 699 } 656 700 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 } 670 783 } 671 784 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 808 fail: 686 809 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 else698 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;747 810 } 748 811 //****************************************************************************** … … 750 813 void Win32PeLdrImage::addSection(ULONG type, ULONG rawoffset, ULONG rawsize, ULONG virtaddress, ULONG virtsize, ULONG flags) 751 814 { 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) 765 828 imageVirtBase = virtaddress; 766 if(virtaddress + virtsize > imageVirtEnd)829 if(virtaddress + virtsize > imageVirtEnd) 767 830 imageVirtEnd = virtaddress + virtsize; 768 831 769 nrsections++;832 nrsections++; 770 833 } 771 834 //****************************************************************************** … … 776 839 ULONG baseAddress; 777 840 778 realBaseAddress = 0;779 780 //Allocated in by pe.exe781 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 lookup787 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)) { 788 851 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)); 793 856 errorState = rc; 794 857 return(FALSE); 795 }796 realBaseAddress = baseAddress;797 return(TRUE);858 } 859 realBaseAddress = baseAddress; 860 return(TRUE); 798 861 } 799 862 //****************************************************************************** … … 801 864 Section *Win32PeLdrImage::findSection(ULONG type) 802 865 { 803 for(int i=0;i<nrsections;i++) {804 if(section[i].type == type) {805 return §ion[i];806 }807 }808 return NULL;866 for(int i=0;i<nrsections;i++) { 867 if(section[i].type == type) { 868 return §ion[i]; 869 } 870 } 871 return NULL; 809 872 } 810 873 //****************************************************************************** … … 812 875 Section *Win32PeLdrImage::findSectionByAddr(ULONG addr) 813 876 { 814 for(int i=0;i<nrsections;i++) {815 if(section[i].virtaddr <= addr && section[i].virtaddr + section[i].virtualsize > addr) {816 return §ion[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 §ion[i]; 880 } 881 } 882 return NULL; 820 883 } 821 884 //****************************************************************************** … … 823 886 Section *Win32PeLdrImage::findSectionByOS2Addr(ULONG addr) 824 887 { 825 for(int i=0;i<nrsections;i++) {826 if(section[i].realvirtaddr <= addr && section[i].realvirtaddr + section[i].virtualsize > addr) {827 return §ion[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 §ion[i]; 891 } 892 } 893 return NULL; 831 894 } 832 895 //****************************************************************************** … … 837 900 ULONG index = -1; 838 901 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 §ion[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 §ion[index]; 851 914 } 852 915 //****************************************************************************** … … 864 927 BOOL allocFlags = flAllocMem; 865 928 866 //Reserve enough space to store 4096 pointers to 1MB memory chunks867 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) { 877 940 rc = DosAllocMem((PPVOID)&address, FALLOC_SIZE, PAG_READ | allocFlags); 878 941 if(rc) break; … … 881 944 if(address + FALLOC_SIZE >= oh.ImageBase) { 882 945 if(address > oh.ImageBase) {//we've passed it! 883 884 946 DosFreeMem((PVOID)address); 947 break; 885 948 } 886 949 //found the right address … … 889 952 diff = oh.ImageBase - address; 890 953 if(diff) { 891 892 954 rc = DosAllocMem((PPVOID)&address, diff, PAG_READ | allocFlags); 955 if(rc) break; 893 956 } 894 957 rc = DosAllocMem((PPVOID)&baseAddress, imageSize, PAG_READ | PAG_WRITE | allocFlags); … … 900 963 break; 901 964 } 902 memallocs[alloccnt++] = address;903 }904 for(i=0;i<alloccnt;i++) {965 memallocs[alloccnt++] = address; 966 } 967 for(i=0;i<alloccnt;i++) { 905 968 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? 910 973 return(FALSE); 911 974 912 return(TRUE);975 return(TRUE); 913 976 } 914 977 //****************************************************************************** … … 931 994 for(i=0;i<nrsections;i++) { 932 995 switch(section[i].type) 933 {996 { 934 997 case SECTION_CODE: 935 998 case (SECTION_CODE | SECTION_IMPORT): 936 937 if(section[i].flags & IMAGE_SCN_MEM_WRITE)938 section[i].pageflags |= PAG_WRITE;939 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; 940 1003 case SECTION_INITDATA: 941 1004 case SECTION_UNINITDATA: 942 1005 case SECTION_IMPORT: 943 case SECTION_TLS:944 945 1006 case SECTION_TLS: 1007 section[i].pageflags = PAG_WRITE | PAG_READ; 1008 break; 946 1009 947 1010 case SECTION_RESOURCE: 948 //TODO: GDI32 changes some bitmap structures to avoid problems in Open32949 950 951 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; 953 1016 954 1017 case SECTION_READONLYDATA: 955 1018 case SECTION_EXPORT: 956 1019 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 } 966 1028 } 967 1029 return(TRUE); … … 987 1049 988 1050 if(prel) { 989 j = 1;990 while(((ULONG)prel < (ULONG)pFixups+dwFixupSize) &&1051 j = 1; 1052 while(((ULONG)prel < (ULONG)pFixups+dwFixupSize) && 991 1053 prel->VirtualAddress && prel->VirtualAddress < virtAddress) 992 1054 { 993 1055 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) 997 1059 { 998 1060 page = (char *)((char *)prel + (ULONG)prel->VirtualAddress); … … 1002 1064 int type = prel->TypeOffset[i] >> 12; 1003 1065 int offset = prel->TypeOffset[i] & 0xFFF; 1004 int fixupsize = 0;1066 int fixupsize = 0; 1005 1067 1006 1068 switch(type) 1007 {1069 { 1008 1070 case IMAGE_REL_BASED_HIGHLOW: 1009 fixupsize = 4;1010 break;1011 1012 1013 fixupsize = 2;1014 break;1015 }1016 //If the fixup crosses the final page boundary,1017 //then we have to load another page1018 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; 1022 1084 1023 1085 section = findSectionByOS2Addr(newpage); 1024 1086 if(section == NULL) { 1025 //should never happen1026 dprintf((LOG, "::setFixups -> section == NULL!!"));1027 return FALSE;1087 //should never happen 1088 dprintf((LOG, "::setFixups -> section == NULL!!")); 1089 return FALSE; 1028 1090 } 1029 //SvL: Read page from disk1030 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) 1033 1095 DosSetMem((PVOID)newpage, PAGE_SIZE, PAG_READ|PAG_WRITE); 1034 }1096 } 1035 1097 1036 1098 switch(type) 1037 {1099 { 1038 1100 case IMAGE_REL_BASED_ABSOLUTE: 1039 1101 break; //skip 1040 1102 case IMAGE_REL_BASED_HIGHLOW: 1041 1042 1043 1044 AddOff16Fixup(prel->VirtualAddress + offset, TRUE);1045 break;1046 1047 AddOff16Fixup(prel->VirtualAddress + offset, FALSE);1048 break;1049 1050 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: 1051 1113 default: 1052 1114 break; 1053 1115 } 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) 1057 1119 DosSetMem((PVOID)newpage, PAGE_SIZE, section->pageflags); 1058 }1120 } 1059 1121 } 1060 1122 prel = (PIMAGE_BASE_RELOCATION)((char*)prel + prel->SizeOfBlock); … … 1062 1124 } 1063 1125 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)); 1065 1127 return(FALSE); 1066 1128 } … … 1081 1143 if(prel) { 1082 1144 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: 1093 1155 //// dprintf((LOG, "absolute fixup; unused" )); 1094 break; //skip1095 case IMAGE_REL_BASED_HIGHLOW:1156 break; //skip 1157 case IMAGE_REL_BASED_HIGHLOW: 1096 1158 //// 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 }//while1159 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 1114 1176 } 1115 1177 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); 1119 1181 } 1120 1182 return(TRUE);
Note:
See TracChangeset
for help on using the changeset viewer.