- Timestamp:
- Jan 15, 2004, 11:39:15 AM (22 years ago)
- Location:
- trunk/src/kernel32
- Files:
-
- 20 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/kernel32/windllbase.cpp
r10054 r10397 1 /* $Id: windllbase.cpp,v 1.3 3 2003-04-30 11:04:07sandervl Exp $ */1 /* $Id: windllbase.cpp,v 1.34 2004-01-15 10:39:06 sandervl Exp $ */ 2 2 3 3 /* … … 5 5 * 6 6 * Copyright 1998-2000 Sander van Leeuwen (sandervl@xs4all.nl) 7 * Copyright 2003 Innotek Systemberatung GmbH (sandervl@innotek.de) 7 8 * 8 9 * Unloading of a dll always happens in order of dependency (taking nr of … … 438 439 #ifdef DEBUG 439 440 time2 = GetTickCount(); 440 dprintf(("attachProcess to dll %s DONE in %x msec ", szModule, time2-time1));441 dprintf(("attachProcess to dll %s DONE in %x msec rc %d", szModule, time2-time1, rc)); 441 442 #endif 442 443 … … 883 884 //****************************************************************************** 884 885 //****************************************************************************** 886 int Win32DllBase::enumDlls(HMODULE *lphModule, int countMax) 887 { 888 int count = 0; 889 HMODULE hModule; 890 891 dlllistmutex.enter(); 892 893 Win32DllBase *mod = Win32DllBase::head; 894 while(mod != NULL) { 895 dbgCheckObj(mod); 896 897 hModule = mod->getInstanceHandle(); 898 if ( count < countMax ) 899 lphModule[count] = hModule; 900 count++; 901 902 mod = mod->next; 903 } 904 dlllistmutex.leave(); 905 return count; 906 } 907 //****************************************************************************** 908 //****************************************************************************** 885 909 Win32DllBase *Win32DllBase::head = NULL; 886 910 Queue Win32DllBase::loadLibDlls; -
trunk/src/kernel32/windllbase.h
r8923 r10397 1 /* $Id: windllbase.h,v 1.1 0 2002-07-26 10:48:40sandervl Exp $ */1 /* $Id: windllbase.h,v 1.11 2004-01-15 10:39:06 sandervl Exp $ */ 2 2 3 3 /* … … 86 86 BOOL isDynamicLib() { return nrDynamicLibRef != 0; }; 87 87 88 WIN32DLLENTRY getEntryPoint() { return dllEntryPoint; }; 89 88 90 void setUnloadOrder(Win32ImageBase *parent); 89 91 … … 114 116 static Win32DllBase *findModuleByAddr(ULONG address); 115 117 static Win32DllBase *findModuleByOS2Handle(HINSTANCE hinstance); 118 119 static int enumDlls(HMODULE *lphModule, int countMax); 116 120 117 121 #ifdef DEBUG -
trunk/src/kernel32/windlllx.cpp
r10304 r10397 1 /* $Id: windlllx.cpp,v 1.2 8 2003-10-28 10:42:40sandervl Exp $ */1 /* $Id: windlllx.cpp,v 1.29 2004-01-15 10:39:07 sandervl Exp $ */ 2 2 3 3 /* … … 5 5 * 6 6 * Copyright 1999-2000 Sander van Leeuwen (sandervl@xs4all.nl) 7 * Copyright 2003 Innotek Systemberatung GmbH (sandervl@innotek.de) 7 8 * 8 9 * TODO: Unloading of dlls probably needs to be fixed due to OS/2 bug … … 45 46 *******************************************************************************/ 46 47 char *lpszCustomDllName = NULL; 47 char *lpszCustomExportPrefix = NULL; 48 ULONG dwOrdinalBase = 0; 48 PIMAGE_FILE_HEADER lpCustomDllPEHdr = NULL; 49 49 50 50 /** … … 57 57 //****************************************************************************** 58 58 //****************************************************************************** 59 void WIN32API SetCustomBuildName(char *lpszName, PIMAGE_FILE_HEADER pfh) 60 59 void WIN32API SetCustomBuildName(char *lpszName, PIMAGE_FILE_HEADER pfh) 61 60 { 62 61 lpszCustomDllName = lpszName; 62 lpCustomDllPEHdr = pfh; 63 63 } 64 64 //****************************************************************************** … … 101 101 } 102 102 } 103 else { 104 //make sure this dll hasn't already been loaded 105 if(Win32DllBase::findModule(lpszCustomDllName) != NULL) { 106 dprintf(("ERROR: RegisterLxDll: module %s already loaded!!", lpszCustomDllName)); 107 DebugInt3(); 108 return 0; 109 } 110 } 103 111 windll = new Win32LxDll(hInstance, EntryPoint, pResData, MajorImageVersion, 104 112 MinorImageVersion, Subsystem); … … 109 117 //clear name override in case dll init loads another dll 110 118 lpszCustomDllName = NULL; 119 lpCustomDllPEHdr = NULL; 111 120 112 121 if(!fPeLoader) { -
trunk/src/kernel32/windlllx.h
r9411 r10397 1 /* $Id: windlllx.h,v 1. 8 2002-11-18 13:53:54sandervl Exp $ */1 /* $Id: windlllx.h,v 1.9 2004-01-15 10:39:07 sandervl Exp $ */ 2 2 3 3 /* … … 47 47 }; 48 48 49 extern char *lpszCustomDllName , *lpszCustomExportPrefix;50 extern DWORD dwOrdinalBase;49 extern char *lpszCustomDllName; 50 extern PIMAGE_FILE_HEADER lpCustomDllPEHdr; 51 51 52 52 #endif //__WINDLLLX_H__ -
trunk/src/kernel32/windllpe2lx.cpp
r9963 r10397 1 /* $Id: windllpe2lx.cpp,v 1.1 4 2003-03-31 11:54:28 sandervl Exp $ */1 /* $Id: windllpe2lx.cpp,v 1.15 2004-01-15 10:39:08 sandervl Exp $ */ 2 2 3 3 /* -
trunk/src/kernel32/windllpe2lx.h
r9963 r10397 1 /* $Id: windllpe2lx.h,v 1. 3 2003-03-31 11:54:28 sandervl Exp $ */1 /* $Id: windllpe2lx.h,v 1.4 2004-01-15 10:39:08 sandervl Exp $ */ 2 2 3 3 /* -
trunk/src/kernel32/windllpeldr.cpp
r9975 r10397 1 /* $Id: windllpeldr.cpp,v 1.1 2 2003-04-02 12:58:31sandervl Exp $ */1 /* $Id: windllpeldr.cpp,v 1.13 2004-01-15 10:39:08 sandervl Exp $ */ 2 2 3 3 /* … … 5 5 * 6 6 * Copyright 1999 Sander van Leeuwen (sandervl@xs4all.nl) 7 * Copyright 2003 Innotek Systemberatung GmbH (sandervl@innotek.de) 7 8 * 8 9 * … … 83 84 dllEntryPoint = (WIN32DLLENTRY)entryPoint; 84 85 85 if(!( fh.Characteristics & IMAGE_FILE_DLL)) {86 if(!(Characteristics & IMAGE_FILE_DLL)) { 86 87 //executable loaded as dll; don't call entrypoint 87 88 dprintf(("WARNING: Exe %s loaded as dll; entrypoint not called", szFileName)); -
trunk/src/kernel32/windllpeldr.h
r9975 r10397 1 /* $Id: windllpeldr.h,v 1. 4 2003-04-02 12:58:31sandervl Exp $ */1 /* $Id: windllpeldr.h,v 1.5 2004-01-15 10:39:09 sandervl Exp $ */ 2 2 3 3 /* -
trunk/src/kernel32/winexedummy.cpp
r10386 r10397 1 /* $Id: winexedummy.cpp,v 1. 5 2004-01-12 17:27:28sandervl Exp $ */1 /* $Id: winexedummy.cpp,v 1.6 2004-01-15 10:39:09 sandervl Exp $ */ 2 2 3 3 /* -
trunk/src/kernel32/winexelx.cpp
r9800 r10397 1 /* $Id: winexelx.cpp,v 1.1 2 2003-02-13 15:30:53sandervl Exp $ */1 /* $Id: winexelx.cpp,v 1.13 2004-01-15 10:39:10 sandervl Exp $ */ 2 2 3 3 /* -
trunk/src/kernel32/winexepe2lx.cpp
r9540 r10397 1 /* $Id: winexepe2lx.cpp,v 1.1 3 2002-12-20 12:40:43sandervl Exp $ */1 /* $Id: winexepe2lx.cpp,v 1.14 2004-01-15 10:39:10 sandervl Exp $ */ 2 2 3 3 /* -
trunk/src/kernel32/winexepeldr.cpp
r9780 r10397 1 /* $Id: winexepeldr.cpp,v 1.2 3 2003-02-10 16:05:39sandervl Exp $ */1 /* $Id: winexepeldr.cpp,v 1.24 2004-01-15 10:39:10 sandervl Exp $ */ 2 2 3 3 /* … … 184 184 //Note: MUST use 128kb as a minimum. Or else the workarounds for out of 185 185 // stack space in 16 bits code (thread entrypoint) might fail. 186 return ( oh.SizeOfStackReserve > 128*1024) ? oh.SizeOfStackReserve : 128*1024;186 return (poh->SizeOfStackReserve > 128*1024) ? poh->SizeOfStackReserve : 128*1024; 187 187 } 188 188 //****************************************************************************** -
trunk/src/kernel32/winimagebase.cpp
r9617 r10397 1 /* $Id: winimagebase.cpp,v 1.3 6 2003-01-05 12:31:25sandervl Exp $ */1 /* $Id: winimagebase.cpp,v 1.37 2004-01-15 10:39:11 sandervl Exp $ */ 2 2 3 3 /* … … 6 6 * Copyright 1998-1999 Sander van Leeuwen (sandervl@xs4all.nl) 7 7 * Copyright 1998-2000 knut st. osmundsen (knut.stange.osmundsen@mynd.no) 8 * Copyright 2003 Innotek Systemberatung GmbH (sandervl@innotek.de) 8 9 * 9 10 * Project Odin Software License can be found in LICENSE.TXT … … 48 49 errorState(NO_ERROR), entryPoint(0), fullpath(NULL), 49 50 tlsAddress(0), tlsIndexAddr(0), tlsInitSize(0), tlsTotalSize(0), 50 tlsCallBackAddr(0), tlsIndex(-1), pResRootDir(NULL), 51 ulRVAResourceSection(0), fIsPEImage(FALSE) 51 tlsCallBackAddr(0), tlsIndex(-1), pResRootDir(NULL), poh(NULL), 52 ulRVAResourceSection(0), fIsPEImage(FALSE), pExportDir(NULL) 52 53 { 53 54 char *name; … … 153 154 } 154 155 //****************************************************************************** 156 // 157 // Win32ImageBase::findApi: find function in export table and change if necessary 158 // 159 // Parameters: 160 // char *name - function name (NULL for ordinal search) 161 // int ordinal - function ordinal (only used if name == NULL) 162 // ULONG pfnNewProc - new function address (ignored if 0) 163 // 164 // Returns: 165 // 0 - not found 166 // <>0 - function address 167 // 168 //****************************************************************************** 169 ULONG Win32ImageBase::findApi(char *pszName, ULONG ulOrdinal, ULONG pfnNewProc) 170 { 171 PIMAGE_EXPORT_DIRECTORY ped = pExportDir; 172 173 /* 174 * Get ped if it's NULL. 175 */ 176 if (!ped) 177 { 178 if (!poh->DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].VirtualAddress) 179 return 0; 180 ped = (PIMAGE_EXPORT_DIRECTORY)getPointerFromRVA(poh->DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].VirtualAddress); 181 pExportDir = ped; 182 } 183 184 int iExpOrdinal = 0; /* index into address table. */ 185 if (pszName) 186 { 187 /* 188 * Find Named Export: Do binary search on the name table. 189 */ 190 const char**paRVANames = (const char **)getPointerFromRVA(ped->AddressOfNames); 191 PUSHORT paOrdinals = (PUSHORT)getPointerFromRVA(ped->AddressOfNameOrdinals); 192 int iStart = 1; 193 int iEnd = ped->NumberOfNames; 194 195 for (;;) 196 { 197 /* end of search? */ 198 if (iStart > iEnd) 199 { 200 #ifdef DEBUG 201 /* do a linear search just to verify the correctness of the above algorithm */ 202 for (int i = 0; i < ped->NumberOfNames; i++) 203 if (!strcmp(paRVANames[i - 1] + (unsigned)hinstance, pszName)) 204 { 205 dprintf(("bug in binary export search!!!\n")); 206 DebugInt3(); 207 } 208 #endif 209 return 0; 210 } 211 212 int i = (iEnd - iStart) / 2 + iStart; 213 const char *pszExpName = (const char *)getPointerFromRVA(paRVANames[i - 1]); 214 int diff = strcmp(pszExpName, pszName); 215 if (diff > 0) /* pszExpName > pszName: search chunck before i */ 216 iEnd = i - 1; 217 else if (diff) /* pszExpName < pszName: search chunk after i */ 218 iStart = i + 1; 219 else /* pszExpName == pszName */ 220 { 221 iExpOrdinal = paOrdinals[i - 1]; 222 break; 223 } 224 } /* binary search thru name table */ 225 } 226 else 227 { 228 /* 229 * Find ordinal export: Simple table lookup. 230 */ 231 if ( ulOrdinal >= ped->Base + max(ped->NumberOfNames, ped->NumberOfFunctions) 232 || ulOrdinal < ped->Base) 233 return NULL; 234 iExpOrdinal = ulOrdinal - ped->Base; 235 } 236 237 /* 238 * Found export (iExpOrdinal). 239 */ 240 PULONG paAddress = (PULONG)getPointerFromRVA(ped->AddressOfFunctions); 241 unsigned uRVAExport = paAddress[iExpOrdinal]; 242 unsigned uRet; 243 244 /* Install override for the export (if requested) */ 245 if (pfnNewProc && uRet) 246 paAddress[iExpOrdinal] = getRVAFromPointer((void*)pfnNewProc, TRUE); 247 248 if ( uRVAExport > poh->DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].VirtualAddress 249 && uRVAExport < poh->DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].VirtualAddress 250 + poh->DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].Size) 251 /* Resolve forwarder. */ 252 uRet = findForwarder(poh->ImageBase + uRVAExport, pszName, iExpOrdinal); 253 else 254 /* Get plain export address */ 255 uRet = (ULONG)getPointerFromRVA(uRVAExport, TRUE); 256 257 return uRet; 258 } 259 //****************************************************************************** 260 //****************************************************************************** 261 ULONG Win32ImageBase::findForwarder(ULONG virtaddr, char *apiname, ULONG ordinal) 262 { 263 char *forward; 264 char *forwarddll, *forwardapi; 265 Win32DllBase *WinDll; 266 DWORD exportaddr; 267 int forwardord; 268 int iForwardDllLength; 269 int iForwardApiLength; 270 271 forward = (char *)(hinstance + (virtaddr - poh->ImageBase)); 272 iForwardDllLength = strlen(forward); 273 274 if(iForwardDllLength == 0) 275 return 0; 276 277 forwarddll = (char*)alloca(iForwardDllLength); 278 if(forwarddll == NULL) { 279 DebugInt3(); 280 return 0; 281 } 282 memcpy(forwarddll, forward, iForwardDllLength + 1); 283 284 forwardapi = strchr(forwarddll, '.'); 285 if(forwardapi == NULL) { 286 return 0; 287 } 288 *forwardapi++ = 0; 289 iForwardApiLength = strlen(forwardapi); 290 if(iForwardApiLength == 0) { 291 return FALSE; 292 } 293 WinDll = Win32DllBase::findModule(forwarddll); 294 if(WinDll == NULL) { 295 return 0; 296 } 297 //check if name or ordinal forwarder 298 forwardord = 0; 299 if(*forwardapi >= '0' && *forwardapi <= '9') { 300 forwardord = atoi(forwardapi); 301 } 302 if(forwardord != 0 || (iForwardApiLength == 1 && *forwardapi == '0')) { 303 exportaddr = WinDll->getApi(forwardord); 304 } 305 else exportaddr = WinDll->getApi(forwardapi); 306 307 return exportaddr; 308 } 309 //****************************************************************************** 155 310 //****************************************************************************** 156 311 ULONG Win32ImageBase::setApi(char *name, ULONG pfnNewProc) 157 312 { 158 return -1; //only implemented for PE modules313 return findApi(name, 0, pfnNewProc); 159 314 } 160 315 //****************************************************************************** … … 162 317 ULONG Win32ImageBase::setApi(int ordinal, ULONG pfnNewProc) 163 318 { 164 return -1; //only implemented for PE modules 319 return findApi(NULL, ordinal, pfnNewProc); 320 } 321 //****************************************************************************** 322 //****************************************************************************** 323 ULONG Win32ImageBase::getApi(char *name) 324 { 325 return findApi(name, 0); 326 } 327 //****************************************************************************** 328 //****************************************************************************** 329 ULONG Win32ImageBase::getApi(int ordinal) 330 { 331 return findApi(NULL, ordinal); 165 332 } 166 333 //****************************************************************************** … … 227 394 //the Characteristics member of the file header structure) 228 395 //****************************************************************************** 229 ULONG Win32ImageBase::isPEImage(char *szFileName, DWORD *Characteristics, 396 ULONG Win32ImageBase::isPEImage(char *szFileName, DWORD *Characteristics, 230 397 DWORD *subsystem, DWORD *fNEExe) 231 398 { … … 243 410 int nSections, i; 244 411 245 if(fNEExe) 412 if(fNEExe) 246 413 *fNEExe = FALSE; 247 414 … … 306 473 } 307 474 308 if(GetPEFileHeader (win32file, &fh) == FALSE) 475 if(GetPEFileHeader (win32file, &fh) == FALSE) 309 476 { 310 477 if(*(WORD *)PE_HEADER(win32file) == IMAGE_OS2_SIGNATURE) { 311 if(fNEExe) 478 if(fNEExe) 312 479 *fNEExe = TRUE; 313 480 } … … 334 501 *subsystem = oh.Subsystem; 335 502 } 336 503 337 504 free(win32file); 338 505 DosClose(win32handle); … … 414 581 return stricmp(pszModName, szModule) == 0; 415 582 } 583 584 /** Converts a RVA to an pointer into the loaded image. 585 * @returns Pointer corresponding to the RVA. 586 * @param ulRVA RVA to make a pointer. 587 * @param fOverride Flags if the RVA might be to an overridden address (export). 588 */ 589 void *Win32ImageBase::getPointerFromRVA(ULONG ulRVA, BOOL fOverride/* = FALSE*/) 590 { 591 return (PVOID)((char*)hinstance + ulRVA); 592 } 593 594 /** Converts a pointer to an RVA for the loaded image. 595 * @returns Pointer corresponding to the RVA. 596 * @param ulRVA RVA to make a pointer. 597 * @param fOverride Flags if the pointer might be to an overridden address (export). 598 */ 599 ULONG Win32ImageBase::getRVAFromPointer(void *pv, BOOL fOverride/* = FALSE*/) 600 { 601 return (ULONG)pv - (ULONG)hinstance; 602 } 603 -
trunk/src/kernel32/winimagebase.h
r9617 r10397 1 /* $Id: winimagebase.h,v 1.2 3 2003-01-05 12:31:25sandervl Exp $ */1 /* $Id: winimagebase.h,v 1.24 2004-01-15 10:39:11 sandervl Exp $ */ 2 2 3 3 /* … … 110 110 virtual BOOL insideModuleCode(ULONG address); 111 111 112 virtual ULONG getApi(char *name) = 0;113 virtual ULONG getApi(int ordinal) = 0;112 virtual ULONG getApi(char *name); 113 virtual ULONG getApi(int ordinal); 114 114 115 115 virtual ULONG setApi(char *name, ULONG pfnNewProc); … … 132 132 void tlsAlloc(); //Allocate TLS index for this module 133 133 void tlsDelete(); //Destroy TLS index for this module 134 135 ULONG findApi(char *pszName, ULONG ulOrdinal, ULONG pfnNewProc = NULL); 136 ULONG findForwarder(ULONG virtaddr, char *apiname, ULONG ordinal); 137 virtual void *getPointerFromRVA(ULONG ulRVA, BOOL fOverride = FALSE); 138 void * getPointerFromRVA(const void *pvRVA) { return getPointerFromRVA((ULONG)pvRVA); } 139 virtual ULONG getRVAFromPointer(void *pv, BOOL fOverride = FALSE); 134 140 135 141 ULONG errorState, … … 161 167 PIMAGE_RESOURCE_DIRECTORY pResRootDir; 162 168 169 PIMAGE_EXPORT_DIRECTORY pExportDir; 170 PIMAGE_OPTIONAL_HEADER poh; 171 163 172 //substracted from RVA data offsets 164 173 ULONG ulRVAResourceSection; -
trunk/src/kernel32/winimagelx.cpp
r9971 r10397 1 /* $Id: winimagelx.cpp,v 1.2 0 2003-04-02 11:03:33sandervl Exp $ */1 /* $Id: winimagelx.cpp,v 1.21 2004-01-15 10:39:11 sandervl Exp $ */ 2 2 3 3 /* … … 5 5 * 6 6 * Copyright 1999-2000 Sander van Leeuwen (sandervl@xs4all.nl) 7 * Copyright 2003 Innotek Systemberatung GmbH (sandervl@innotek.de) 8 * 9 * header adjustment & fixup_rva_ptrs borrowed from Wine (Rewind) 10 * Copyright 2000 Alexandre Julliard 7 11 * 8 12 * TODO: headers not complete 9 * 13 * 10 14 * Project Odin Software License can be found in LICENSE.TXT 11 15 * … … 62 66 63 67 //****************************************************************************** 68 /* adjust an array of pointers to make them into RVAs */ 69 //****************************************************************************** 70 static inline void fixup_rva_ptrs( void *array, void *base, int count ) 71 { 72 void **ptr = (void **)array; 73 while (count--) 74 { 75 if (*ptr) *ptr = (void *)((char *)*ptr - (char *)base); 76 ptr++; 77 } 78 } 79 //****************************************************************************** 64 80 //****************************************************************************** 65 81 Win32LxImage::Win32LxImage(HINSTANCE hInstance, PVOID pResData) 66 : Win32ImageBase(hInstance), header(0) 82 : Win32ImageBase(hInstance), header(0), pCustomPEHeader(0) 67 83 { 68 84 APIRET rc; … … 71 87 szFileName[0] = 0; 72 88 73 this->lpszExportPrefix = NULL; 74 if(lpszCustomDllName) { 75 name = lpszCustomDllName; 76 this->dwOrdinalBase = ::dwOrdinalBase; 77 78 if(lpszCustomExportPrefix) { 79 this->lpszExportPrefix = strdup(::lpszCustomExportPrefix); 80 } 89 if (lpszCustomDllName) { 90 name = lpszCustomDllName; 91 pCustomPEHeader = lpCustomDllPEHdr; 92 93 hinstance = (DWORD)pCustomPEHeader; 94 if (pCustomPEHeader) { 95 //Calculate address of optional header 96 poh = (PIMAGE_OPTIONAL_HEADER)OPTHEADEROFF(pCustomPEHeader); 97 98 //Update the header data to reflect the new load address 99 poh->ImageBase = hinstance; 100 101 PIMAGE_EXPORT_DIRECTORY pExpDir; 102 pExpDir = (PIMAGE_EXPORT_DIRECTORY)((char*)hinstance 103 + poh->DataDirectory[IMAGE_FILE_EXPORT_DIRECTORY].VirtualAddress); 104 fixup_rva_ptrs((char*)hinstance + (unsigned)pExpDir->AddressOfFunctions, 105 (LPVOID)hinstance, 106 pExpDir->NumberOfFunctions ); 107 } 81 108 } 82 109 else { 83 110 name = OSLibGetDllName(hinstance); 84 this->dwOrdinalBase = 0;85 111 } 86 112 … … 102 128 Win32LxImage::~Win32LxImage() 103 129 { 104 if(lpszExportPrefix) free(lpszExportPrefix);105 106 130 if(header) { 107 131 DosFreeMem(header); … … 115 139 ULONG apiaddr; 116 140 117 if(lpszExportPrefix) 118 {//if this dll exports by name with a prefix, then concatenate the prefix 119 //with the export name to get the OS/2 export name 120 char *lpszNewName = (char *)alloca(strlen(name) + strlen(lpszExportPrefix)+1); 121 if(lpszNewName == NULL) { 122 DebugInt3(); 123 return 0; 124 } 125 strcpy(lpszNewName, lpszExportPrefix); 126 strcat(lpszNewName, name); 127 rc = DosQueryProcAddr(hinstanceOS2, 0, lpszNewName, (PFN *)&apiaddr); 128 if(rc == NO_ERROR) { 129 return(apiaddr); 130 } 131 //else try with the normal name 132 } 141 if(pCustomPEHeader) return Win32ImageBase::getApi(name); 142 133 143 rc = DosQueryProcAddr(hinstanceOS2, 0, name, (PFN *)&apiaddr); 134 144 if(rc) … … 146 156 ULONG apiaddr; 147 157 148 rc = DosQueryProcAddr(hinstanceOS2, dwOrdinalBase+ordinal, NULL, (PFN *)&apiaddr); 158 if(pCustomPEHeader) return Win32ImageBase::getApi(ordinal); 159 160 rc = DosQueryProcAddr(hinstanceOS2, ordinal, NULL, (PFN *)&apiaddr); 149 161 if(rc) { 150 162 dprintf(("Win32LxImage::getApi %x %d -> rc = %d", hinstanceOS2, ordinal, rc)); … … 155 167 //****************************************************************************** 156 168 //****************************************************************************** 169 ULONG Win32LxImage::setApi(char *name, ULONG pfnNewProc) 170 { 171 if(pCustomPEHeader) return Win32ImageBase::setApi(name, pfnNewProc); 172 173 return -1; 174 } 175 //****************************************************************************** 176 //****************************************************************************** 177 ULONG Win32LxImage::setApi(int ordinal, ULONG pfnNewProc) 178 { 179 if(pCustomPEHeader) return Win32ImageBase::setApi(ordinal, pfnNewProc); 180 181 return -1; 182 } 183 //****************************************************************************** 184 //****************************************************************************** 157 185 LPVOID Win32LxImage::buildHeader(DWORD MajorImageVersion, DWORD MinorImageVersion, 158 DWORD Subsystem) 186 DWORD Subsystem) 159 187 { 160 188 APIRET rc; 161 189 IMAGE_DOS_HEADER *pdosheader; 162 PIMAGE_OPTIONAL_HEADER poh; 163 PIMAGE_FILE_HEADER pfh; 190 PIMAGE_OPTIONAL_HEADER poh; 191 PIMAGE_FILE_HEADER pfh; 192 PIMAGE_SECTION_HEADER psh; 193 PIMAGE_EXPORT_DIRECTORY ped; 194 195 if(pCustomPEHeader) 196 { 197 return (LPVOID)pCustomPEHeader; 198 } 199 164 200 DWORD *ntsig; 165 201 … … 180 216 pfh->NumberOfSymbols = 0; 181 217 pfh->SizeOfOptionalHeader = sizeof(IMAGE_OPTIONAL_HEADER); 182 pfh->Characteristics = IMAGE_FILE_DLL | IMAGE_FILE_32BIT_MACHINE | 183 IMAGE_FILE_DEBUG_STRIPPED | IMAGE_FILE_EXECUTABLE_IMAGE | 218 pfh->Characteristics = IMAGE_FILE_DLL | IMAGE_FILE_32BIT_MACHINE | 219 IMAGE_FILE_DEBUG_STRIPPED | IMAGE_FILE_EXECUTABLE_IMAGE | 184 220 IMAGE_FILE_RELOCS_STRIPPED; 185 221 poh = (PIMAGE_OPTIONAL_HEADER)(pfh+1); … … 214 250 poh->LoaderFlags = 0; 215 251 poh->NumberOfRvaAndSizes = 0; 216 // poh->DataDirectory[0]217 252 218 253 return header; -
trunk/src/kernel32/winimagelx.h
r9411 r10397 1 /* $Id: winimagelx.h,v 1. 7 2002-11-18 13:53:55sandervl Exp $ */1 /* $Id: winimagelx.h,v 1.8 2004-01-15 10:39:12 sandervl Exp $ */ 2 2 3 3 /* … … 24 24 virtual ULONG getApi(int ordinal); 25 25 26 virtual ULONG setApi(char *name, ULONG pfnNewProc); 27 virtual ULONG setApi(int ordinal, ULONG pfnNewProc); 28 26 29 LPVOID buildHeader(DWORD MajorImageVersion, DWORD MinorImageVersion, 27 30 DWORD Subsystem); … … 29 32 * @returns OS/2 module handle. */ 30 33 HINSTANCE getHMOD() const { return hinstanceOS2; } 34 31 35 protected: 32 36 LPVOID header; 33 37 HINSTANCE hinstanceOS2; 34 DWORD dwOrdinalBase; 35 LPSTR lpszExportPrefix; 38 39 //custom build PE header 40 LPVOID pCustomPEHeader; 41 36 42 private: 37 43 }; -
trunk/src/kernel32/winimagepe2lx.cpp
r9537 r10397 1 /* $Id: winimagepe2lx.cpp,v 1.2 1 2002-12-20 11:39:42 sandervl Exp $ */1 /* $Id: winimagepe2lx.cpp,v 1.22 2004-01-15 10:39:12 sandervl Exp $ */ 2 2 3 3 /* … … 35 35 #include <misc.h> 36 36 #include "winimagebase.h" 37 #include "windllbase.h" 38 #include "winexebase.h" 37 39 #include "winimagepe2lx.h" 40 #include "winimagepeldr.h" 41 #include "windllpeldr.h" 42 #include "winimagelx.h" 43 #include "windlllx.h" 38 44 #include "Win32k.h" 39 45 … … 259 265 hinstance = (HINSTANCE)paSections[0].ulAddress; 260 266 267 /* Set poh & pExportDir (base class stuff) */ 268 poh = &pNtHdrs->OptionalHeader; 269 pExportDir = (PIMAGE_EXPORT_DIRECTORY)getPointerFromRVA(pNtHdrs->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].VirtualAddress); 270 261 271 /* Locate and set the entrypoint. */ 262 272 setEntryPoint((ULONG)getPointerFromRVA(pNtHdrs->OptionalHeader.AddressOfEntryPoint)); … … 272 282 273 283 /* Locate the resource directory (if any) */ 274 if (pNtHdrs->OptionalHeader.NumberOfRvaAndSizes > IMAGE_DIRECTORY_ENTRY_RESOURCE 275 && pNtHdrs->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_RESOURCE].VirtualAddress > 0UL) 276 { 277 ulRVAResourceSection = pNtHdrs->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_RESOURCE].VirtualAddress; 278 pResRootDir = (PIMAGE_RESOURCE_DIRECTORY)getPointerFromRVA(ulRVAResourceSection); 279 /* _temporary_ fix: 280 * We'll have to make the resource section writable. 281 * And we'll have to make the pages before it readable. 282 */ 283 LONG iSection = getSectionIndexFromRVA(ulRVAResourceSection); 284 if (iSection >= 0) 285 { 286 rc = DosSetMem((PVOID)paSections[iSection].ulAddress, paSections[iSection].cbVirtual, PAG_WRITE | PAG_READ); 287 288 ULONG ulAddr = paSections[iSection].ulAddress - 0x10000; //64KB 289 while (ulAddr < paSections[iSection].ulAddress) 290 { 291 ULONG fl = ~0UL; 292 ULONG cb = ~0UL; 293 rc = DosQueryMem((PVOID)ulAddr, &cb, &fl); 294 if (rc == NO_ERROR) 295 { 296 if (fl & PAG_GUARD) 297 rc = -1; 298 else if (fl & PAG_COMMIT) 299 fl &= ~(PAG_COMMIT); 300 else 301 fl |= PAG_COMMIT; 302 cb = (cb + 0xfffUL) & ~0xfffUL; 303 } 304 else 305 { 306 fl = PAG_COMMIT; 307 cb = 0x1000; 308 } 309 fl &= PAG_READ | PAG_COMMIT | PAG_WRITE | PAG_GUARD; 310 fl |= PAG_READ; 311 if (cb > paSections[iSection].ulAddress - ulAddr) 312 cb = paSections[iSection].ulAddress - ulAddr; 313 if (rc == NO_ERROR) 314 rc = DosSetMem((PVOID)ulAddr, cb, fl); 315 316 ulAddr += cb; 317 } 318 } 319 } 320 321 /* TLS - Thread Local Storage */ 322 if (pNtHdrs->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_TLS].VirtualAddress != 0UL 323 && pNtHdrs->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_TLS].Size != 0UL) 324 { 325 PIMAGE_TLS_DIRECTORY pTLSDir; 326 LONG iSection; 327 iSection = getSectionIndexFromRVA(pNtHdrs->OptionalHeader. 328 DataDirectory[IMAGE_DIRECTORY_ENTRY_TLS]. 329 VirtualAddress); 330 pTLSDir = (PIMAGE_TLS_DIRECTORY)getPointerFromRVA(pNtHdrs->OptionalHeader. 331 DataDirectory[IMAGE_DIRECTORY_ENTRY_TLS]. 332 VirtualAddress); 333 334 if (pTLSDir != NULL && iSection != -1) 335 { 336 PVOID pv; 337 338 /* 339 * According to the docs StartAddressOfRawData and EndAddressOfRawData is 340 * real pointers with a baserelocs. 341 * 342 * The docs says nothing about the two AddressOf pointers. So, we'll assume that 343 * these also are real pointers. But, we'll try compensate if they should not have 344 * base realocations. 345 */ 346 if (validateRealPointer((PVOID)pTLSDir->StartAddressOfRawData) 347 && 348 validateRealPointer((PVOID)pTLSDir->EndAddressOfRawData) 349 ) 350 { 351 setTLSAddress((PVOID)pTLSDir->StartAddressOfRawData); 352 setTLSInitSize(pTLSDir->EndAddressOfRawData - pTLSDir->StartAddressOfRawData); 353 setTLSTotalSize(pTLSDir->EndAddressOfRawData - pTLSDir->StartAddressOfRawData + pTLSDir->SizeOfZeroFill); 354 355 if (pTLSDir->AddressOfIndex) 356 { 357 if (validateRealPointer(pTLSDir->AddressOfIndex)) 358 /* assume baserelocations for thepointer; use it without any change. */ 359 setTLSIndexAddr((LPDWORD)(void*)pTLSDir->AddressOfIndex); 360 else 361 { /* assume no baserelocs for these pointers? Complain and debugint3 */ 362 eprintf(("Win32Pe2LxImage::init: TLS - AddressOfIndex(%#8x) is not a pointer with basereloc.\n", 363 pTLSDir->AddressOfIndex)); 364 pv = getPointerFromPointer(pTLSDir->AddressOfIndex); 365 if (pv == NULL) 366 { 367 eprintf(("Win32Pe2LxImage::init: invalid RVA to TLS AddressOfIndex - %#8x.\n", 368 pTLSDir->AddressOfIndex)); 369 return LDRERROR_INVALID_HEADER; 370 } 371 setTLSIndexAddr((LPDWORD)pv); 372 } 373 } 374 375 if (pTLSDir->AddressOfCallBacks) 376 { 377 if (validateRealPointer(pTLSDir->AddressOfCallBacks)) 378 /* assume baserelocations for thepointer; use it without any change. */ 379 setTLSCallBackAddr(pTLSDir->AddressOfCallBacks); 380 else 381 { /* assume no baserelocs for these pointers? Complain and debugint3 */ 382 eprintf(("Win32Pe2LxImage::init: Warning: TLS - AddressOfCallBacks(%#8x) is not a pointer with basereloc.\n", 383 pTLSDir->AddressOfCallBacks)); 384 pv = getPointerFromPointer(pTLSDir->AddressOfCallBacks); 385 if (pv == NULL) 386 { 387 eprintf(("Win32Pe2LxImage::init: invalid pointer to TLS AddressOfCallBacks - %#8x.\n", 388 pTLSDir->AddressOfIndex)); 389 return LDRERROR_INVALID_HEADER; 390 } 391 setTLSCallBackAddr((PIMAGE_TLS_CALLBACK*)pv); 392 } 393 } 394 } 395 } 396 else 397 { 398 eprintf(("Win32Pe2LxImage::init: invalid RVA to TLS Dir - %#8x. (getPointerFromRVA failed)\n", 399 pNtHdrs->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_TLS].VirtualAddress)); 400 return LDRERROR_INVALID_HEADER; 401 } 402 } 284 rc = doResources(); 285 if (rc) 286 return rc; 287 288 /* 289 * TLS - Thread Local Storage 290 */ 291 rc = doTLS(); 292 if (rc) 293 return rc; 294 295 296 /* 297 * Process imports. 298 */ 299 rc = doImports(); 300 if (rc) 301 return rc; 302 403 303 return LDRERROR_SUCCESS; 404 304 } 405 406 305 407 306 … … 688 587 689 588 /** 589 * Process resource section. 590 */ 591 ULONG Win32Pe2LxImage::doResources() 592 { 593 ULONG rc; 594 595 if (pNtHdrs->OptionalHeader.NumberOfRvaAndSizes > IMAGE_DIRECTORY_ENTRY_RESOURCE 596 && pNtHdrs->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_RESOURCE].VirtualAddress > 0UL) 597 { 598 ulRVAResourceSection = pNtHdrs->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_RESOURCE].VirtualAddress; 599 pResRootDir = (PIMAGE_RESOURCE_DIRECTORY)getPointerFromRVA(ulRVAResourceSection); 600 /* _temporary_ fix: 601 * We'll have to make the resource section writable. 602 * And we'll have to make the pages before it readable. 603 */ 604 LONG iSection = getSectionIndexFromRVA(ulRVAResourceSection); 605 if (iSection >= 0) 606 { 607 rc = DosSetMem((PVOID)paSections[iSection].ulAddress, paSections[iSection].cbVirtual, PAG_WRITE | PAG_READ); 608 609 ULONG ulAddr = paSections[iSection].ulAddress - 0x10000; //64KB 610 while (ulAddr < paSections[iSection].ulAddress) 611 { 612 ULONG fl = ~0UL; 613 ULONG cb = ~0UL; 614 rc = DosQueryMem((PVOID)ulAddr, &cb, &fl); 615 if (rc == NO_ERROR) 616 { 617 if (fl & PAG_GUARD) 618 rc = -1; 619 else if (fl & PAG_COMMIT) 620 fl &= ~(PAG_COMMIT); 621 else 622 fl |= PAG_COMMIT; 623 cb = (cb + 0xfffUL) & ~0xfffUL; 624 } 625 else 626 { 627 fl = PAG_COMMIT; 628 cb = 0x1000; 629 } 630 fl &= PAG_READ | PAG_COMMIT | PAG_WRITE | PAG_GUARD; 631 fl |= PAG_READ; 632 if (cb > paSections[iSection].ulAddress - ulAddr) 633 cb = paSections[iSection].ulAddress - ulAddr; 634 if (rc == NO_ERROR) 635 rc = DosSetMem((PVOID)ulAddr, cb, fl); 636 637 ulAddr += cb; 638 } 639 } 640 } 641 642 return 0; 643 } 644 645 646 /** 647 * Do TLS related matters. 648 */ 649 ULONG Win32Pe2LxImage::doTLS() 650 { 651 if (pNtHdrs->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_TLS].VirtualAddress != 0UL 652 && pNtHdrs->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_TLS].Size != 0UL) 653 { 654 PIMAGE_TLS_DIRECTORY pTLSDir; 655 LONG iSection; 656 iSection = getSectionIndexFromRVA(pNtHdrs->OptionalHeader. 657 DataDirectory[IMAGE_DIRECTORY_ENTRY_TLS]. 658 VirtualAddress); 659 pTLSDir = (PIMAGE_TLS_DIRECTORY)getPointerFromRVA(pNtHdrs->OptionalHeader. 660 DataDirectory[IMAGE_DIRECTORY_ENTRY_TLS]. 661 VirtualAddress); 662 663 if (pTLSDir != NULL && iSection != -1) 664 { 665 PVOID pv; 666 667 /* 668 * According to the docs StartAddressOfRawData and EndAddressOfRawData is 669 * real pointers with a baserelocs. 670 * 671 * The docs says nothing about the two AddressOf pointers. So, we'll assume that 672 * these also are real pointers. But, we'll try compensate if they should not have 673 * base realocations. 674 */ 675 if (validateRealPointer((PVOID)pTLSDir->StartAddressOfRawData) 676 && 677 validateRealPointer((PVOID)pTLSDir->EndAddressOfRawData) 678 ) 679 { 680 setTLSAddress((PVOID)pTLSDir->StartAddressOfRawData); 681 setTLSInitSize(pTLSDir->EndAddressOfRawData - pTLSDir->StartAddressOfRawData); 682 setTLSTotalSize(pTLSDir->EndAddressOfRawData - pTLSDir->StartAddressOfRawData + pTLSDir->SizeOfZeroFill); 683 684 if (pTLSDir->AddressOfIndex) 685 { 686 if (validateRealPointer(pTLSDir->AddressOfIndex)) 687 /* assume baserelocations for thepointer; use it without any change. */ 688 setTLSIndexAddr((LPDWORD)(void*)pTLSDir->AddressOfIndex); 689 else 690 { /* assume no baserelocs for these pointers? Complain and debugint3 */ 691 eprintf(("Win32Pe2LxImage::init: TLS - AddressOfIndex(%#8x) is not a pointer with basereloc.\n", 692 pTLSDir->AddressOfIndex)); 693 pv = getPointerFromPointer(pTLSDir->AddressOfIndex); 694 if (pv == NULL) 695 { 696 eprintf(("Win32Pe2LxImage::init: invalid RVA to TLS AddressOfIndex - %#8x.\n", 697 pTLSDir->AddressOfIndex)); 698 return LDRERROR_INVALID_HEADER; 699 } 700 setTLSIndexAddr((LPDWORD)pv); 701 } 702 } 703 704 if (pTLSDir->AddressOfCallBacks) 705 { 706 if (validateRealPointer(pTLSDir->AddressOfCallBacks)) 707 /* assume baserelocations for thepointer; use it without any change. */ 708 setTLSCallBackAddr(pTLSDir->AddressOfCallBacks); 709 else 710 { /* assume no baserelocs for these pointers? Complain and debugint3 */ 711 eprintf(("Win32Pe2LxImage::init: Warning: TLS - AddressOfCallBacks(%#8x) is not a pointer with basereloc.\n", 712 pTLSDir->AddressOfCallBacks)); 713 pv = getPointerFromPointer(pTLSDir->AddressOfCallBacks); 714 if (pv == NULL) 715 { 716 eprintf(("Win32Pe2LxImage::init: invalid pointer to TLS AddressOfCallBacks - %#8x.\n", 717 pTLSDir->AddressOfIndex)); 718 return LDRERROR_INVALID_HEADER; 719 } 720 setTLSCallBackAddr((PIMAGE_TLS_CALLBACK*)pv); 721 } 722 } 723 } 724 } 725 else 726 { 727 eprintf(("Win32Pe2LxImage::init: invalid RVA to TLS Dir - %#8x. (getPointerFromRVA failed)\n", 728 pNtHdrs->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_TLS].VirtualAddress)); 729 return LDRERROR_INVALID_HEADER; 730 } 731 } 732 733 return 0; 734 } 735 736 /** 737 * Processes the import directory of the image. 738 * @returns LDRERROR_* 739 * @remark This could be in base class and shared with the peldr. 740 */ 741 ULONG Win32Pe2LxImage::doImports() 742 { 743 ULONG rc; 744 PIMAGE_IMPORT_DESCRIPTOR pImps; 745 746 /* 747 * Check if there is actually anything to work on. 748 */ 749 if ( !pNtHdrs->OptionalHeader.DataDirectory[IMAGE_FILE_IMPORT_DIRECTORY].VirtualAddress 750 || !pNtHdrs->OptionalHeader.DataDirectory[IMAGE_FILE_IMPORT_DIRECTORY].Size) 751 { 752 dprintf(("Win32Pe2LxImage::initImports: there are no imports\n")); 753 return 0; 754 } 755 756 /* 757 * Walk the IMAGE_IMPORT_DESCRIPTOR table. 758 */ 759 for (rc = 0, pImps = (PIMAGE_IMPORT_DESCRIPTOR)getPointerFromRVA(pNtHdrs->OptionalHeader.DataDirectory[IMAGE_FILE_IMPORT_DIRECTORY].VirtualAddress); 760 !rc && pImps->Name != 0 && pImps->FirstThunk != 0; 761 pImps++) 762 { 763 const char * pszName = (const char*)getPointerFromRVA(pImps->Name); 764 Win32ImageBase *pModule; 765 dprintf(("Win32Pe2LxImage::initImports: DLL %s\n", pszName)); 766 767 /* 768 * Try find the table. 769 */ 770 pModule = importsGetModule(pszName); 771 if (pModule) 772 { 773 PIMAGE_THUNK_DATA pFirstThunk; /* update this. */ 774 PIMAGE_THUNK_DATA pThunk; /* read from this. */ 775 776 /* 777 * Walk the thunks table(s). 778 */ 779 pFirstThunk = (PIMAGE_THUNK_DATA)getPointerFromRVA((ULONG)pImps->FirstThunk); 780 pThunk = pImps->u.OriginalFirstThunk == 0 ? pFirstThunk 781 : (PIMAGE_THUNK_DATA)getPointerFromRVA((ULONG)pImps->FirstThunk); 782 while (!rc && pThunk->u1.Ordinal != 0) 783 { 784 if (pThunk->u1.Ordinal & IMAGE_ORDINAL_FLAG) 785 rc = importsByOrdinal(pModule, IMAGE_ORDINAL(pThunk->u1.Ordinal), (void**)&pFirstThunk->u1.Function); 786 else if ( pThunk->u1.Ordinal > 0 787 && pThunk->u1.Ordinal < pNtHdrs->OptionalHeader.SizeOfImage) 788 rc = importsByName(pModule, (const char*)getPointerFromRVA((ULONG)pThunk->u1.AddressOfData + 2), (void**)&pFirstThunk->u1.Function); 789 else 790 { 791 dprintf(("Win32Pe2LxImage::initImports: bad import data thunk!\n")); 792 DebugInt3(); 793 rc = LDRERROR_IMPORTS; 794 } 795 796 pThunk++; 797 pFirstThunk++; 798 } 799 } 800 else 801 { 802 dprintf(("Win32Pe2LxImage::initImports: cannot find module '%s'!!!\n", pszName)); 803 DebugInt3(); 804 rc = LDRERROR_IMPORTS; 805 } 806 } 807 808 return rc; 809 } 810 811 812 /** 813 * Find a module. 814 * 815 * @returns Pointer to module 816 * @returns NULL on failure. 817 * @param pszModName Pointer to module name. 818 * @remark This should be in base class and shared with the peldr. 819 */ 820 Win32ImageBase * Win32Pe2LxImage::importsGetModule(const char *pszModName) 821 { 822 Win32ImageBase *pMod; 823 Win32DllBase *pDll; 824 825 /* 826 * Look if it's already loaded. 827 */ 828 pDll = Win32DllBase::findModule((char*)pszModName); 829 if (pDll) 830 { 831 dprintf(("Win32Pe2LxImage::importGetModule(%s) already loaded\n", pszModName)); 832 pDll->AddRef(); 833 } 834 else if (WinExe != NULL && WinExe->matchModName(pszModName)) 835 { 836 dprintf(("Win32Pe2LxImage::importGetModule(%s) already loaded (exe)\n", pszModName)); 837 pMod = (Win32ImageBase *)WinExe; 838 pDll = NULL; 839 } 840 else 841 { 842 /* 843 * Load it (simplified). 844 */ 845 pDll = importsLoadModule(pszModName); 846 if (!pDll) 847 return NULL; 848 dprintf(("Win32Pe2LxImage::importGetModule(%s) Loaded module\n", pszModName)); 849 } 850 851 /* 852 * Update dependendcies. 853 */ 854 if (pDll) 855 { 856 /* 857 * Add the dll we just loaded to dependency list for this image. 858 */ 859 addDependency(pDll); 860 861 /* 862 * Make sure the dependency list is correct (already done in the ctor 863 * of Win32DllBase, but for LX dlls the parent is then set to NULL) 864 * so, change it here again 865 */ 866 pDll->setUnloadOrder(this); 867 pMod = pDll; 868 } 869 870 return pMod; 871 } 872 873 /** 874 * Loads a module this module is depending on. 875 * @returns Pointer to loaded module. 876 * @returns NULL on failure. 877 * @param pszModName Name of the module to be loaded. 878 * @remark This should be in base class and shared with the peldr. 879 */ 880 Win32DllBase *Win32Pe2LxImage::importsLoadModule(const char *pszModName) 881 { 882 Win32DllBase *pDll; 883 char szRenamed[CCHMAXPATH]; 884 885 /* 886 * Copy and rename the module name. (i.e. OLE32 -> OLE32OS2) 887 */ 888 Win32DllBase::renameDll(strcpy(szRenamed, pszModName)); 889 890 /* 891 * Find the filename (using the standard search stuff). 892 */ 893 char szFullname[CCHMAXPATH]; 894 if (!Win32ImageBase::findDll(szRenamed, szFullname, sizeof(szFullname))) 895 { 896 dprintf(("Module %s not found!", szRenamed)); 897 errorState = ERROR_FILE_NOT_FOUND; 898 return NULL; 899 } 900 901 /* 902 * Check which type of executable module this is. 903 */ 904 if (isPEImage(szFullname, NULL, NULL) != ERROR_SUCCESS_W) 905 { 906 /* 907 * LX image: let OS/2 do all the work for us 908 */ 909 char szModuleFailure[CCHMAXPATH]; 910 HMODULE hmodLXDll; 911 APIRET rc; 912 913 rc = DosLoadModule(szModuleFailure, sizeof(szModuleFailure), szFullname, (HMODULE *)&hmodLXDll); 914 if (rc) 915 { 916 dprintf(("DosLoadModule returned %X for %s", rc, szModuleFailure)); 917 errorState = rc; 918 return NULL; 919 } 920 921 pDll = Win32DllBase::findModuleByOS2Handle((HINSTANCE)hmodLXDll); 922 if (pDll == NULL) 923 { 924 dprintf(("Just loaded the dll, but can't find it anywhere?!!?")); 925 DebugInt3(); 926 errorState = ERROR_INTERNAL; 927 return NULL; 928 } 929 930 /* 931 * For none Pe2Lx'ed LX modules we'll have to do a little work here. 932 */ 933 if (pDll->isLxDll()) 934 { 935 Win32LxDll *pLXDll = (Win32LxDll *)pDll; 936 pLXDll->setDllHandleOS2(hmodLXDll); 937 if (pLXDll->AddRef() == -1) //-1 -> load failed (attachProcess) 938 { 939 dprintf(("Dll %s refused to be loaded; aborting", szFullname)); 940 delete pLXDll; 941 errorState = ERROR_INTERNAL; 942 return NULL; 943 } 944 } 945 } 946 else 947 { 948 /* 949 * PE image: use the peldr. 950 */ 951 Win32PeLdrDll *pPEDll; 952 953 pPEDll = new Win32PeLdrDll(szFullname, this); 954 if (!pPEDll) 955 { 956 dprintf(("pedll: Error allocating memory" )); 957 errorState = ERROR_INTERNAL; 958 return NULL; 959 } 960 dprintf(("**********************************************************************")); 961 dprintf(("********************** Loading Module *********************")); 962 dprintf(("**********************************************************************")); 963 if (pPEDll->init(0) != LDRERROR_SUCCESS) 964 { 965 dprintf(("Internal WinDll error ", pPEDll->getError())); 966 delete pPEDll; 967 return NULL; 968 } 969 970 #ifdef DEBUG 971 pPEDll->AddRef(getModuleName()); 972 #else 973 pPEDll->AddRef(); 974 #endif 975 if (pPEDll->attachProcess() == FALSE) 976 { 977 dprintf(("attachProcess failed!")); 978 delete pPEDll; 979 errorState = ERROR_INTERNAL; 980 return NULL; 981 } 982 pDll = (Win32DllBase*)pPEDll; 983 } 984 985 dprintf(("**********************************************************************")); 986 dprintf(("********************** Finished Loading Module %s ", szFullname)); 987 dprintf(("**********************************************************************")); 988 return pDll; 989 } 990 991 992 /** 993 * Resolve an import by symbol name. 994 * 995 * @returns 0 on success, error code on failure. 996 * @param pModule Pointer to module. 997 * @param uOrdinal Ordinal of the symbol to import. 998 * @param ppvAddr Where to store the symbol address. 999 * @remark This should be in base class and shared with the peldr. 1000 */ 1001 ULONG Win32Pe2LxImage::importsByOrdinal(Win32ImageBase *pModule, unsigned uOrdinal, void **ppvAddr) 1002 { 1003 void *pfn; 1004 pfn = (void*)pModule->getApi(uOrdinal); 1005 if (pfn) 1006 { 1007 dprintf(("Win32Pe2LxImage::importsByOrdinal: *%p=%p %s!%d\n", ppvAddr, pfn, pModule->getModuleName(), uOrdinal)); 1008 *ppvAddr = pfn; 1009 return 0; 1010 } 1011 1012 dprintf(("Win32Pe2LxImage::importsByOrdinal: %s!%u\n", pModule->getModuleName(), uOrdinal)); 1013 DebugInt3(); 1014 /** @todo: missing api */ 1015 *ppvAddr = NULL; 1016 return LDRERROR_IMPORTS; 1017 } 1018 1019 1020 /** 1021 * Resolve an import by symbol name. 1022 * 1023 * @returns 0 on success, error code on failure. 1024 * @param pModule Pointer to module. 1025 * @param pszSymName Name of symbol to import. 1026 * @param ppvAddr Where to store the symbol address. 1027 * @remark This should be in base class and shared with the peldr. 1028 */ 1029 ULONG Win32Pe2LxImage::importsByName(Win32ImageBase *pModule, const char *pszSymName, void **ppvAddr) 1030 { 1031 void *pfn; 1032 pfn = (void*)pModule->getApi((char*)pszSymName); 1033 if (pfn) 1034 { 1035 dprintf(("Win32Pe2LxImage::importsByName: *%p=%p %s!%s\n", ppvAddr, pfn, pModule->getModuleName(), pszSymName)); 1036 *ppvAddr = pfn; 1037 return 0; 1038 } 1039 1040 dprintf(("Win32Pe2LxImage::importsByName: %s!%s\n", pModule->getModuleName(), pszSymName)); 1041 DebugInt3(); 1042 /** @todo: missing api */ 1043 *ppvAddr = NULL; 1044 return LDRERROR_IMPORTS; 1045 } 1046 1047 1048 /** 690 1049 * Frees memory used by this object. 691 1050 * When an exception is to be thrown, this function is called first to clean up … … 711 1070 * Converts a RVA into a pointer. 712 1071 * @returns Pointer matching the given RVA, NULL on error. 713 * @param ulRVA An address relative to the imagebase of the original PE image. 714 * If this is 0UL NULL is returned. 1072 * @param ulRVA An address relative to the imagebase of the original PE image. 1073 * If this is 0UL NULL is returned. 1074 * @param fOverride If set the ulRVA doesn't have to be inside the image. 715 1075 * @sketch DEBUG: validate state, paSections != NULL 716 1076 * IF ulRVA is 0 THEN return NULL … … 724 1084 * RVA == 0 is ignored. 725 1085 */ 726 PVOID Win32Pe2LxImage::getPointerFromRVA(ULONG ulRVA) 727 { 728 int i; 729 1086 void * Win32Pe2LxImage::getPointerFromRVA(ULONG ulRVA, BOOL fOverride) 1087 { 730 1088 #ifdef DEBUG 731 1089 if (paSections == NULL) … … 739 1097 return NULL; 740 1098 741 i = 0;1099 int i = 0; 742 1100 while (i < cSections && 743 1101 (paSections[i].ulRVA > ulRVA || paSections[i].ulRVA + paSections[i].cbVirtual <= ulRVA)) /* ALIGN on page too? */ 744 1102 i++; 745 746 1103 if (i >= cSections) 1104 { 1105 /* This isn't good, but it's required to support api overrides. */ 1106 if (fOverride) 1107 return (char*)hinstance + ulRVA; 747 1108 return NULL; 1109 } 748 1110 749 1111 return (PVOID)(ulRVA - paSections[i].ulRVA + paSections[i].ulAddress); 1112 } 1113 1114 1115 /** Converts a pointer to an RVA for the loaded image. 1116 * @remark Because of export overriding addresses outside the image must be supported. 1117 */ 1118 ULONG Win32Pe2LxImage::getRVAFromPointer(void *pv, BOOL fOverride/* = FALSE*/) 1119 { 1120 #ifdef DEBUG 1121 if (paSections == NULL) 1122 { 1123 eprintf(("Win32Pe2LxImage::getPointerFromRVA: paSections is NULL!\n")); 1124 return NULL; 1125 } 1126 #endif 1127 1128 if (pv == 0UL) 1129 return NULL; 1130 1131 int i = 0; 1132 while (i < cSections && 1133 (paSections[i].ulAddress > (ULONG)pv || paSections[i].ulAddress + paSections[i].cbVirtual <= (ULONG)pv)) /* ALIGN on page too? */ 1134 i++; 1135 if (i >= cSections) 1136 { 1137 /* This isn't good, but it's required to support api overrides. */ 1138 if (fOverride) 1139 return (ULONG)pv - (ULONG)hinstance; 1140 return NULL; 1141 } 1142 1143 return (ULONG)pv - paSections[i].ulAddress + paSections[i].ulRVA; 750 1144 } 751 1145 … … 843 1237 844 1238 845 /**846 * Gets pointer to an exported procedure by procedure name.847 * @returns Address of exported procedure. 0UL if not found.848 * @param name Exported procedure name.849 * @status completely implemented.850 * @author Sander van Leeuwen851 * @remark852 */853 ULONG Win32Pe2LxImage::getApi(char *name)854 {855 APIRET rc;856 ULONG ulApiAddr;857 858 rc = DosQueryProcAddr(hmod, 0, name, (PFN *)&ulApiAddr);859 return rc == NO_ERROR ? ulApiAddr : 0;860 }861 862 863 /**864 * Gets pointer to an exported procedure by ordinal.865 * @returns Pointer to an exported procedure. 0UL if not found.866 * @param ordinal Export ordinal number.867 * @status completely implemented.868 * @author Sander van Leeuwen869 * @remark FIXME:870 * This function should be implemented for both Exe and Dll images!871 * It could be done similar in both peldr image and pe2lx images by872 * accessing PE structures.873 */874 ULONG Win32Pe2LxImage::getApi(int ordinal)875 {876 APIRET rc;877 ULONG ulApiAddr;878 879 rc = DosQueryProcAddr(hmod, ordinal, NULL, (PFN *)&ulApiAddr);880 881 return rc == NO_ERROR ? ulApiAddr : 0;882 } -
trunk/src/kernel32/winimagepe2lx.h
r9537 r10397 1 /* $Id: winimagepe2lx.h,v 1. 9 2002-12-20 11:39:42sandervl Exp $ */1 /* $Id: winimagepe2lx.h,v 1.10 2004-01-15 10:39:13 sandervl Exp $ */ 2 2 3 3 /* … … 43 43 virtual DWORD init(); 44 44 45 /** @cat Exports */46 virtual ULONG getApi(char *name);47 virtual ULONG getApi(int ordinal);48 49 45 /** @cat Queries */ 50 46 /** Get the OS/2 module handle. … … 56 52 ULONG getSections(); 57 53 ULONG setSectionRVAs(); 54 ULONG doResources(); 55 ULONG doTLS(); 56 ULONG doImports(); 57 Win32ImageBase *importsGetModule(const char *pszModName); 58 Win32DllBase *importsLoadModule(const char *pszModName); 59 ULONG importsByOrdinal(Win32ImageBase *pModule, unsigned uOrdinal, void **ppvAddr); 60 ULONG importsByName(Win32ImageBase *pModule, const char *pszSymName, void **ppvAddr); 58 61 VOID cleanup(); 59 62 … … 61 64 /** @cat RVA -> pointer */ 62 65 /* these should be moved to winimagebase some day... */ 63 PVOID getPointerFromRVA(ULONG ulRVA); 66 void * getPointerFromRVA(ULONG ulRVA, BOOL fOverride = FALSE); 67 ULONG getRVAFromPointer(void *pv, BOOL fOverride = FALSE); 64 68 PVOID getPointerFromPointer(PVOID pv); 65 69 LONG getSectionIndexFromRVA(ULONG ulRVA); 66 70 BOOL validateRealPointer(PVOID pv); 67 71 68 PSECTION paSections; /* Used by getPointerFromRVA and created by getSections and 69 * setSectionRVAs. */ 70 WORD cSections; /* Count of entires in the section array (paSection) */ 72 /** Used by getPointerFromRVA and created by getSections and setSectionRVAs. */ 73 PSECTION paSections; 74 /** Count of entires in the section array (paSection) */ 75 int cSections; 71 76 72 77 /** @cat Misc */ 73 PIMAGE_NT_HEADERS pNtHdrs; /* Pointer to NT headers. */ 74 BOOL fWin32k; /* flag which indicates wether this is a Win32k loaded 75 * module (TRUE) or and Pe2Lx module (FALSE). */ 76 HMODULE hmod; /* OS/2 handle of the module. */ 77 BOOL fDll; /* Set by Win32Pe2LxDll. */ 78 /** Pointer to NT headers. */ 79 PIMAGE_NT_HEADERS pNtHdrs; 80 /** Flag which indicates wether this is a Win32k loaded 81 * module (TRUE) or and Pe2Lx module (FALSE). */ 82 BOOL fWin32k; 83 /** OS/2 handle of the module. */ 84 HMODULE hmod; 85 /** Set by Win32Pe2LxDll. */ 86 BOOL fDll; 78 87 }; 79 88 -
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 //****************************************************************************** -
trunk/src/kernel32/winimagepeldr.h
r9997 r10397 1 /* $Id: winimagepeldr.h,v 1.2 0 2003-04-09 10:39:41sandervl Exp $ */1 /* $Id: winimagepeldr.h,v 1.21 2004-01-15 10:39:15 sandervl Exp $ */ 2 2 3 3 /* … … 85 85 virtual BOOL insideModuleCode(ULONG address); 86 86 87 virtual ULONG getApi(char *name);88 virtual ULONG getApi(int ordinal);89 virtual ULONG setApi(char *name, ULONG pfnNewProc);90 virtual ULONG setApi(int ordinal, ULONG pfnNewProc);91 92 87 virtual ULONG getImageSize(); 93 88 … … 114 109 Section *findPreviousSectionByOS2Addr(ULONG addr); 115 110 116 OrdExport *findApi(int ordinal);117 NameExport *findApi(char *name);118 119 111 BOOL setMemFlags(); 120 112 BOOL setFixups(PIMAGE_BASE_RELOCATION prel); … … 125 117 BOOL processImports(); 126 118 BOOL processExports(); 127 void AddNameExport(ULONG virtaddr, char *apiname, ULONG ordinal, BOOL fAbsoluteAddress=FALSE); 128 void AddOrdExport(ULONG virtaddr, ULONG ordinal, BOOL fAbsoluteAddress=FALSE); 129 BOOL AddForwarder(ULONG virtaddr, char *apiname, ULONG ordinal); 119 120 BOOL loadForwarder(ULONG virtaddr, char *apiname, ULONG ordinal); 130 121 131 122 Win32DllBase *loadDll(char *pszCurModule); 132 123 133 IMAGE_OPTIONAL_HEADER oh;134 IMAGE_FILE_HEADER fh;135 136 ULONG nrNameExports, nameExportSize;137 ULONG nrOrdExports;138 ULONG nrOrdExportsRegistered;139 NameExport *nameexports, *curnameexport;140 OrdExport *ordexports, *curordexport;141 142 124 ULONG nrsections, imageSize, imageVirtBase, imageVirtEnd; 143 125 //OS/2 virtual base address 144 ULONG realBaseAddress; 145 Section *section; 126 ULONG realBaseAddress, originalBaseAddress; 127 Section *section; 128 ULONG Characteristics; 146 129 147 130 //offset in executable image where real PE file starts (default 0)
Note:
See TracChangeset
for help on using the changeset viewer.