Changeset 10397 for trunk/src/kernel32/winimagebase.cpp
- Timestamp:
- Jan 15, 2004, 11:39:15 AM (22 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
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
Note:
See TracChangeset
for help on using the changeset viewer.