Changeset 10397 for trunk/src/kernel32/winimagepeldr.cpp
- Timestamp:
- Jan 15, 2004, 11:39:15 AM (22 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/kernel32/winimagepeldr.cpp
r10001 r10397 1 /* $Id: winimagepeldr.cpp,v 1.10 8 2003-04-09 12:24:45sandervl Exp $ */1 /* $Id: winimagepeldr.cpp,v 1.109 2004-01-15 10:39:13 sandervl Exp $ */ 2 2 3 3 /* … … 6 6 * Copyright 1998-2000 Sander van Leeuwen (sandervl@xs4all.nl) 7 7 * Copyright 1998 Knut St. Osmundsen 8 * Copyright 2003 Innotek Systemberatung GmbH (sandervl@innotek.de) 9 * 8 10 * 9 11 * Project Odin Software License can be found in LICENSE.TXT … … 110 112 nrsections(0), imageSize(0), dwFlags(0), section(NULL), 111 113 imageVirtBase(-1), realBaseAddress(0), imageVirtEnd(0), 112 nrNameExports(0), nrOrdExports(0), nameexports(NULL), ordexports(NULL), 113 memmap(NULL), pFixups(NULL), dwFixupSize(0), curnameexport(NULL), curordexport(NULL), 114 nrOrdExportsRegistered(0), peview(NULL) 115 { 116 HFILE dllfile; 114 memmap(NULL), pFixups(NULL), dwFixupSize(0), peview(NULL), 115 originalBaseAddress(0) 116 { 117 HFILE dllfile; 117 118 118 119 fIsPEImage = TRUE; … … 166 167 } 167 168 168 if(nameexports)169 free(nameexports);170 171 if(ordexports)172 free(ordexports);173 174 169 if(section) 175 170 free(section); … … 181 176 ULONG filesize, ulRead, ulNewPos; 182 177 PIMAGE_SECTION_HEADER psh; 183 IMAGE_SECTION_HEADER sh; 178 IMAGE_SECTION_HEADER sh; 179 IMAGE_OPTIONAL_HEADER oh; 180 IMAGE_FILE_HEADER fh; 184 181 IMAGE_TLS_DIRECTORY *tlsDir = NULL; 185 182 int nSections, i; … … 245 242 oh.SizeOfImage = OSLibDosGetFileSize(hFile, NULL); 246 243 } 244 Characteristics = fh.Characteristics; 245 246 //save original base address of image 247 originalBaseAddress = oh.ImageBase; 247 248 248 249 imageSize = oh.SizeOfImage; … … 264 265 setFullPath(szFullPath); 265 266 } 267 268 //Use pointer to image header as module handle now. Some apps needs this 269 #ifdef COMMIT_ALL 270 commitPage(realBaseAddress, FALSE, SINGLE_PAGE); 271 #endif 272 hinstance = (HINSTANCE)realBaseAddress; 273 274 //Calculate address of optional header 275 poh = (PIMAGE_OPTIONAL_HEADER)OPTHEADEROFF(hinstance); 266 276 267 277 if(!(fh.Characteristics & IMAGE_FILE_EXECUTABLE_IMAGE)) {//not valid … … 373 383 continue; 374 384 } 375 if(IsSectionType(peview, &psh[i], IMAGE_DIRECTORY_ENTRY_DEBUG))376 {377 dprintf((LOG, ".rdebug" ));378 addSection(SECTION_DEBUG, psh[i].PointerToRawData,379 psh[i].SizeOfRawData, psh[i].VirtualAddress + oh.ImageBase,380 psh[i].Misc.VirtualSize, psh[i].Characteristics);381 continue;382 }383 385 if(IsSectionType(peview, &psh[i], IMAGE_DIRECTORY_ENTRY_IMPORT)) 384 386 { … … 406 408 continue; 407 409 } 410 /* bird: Do this test as late as possible since marking a section as debug 411 * because it the section will not be preloaded if marked SECTION_DEBUG 412 * causeing a lot of annoying page faults when all should be preloaded. 413 * A debug section may contain more than just the debug directory. 414 * 415 * IIRC the debug directory doesn't contain the debug info, it's a table telling 416 * raw file offsets of the different debug types. It's never been any custom of 417 * linkers to put debug info into loadable segments/sections/objects, so I've some 418 * difficulty seeing why we're doing this in the first place. 419 * 420 * Why aren't we just using a general approach, which trust the section flags and 421 * only precommits the tree directories we use (fixups/imports/exports)? 422 */ 423 if(IsSectionType(peview, &psh[i], IMAGE_DIRECTORY_ENTRY_DEBUG)) 424 { 425 dprintf((LOG, ".rdebug" )); 426 addSection(SECTION_DEBUG, psh[i].PointerToRawData, 427 psh[i].SizeOfRawData, psh[i].VirtualAddress + oh.ImageBase, 428 psh[i].Misc.VirtualSize, psh[i].Characteristics); 429 continue; 430 } 408 431 if(!(psh[i].Characteristics & IMAGE_SCN_MEM_WRITE)) { //read only data section 409 432 dprintf((LOG, "Read Only Data Section" )); … … 474 497 pFixups = (PIMAGE_BASE_RELOCATION)ImageDirectoryOffset(peview, IMAGE_DIRECTORY_ENTRY_BASERELOC); 475 498 dwFixupSize = ImageDirectorySize(peview, IMAGE_DIRECTORY_ENTRY_BASERELOC); 476 commitPage((ULONG)pFixups, FALSE); 477 } 478 479 //Use pointer to image header as module handle now. Some apps needs this 480 hinstance = (HINSTANCE)realBaseAddress; 499 /* commit complete section to avoid getting exceptions inside setFixups(). */ 500 commitPage((ULONG)pFixups, FALSE, COMPLETE_SECTION); 501 } 481 502 482 503 if(!(dwFlags & FLAG_PELDR_LOADASDATAFILE)) … … 811 832 } 812 833 if(fPageCmd == COMPLETE_SECTION && (section && section->type == SECTION_DEBUG)) {//ignore 834 #ifdef DEBUG 835 /* check for env. var. ODIN_PELDR_COMMIT_ALL, committing it anyway if that is set. */ 836 static int f = -1; 837 if (f == -1) 838 f = (getenv("ODIN_PELDR_COMMIT_ALL") != NULL); 839 if (!f) 840 #endif 813 841 return TRUE; 814 842 } … … 931 959 BOOL Win32PeLdrImage::allocSections(ULONG reservedMem) 932 960 { 933 APIRET rc;934 ULONG baseAddress;961 APIRET rc; 962 ULONG baseAddress; 935 963 936 964 realBaseAddress = 0; 937 965 938 966 //Allocated in by pe.exe 939 if(reservedMem && reservedMem == o h.ImageBase) {940 realBaseAddress = o h.ImageBase;967 if(reservedMem && reservedMem == originalBaseAddress) { 968 realBaseAddress = originalBaseAddress; 941 969 return TRUE; 942 970 } 943 971 944 972 //SvL: We don't care where the image is loaded for resource lookup 945 if( fh.Characteristics & IMAGE_FILE_RELOCS_STRIPPED && !(dwFlags & FLAG_PELDR_LOADASDATAFILE)) {973 if(Characteristics & IMAGE_FILE_RELOCS_STRIPPED && !(dwFlags & FLAG_PELDR_LOADASDATAFILE)) { 946 974 return allocFixedMem(reservedMem); 947 975 } … … 1029 1057 } 1030 1058 1031 if(o h.ImageBase< 512*1024*1024) {1059 if(originalBaseAddress < 512*1024*1024) { 1032 1060 fLowMemory = TRUE; 1033 1061 } … … 1037 1065 1038 1066 dprintf((LOG, "DosAllocMem returned %x", address )); 1039 if(address + FALLOC_SIZE >= o h.ImageBase) {1040 if(address > o h.ImageBase) {//we've passed it!1067 if(address + FALLOC_SIZE >= originalBaseAddress) { 1068 if(address > originalBaseAddress) {//we've passed it! 1041 1069 OSLibDosFreeMem((PVOID)address); 1042 1070 break; … … 1045 1073 OSLibDosFreeMem((PVOID)address); 1046 1074 1047 diff = o h.ImageBase- address;1075 diff = originalBaseAddress - address; 1048 1076 if(diff) { 1049 1077 rc = OSLibDosAllocMem((PPVOID)&address, diff, PAG_READ, fLowMemory); … … 1078 1106 // Process all the image sections 1079 1107 for(i=0;i<nrsections;i++) { 1080 section[i].realvirtaddr = realBaseAddress + (section[i].virtaddr - o h.ImageBase);1108 section[i].realvirtaddr = realBaseAddress + (section[i].virtaddr - originalBaseAddress); 1081 1109 } 1082 1110 … … 1128 1156 PIMAGE_BASE_RELOCATION prel = pFixups; 1129 1157 1130 if(realBaseAddress == o h.ImageBase || fh.Characteristics & IMAGE_FILE_RELOCS_STRIPPED) {1158 if(realBaseAddress == originalBaseAddress || Characteristics & IMAGE_FILE_RELOCS_STRIPPED) { 1131 1159 return(TRUE); 1132 1160 } … … 1226 1254 ULONG count; 1227 1255 1228 if( fh.Characteristics & IMAGE_FILE_RELOCS_STRIPPED) {1256 if(Characteristics & IMAGE_FILE_RELOCS_STRIPPED) { 1229 1257 return(TRUE); 1230 1258 } … … 1280 1308 fixup = (ULONG *)(fixupaddr + realBaseAddress); 1281 1309 orgaddr = *fixup; 1282 // dprintf((LOG, "AddOff32Fixup 0x%x org 0x%x -> new 0x%x", fixup, orgaddr, realBaseAddress + (*fixup - o h.ImageBase)));1283 *fixup = realBaseAddress + (*fixup - o h.ImageBase);1310 // dprintf((LOG, "AddOff32Fixup 0x%x org 0x%x -> new 0x%x", fixup, orgaddr, realBaseAddress + (*fixup - originalBaseAddress))); 1311 *fixup = realBaseAddress + (*fixup - originalBaseAddress); 1284 1312 } 1285 1313 //****************************************************************************** … … 1293 1321 orgaddr = *fixup; 1294 1322 if(fHighFixup) { 1295 *fixup += (USHORT)((realBaseAddress - o h.ImageBase) >> 16);1323 *fixup += (USHORT)((realBaseAddress - originalBaseAddress) >> 16); 1296 1324 // dprintf((LOG, "AddOff16FixupH 0x%x org 0x%x -> new 0x%x", fixup, orgaddr, *fixup)); 1297 1325 } 1298 1326 else { 1299 *fixup += (USHORT)((realBaseAddress - o h.ImageBase) & 0xFFFF);1327 *fixup += (USHORT)((realBaseAddress - originalBaseAddress) & 0xFFFF); 1300 1328 // dprintf((LOG, "AddOff16FixupL 0x%x org 0x%x -> new 0x%x", fixup, orgaddr, *fixup)); 1301 1329 } … … 1339 1367 char *code = (char *)_cmalloc(sizeof(missingapicode)); 1340 1368 1369 #ifdef DEBUG 1370 MissingApiOrd(WinImage->getModuleName(), getModuleName(), ordinal); 1371 #endif 1341 1372 memcpy(code, missingapicode, sizeof(missingapicode)); 1342 1373 *(DWORD *)&code[MISSINGOFFSET_PUSHIMPORTIMAGE] = (DWORD)getModuleName(); … … 1367 1398 char *code = (char *)_cmalloc(sizeof(missingapicode)); 1368 1399 1400 #ifdef DEBUG 1401 MissingApiName(WinImage->getModuleName(), getModuleName(), impname); 1402 #endif 1403 1369 1404 memcpy(code, missingapicode, sizeof(missingapicode)); 1370 1405 *(DWORD *)&code[MISSINGOFFSET_PUSHIMPORTIMAGE] = (DWORD)getModuleName(); … … 1400 1435 if((ped = (PIMAGE_EXPORT_DIRECTORY)ImageDirectoryOffset 1401 1436 (peview, IMAGE_DIRECTORY_ENTRY_EXPORT)) != NULL && 1402 GetSectionHdrByImageDir(peview, IMAGE_DIRECTORY_ENTRY_EXPORT, &sh) ) 1437 GetSectionHdrByImageDir(peview, IMAGE_DIRECTORY_ENTRY_EXPORT, &sh) ) 1403 1438 { 1404 1439 … … 1410 1445 ptrAddress = (ULONG *)((ULONG)ped->AddressOfFunctions + 1411 1446 (ULONG)peview); 1412 nrOrdExports = ped->NumberOfFunctions;1413 nrNameExports = ped->NumberOfNames;1447 int nrOrdExports = ped->NumberOfFunctions; 1448 int nrNameExports = ped->NumberOfNames; 1414 1449 1415 1450 int ord, RVAExport; … … 1423 1458 1424 1459 /* forwarder? ulRVA within export directory. */ 1425 if(RVAExport > oh.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].VirtualAddress &&1426 RVAExport < oh.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].VirtualAddress1427 + oh.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].Size)1460 if(RVAExport > poh->DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].VirtualAddress && 1461 RVAExport < poh->DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].VirtualAddress 1462 + poh->DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].Size) 1428 1463 { 1429 fForwarder = AddForwarder(oh.ImageBase+ RVAExport, name, ord);1464 fForwarder = loadForwarder(originalBaseAddress + RVAExport, name, ord); 1430 1465 } 1431 1466 if(!fForwarder) { 1432 //points to code (virtual address relative to oh.ImageBase 1433 AddNameExport(oh.ImageBase + RVAExport, name, ord); 1467 //points to code (virtual address relative to originalBaseAddress 1434 1468 dprintf((LOG, "address 0x%x %s @%d (0x%08x)", RVAExport, name, ord, realBaseAddress + RVAExport)); 1435 1469 } … … 1441 1475 RVAExport = ptrAddress[i]; 1442 1476 /* forwarder? ulRVA within export directory. */ 1443 if(RVAExport > oh.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].VirtualAddress &&1444 RVAExport < oh.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].VirtualAddress1445 + oh.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].Size)1477 if(RVAExport > poh->DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].VirtualAddress && 1478 RVAExport < poh->DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].VirtualAddress 1479 + poh->DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].Size) 1446 1480 { 1447 fForwarder = AddForwarder(oh.ImageBase+ RVAExport, NULL, ord);1481 fForwarder = loadForwarder(originalBaseAddress + RVAExport, NULL, ord); 1448 1482 } 1449 1483 if(!fForwarder && RVAExport) { 1450 //points to code (virtual address relative to o h.ImageBase1484 //points to code (virtual address relative to originalBaseAddress 1451 1485 dprintf((LOG, "ord %d at 0x%08x (0x%08x)", ord, RVAExport, realBaseAddress + RVAExport)); 1452 AddOrdExport(oh.ImageBase + RVAExport, ord);1453 1486 } 1454 1487 } … … 1465 1498 //****************************************************************************** 1466 1499 //****************************************************************************** 1467 void Win32PeLdrImage::AddNameExport(ULONG virtaddr, char *apiname, ULONG ordinal, BOOL fAbsoluteAddress) 1468 { 1469 ULONG nsize; 1470 int iApiNameLength = strlen(apiname); 1471 1472 if(nameexports == NULL) { 1473 // think of a maximum of bytes per export name, 1474 // verify if this is true for MFC-DLLs, etc. 1475 nameExportSize = nrNameExports * (sizeof(NameExport) + 32); 1476 1477 nameexports = (NameExport *)malloc(nameExportSize); 1478 curnameexport = nameexports; 1479 } 1480 nsize = (ULONG)curnameexport - (ULONG)nameexports; 1481 if(nsize + sizeof(NameExport) + iApiNameLength > nameExportSize) { 1482 nameExportSize += 4096; 1483 char *tmp = (char *)nameexports; 1484 nameexports = (NameExport *)malloc(nameExportSize); 1485 memcpy(nameexports, tmp, nsize); 1486 curnameexport = (NameExport *)((ULONG)nameexports + nsize); 1487 free(tmp); 1488 } 1489 if(fAbsoluteAddress) {//forwarders use absolute address 1490 curnameexport->virtaddr = virtaddr; 1491 } 1492 else curnameexport->virtaddr = realBaseAddress + (virtaddr - oh.ImageBase); 1493 curnameexport->ordinal = ordinal; 1494 *(ULONG *)curnameexport->name = 0; 1495 1496 curnameexport->nlength = iApiNameLength + 1; 1497 memcpy(curnameexport->name, apiname, curnameexport->nlength); 1498 1499 if(curnameexport->nlength < sizeof(curnameexport->name)) 1500 curnameexport->nlength = sizeof(curnameexport->name); 1501 1502 curnameexport = (NameExport *)((ULONG)curnameexport->name + curnameexport->nlength); 1503 } 1504 //****************************************************************************** 1505 //****************************************************************************** 1506 void Win32PeLdrImage::AddOrdExport(ULONG virtaddr, ULONG ordinal, BOOL fAbsoluteAddress) 1507 { 1508 if(ordexports == NULL) { 1509 ordexports = (OrdExport *)malloc(nrOrdExports * sizeof(OrdExport)); 1510 curordexport = ordexports; 1511 } 1512 if(fAbsoluteAddress) {//forwarders use absolute address 1513 curordexport->virtaddr = virtaddr; 1514 } 1515 else curordexport->virtaddr = realBaseAddress + (virtaddr - oh.ImageBase); 1516 1517 curordexport->ordinal = ordinal; 1518 curordexport++; 1519 nrOrdExportsRegistered++; 1520 } 1521 //****************************************************************************** 1522 //****************************************************************************** 1523 BOOL Win32PeLdrImage::AddForwarder(ULONG virtaddr, char *apiname, ULONG ordinal) 1524 { 1525 char *forward = (char *)(realBaseAddress + (virtaddr - oh.ImageBase)); 1500 BOOL Win32PeLdrImage::loadForwarder(ULONG virtaddr, char *apiname, ULONG ordinal) 1501 { 1502 char *forward = (char *)(realBaseAddress + (virtaddr - originalBaseAddress)); 1526 1503 char *forwarddll, *forwardapi; 1527 1504 Win32DllBase *WinDll; … … 1569 1546 1570 1547 if(apiname) { 1571 dprintf((LOG, "address 0x%x %s @%d (0x%08x) forwarder %s.%s", virtaddr - oh.ImageBase, apiname, ordinal, virtaddr, forwarddll, forwardapi)); 1572 AddNameExport(exportaddr, apiname, ordinal, TRUE); 1548 dprintf((LOG, "address 0x%x %s @%d (0x%08x->0x%08x) forwarder %s.%s", virtaddr - originalBaseAddress, apiname, ordinal, virtaddr, exportaddr, forwarddll, forwardapi)); 1573 1549 } 1574 1550 else { 1575 dprintf((LOG, "address 0x%x @%d (0x%08x) forwarder %s.%s", virtaddr - oh.ImageBase, ordinal, virtaddr, forwarddll, forwardapi)); 1576 AddOrdExport(exportaddr, ordinal, TRUE); 1577 } 1578 return TRUE; 1551 dprintf((LOG, "address 0x%x @%d (0x%08x->0x%08x) forwarder %s.%s", virtaddr - originalBaseAddress, ordinal, virtaddr, exportaddr, forwarddll, forwardapi)); 1552 } 1553 return (exportaddr != 0); 1579 1554 } 1580 1555 //****************************************************************************** … … 1606 1581 ULONG hInstanceNewDll; 1607 1582 1608 char *dot = strchr(modname, '.');1609 if(dot == NULL) {1610 strcat(modname, DLL_EXTENSION);1611 }1612 1583 rc = DosLoadModule(szModuleFailure, sizeof(szModuleFailure), modname, (HMODULE *)&hInstanceNewDll); 1613 1584 if(rc) { … … 1688 1659 IMAGE_SECTION_HEADER shID; 1689 1660 IMAGE_SECTION_HEADER shExtra = {0}; 1690 PIMAGE_OPTIONAL_HEADER pOH;1691 1661 int i,j, nrPages; 1692 1662 BOOL fBorland = 0; … … 1778 1748 /* 2) functions */ 1779 1749 pszCurModule = pszModules; 1780 pOH = (PIMAGE_OPTIONAL_HEADER)OPTHEADEROFF(peview);1781 1750 for (i = 0; i < cModules; i++) 1782 1751 { … … 1792 1761 (ULONG)pID[i].u.OriginalFirstThunk < shID.VirtualAddress || 1793 1762 (ULONG)pID[i].u.OriginalFirstThunk >= shID.VirtualAddress + max(shID.Misc.VirtualSize, shID.SizeOfRawData) || 1794 (ULONG)pID[i].u.OriginalFirstThunk >= p OH->DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].VirtualAddress &&1795 (ULONG)pID[i].u.OriginalFirstThunk < sizeof(*pID)*cModules + p OH->DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].VirtualAddress)1763 (ULONG)pID[i].u.OriginalFirstThunk >= poh->DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].VirtualAddress && 1764 (ULONG)pID[i].u.OriginalFirstThunk < sizeof(*pID)*cModules + poh->DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].VirtualAddress) 1796 1765 { 1797 1766 fBorland = TRUE; … … 1805 1774 1806 1775 // b) check if RVA ok 1807 if (!(pulImport > 0 && (ULONG)pulImport < p OH->SizeOfImage)) {1776 if (!(pulImport > 0 && (ULONG)pulImport < poh->SizeOfImage)) { 1808 1777 dprintf((LOG, "Invalid RVA %x", pulImport )); 1809 1778 break; … … 1831 1800 } 1832 1801 else { 1802 1833 1803 WinDll = loadDll(pszCurModule); 1834 1804 if(WinDll == NULL) { … … 1901 1871 } 1902 1872 //SvL: And restore original protection flags 1903 ulCurFixup = (ULONG)pID[i].FirstThunk + p OH->ImageBase;1873 ulCurFixup = (ULONG)pID[i].FirstThunk + poh->ImageBase; 1904 1874 DosSetMem((PVOID)(ulCurFixup & ~0xfff), PAGE_SIZE*nrPages, section->pageflags); 1905 1875 … … 1940 1910 } 1941 1911 //****************************************************************************** 1942 //******************************************************************************1943 NameExport *Win32PeLdrImage::findApi(char *name)1944 {1945 ULONG apiaddr, i, apilen;1946 char *apiname;1947 char tmp[4];1948 NameExport *curexport;1949 ULONG ulAPIOrdinal; /* api requested by ordinal */1950 1951 apilen = strlen(name) + 1;1952 if(apilen < 4)1953 {1954 *(ULONG *)tmp = 0;1955 strcpy(tmp, name);1956 apiname = tmp;1957 apilen = 4;1958 }1959 else apiname = name;1960 1961 curexport = nameexports;1962 for(i=0; i<nrNameExports; i++)1963 {1964 if(apilen == curexport->nlength &&1965 *(ULONG *)curexport->name == *(ULONG *)apiname)1966 {1967 if(strcmp(curexport->name, apiname) == 0)1968 return curexport;1969 }1970 curexport = (NameExport *)((ULONG)curexport->name + curexport->nlength);1971 }1972 return NULL;1973 }1974 //******************************************************************************1975 //******************************************************************************1976 ULONG Win32PeLdrImage::getApi(char *name)1977 {1978 NameExport *curexport;1979 1980 curexport = findApi(name);1981 if(curexport) {1982 return(curexport->virtaddr);1983 }1984 return 0;1985 }1986 //******************************************************************************1987 //Override a name export1988 //******************************************************************************1989 ULONG Win32PeLdrImage::setApi(char *name, ULONG pfnNewProc)1990 {1991 NameExport *curexport;1992 1993 curexport = findApi(name);1994 if(curexport) {1995 ULONG pfnOldProc = curexport->virtaddr;1996 1997 curexport->virtaddr = pfnNewProc;1998 return pfnOldProc;1999 }2000 return -1;2001 }2002 //******************************************************************************2003 //******************************************************************************2004 OrdExport *Win32PeLdrImage::findApi(int ordinal)2005 {2006 ULONG apiaddr, i;2007 OrdExport *curexport;2008 2009 curexport = ordexports;2010 2011 /* accelerated resolving of ordinal exports2012 * is based on the assumption the ordinal export2013 * table is always sorted ascending.2014 *2015 * When the step size is too small, we continue2016 * with the linear search.2017 */2018 2019 // start in the middle of the tree2020 i = nrOrdExportsRegistered >> 1;2021 int iStep = i;2022 2023 for(;;)2024 {2025 int iThisExport = curexport[i].ordinal;2026 2027 iStep >>= 1; // next step will be narrower2028 2029 if (iThisExport < ordinal)2030 i += min(iStep, (ordinal-iThisExport)); // move farther down the list2031 else2032 if (iThisExport == ordinal) // found the export?2033 return &curexport[i];2034 else2035 i -= min(iStep, (iThisExport-ordinal)); // move farther up the list2036 2037 // if we're in the direct neighbourhood search linearly2038 if (iStep <= 1)2039 {2040 // decide if we're to search backward or forward2041 if (ordinal > curexport[i].ordinal)2042 {2043 // As a certain number of exports are 0 at the end2044 // of the array, this case will hit fairly often.2045 // the last comparison will send the loop off into the2046 // wrong direction!2047 #ifdef DEBUG2048 if (curexport[i].ordinal == 0)2049 {2050 DebugInt3();2051 }2052 #endif2053 2054 for (;i<nrOrdExports;i++) // scan forward2055 {2056 iThisExport = curexport[i].ordinal;2057 if(iThisExport == ordinal)2058 return &curexport[i];2059 else2060 if (iThisExport > ordinal)2061 {2062 // Oops, cannot find the ordinal in the sorted list2063 break;2064 }2065 }2066 }2067 else2068 {2069 for (;i>=0;i--) // scan backward2070 {2071 iThisExport = curexport[i].ordinal;2072 if(curexport[i].ordinal == ordinal)2073 return &curexport[i];2074 else2075 if (iThisExport < ordinal)2076 // Oops, cannot find the ordinal in the sorted list2077 break;2078 }2079 }2080 2081 // not found yet.2082 break;2083 }2084 }2085 return NULL;2086 }2087 //******************************************************************************2088 //******************************************************************************2089 ULONG Win32PeLdrImage::getApi(int ordinal)2090 {2091 OrdExport *curexport;2092 NameExport *nexport;2093 2094 curexport = findApi(ordinal);2095 if(curexport) {2096 return curexport->virtaddr;2097 }2098 2099 //Name exports also contain an ordinal, so check this2100 nexport = nameexports;2101 for(int i=0;i<nrNameExports;i++) {2102 if(nexport->ordinal == ordinal)2103 return(nexport->virtaddr);2104 2105 nexport = (NameExport *)((ULONG)nexport->name + nexport->nlength);2106 }2107 return(0);2108 }2109 //******************************************************************************2110 //Override an ordinal export2111 //******************************************************************************2112 ULONG Win32PeLdrImage::setApi(int ordinal, ULONG pfnNewProc)2113 {2114 OrdExport *curexport;2115 NameExport *nexport;2116 2117 curexport = findApi(ordinal);2118 if(curexport) {2119 ULONG pfnOldProc = curexport->virtaddr;2120 2121 curexport->virtaddr = pfnNewProc;2122 return pfnOldProc;2123 }2124 2125 //Name exports also contain an ordinal, so check this2126 nexport = nameexports;2127 for(int i=0;i<nrNameExports;i++)2128 {2129 if(nexport->ordinal == ordinal) {2130 ULONG pfnOldProc = nexport->virtaddr;2131 2132 nexport->virtaddr = pfnNewProc;2133 return pfnOldProc;2134 }2135 2136 nexport = (NameExport *)((ULONG)nexport->name + nexport->nlength);2137 }2138 return -1;2139 }2140 //******************************************************************************2141 1912 //Returns required OS version for this image 2142 1913 //****************************************************************************** 2143 1914 ULONG Win32PeLdrImage::getVersion() 2144 1915 { 2145 return ( oh.MajorOperatingSystemVersion << 16) | oh.MinorOperatingSystemVersion;1916 return (poh->MajorOperatingSystemVersion << 16) | poh->MinorOperatingSystemVersion; 2146 1917 } 2147 1918 //******************************************************************************
Note:
See TracChangeset
for help on using the changeset viewer.