CF_EXPORT Boolean _CFBundleDlfcnPreflight(CFBundleRef bundle, CFErrorRef *error) { Boolean retval = true; CFErrorRef localError = NULL; if (!bundle->_isLoaded) { CFURLRef executableURL = CFBundleCopyExecutableURL(bundle); char buff[CFMaxPathSize]; retval = false; if (executableURL && CFURLGetFileSystemRepresentation(executableURL, true, (uint8_t *)buff, CFMaxPathSize)) { #if DEPLOYMENT_TARGET_MACOSX || DEPLOYMENT_TARGET_EMBEDDED retval = dlopen_preflight(buff); #endif if (!retval && error) { CFArrayRef archs = CFBundleCopyExecutableArchitectures(bundle); CFStringRef debugString = NULL; const char *errorString = dlerror(); if (errorString && strlen(errorString) > 0) debugString = CFStringCreateWithFileSystemRepresentation(kCFAllocatorSystemDefault, errorString); if (archs) { Boolean hasSuitableArch = false, hasRuntimeMismatch = false; CFIndex i, count = CFArrayGetCount(archs); SInt32 arch, curArch = _CFBundleCurrentArchitecture(); for (i = 0; !hasSuitableArch && i < count; i++) { if (CFNumberGetValue((CFNumberRef)CFArrayGetValueAtIndex(archs, i), kCFNumberSInt32Type, (void *)&arch) && arch == curArch) hasSuitableArch = true; } #if defined(BINARY_SUPPORT_DYLD) if (hasSuitableArch) { uint32_t mainFlags = 0; if (_CFBundleGrokObjCImageInfoFromMainExecutable(NULL, &mainFlags) && (mainFlags & 0x2) != 0) { #if DEPLOYMENT_TARGET_MACOSX || DEPLOYMENT_TARGET_EMBEDDED uint32_t bundleFlags = 0; if (_CFBundleGetObjCImageInfo(bundle, NULL, &bundleFlags) && (bundleFlags & 0x2) == 0) hasRuntimeMismatch = true; #endif } } #endif /* BINARY_SUPPORT_DYLD */ if (hasRuntimeMismatch) { localError = _CFBundleCreateErrorDebug(CFGetAllocator(bundle), bundle, CFBundleExecutableRuntimeMismatchError, debugString); } else if (!hasSuitableArch) { localError = _CFBundleCreateErrorDebug(CFGetAllocator(bundle), bundle, CFBundleExecutableArchitectureMismatchError, debugString); } else { localError = _CFBundleCreateErrorDebug(CFGetAllocator(bundle), bundle, CFBundleExecutableLoadError, debugString); } CFRelease(archs); } else { localError = _CFBundleCreateErrorDebug(CFGetAllocator(bundle), bundle, CFBundleExecutableLoadError, debugString); } if (debugString) CFRelease(debugString); } } else { if (error) localError = _CFBundleCreateError(CFGetAllocator(bundle), bundle, CFBundleExecutableNotFoundError); } if (executableURL) CFRelease(executableURL); } if (!retval && error) *error = localError; return retval; }
int main(int argc,char **argv) { scanner_t *fn; if(argc!=2){ fprintf(stderr,"usage: %s scanner.so\n",argv[0]); exit(1); } #ifdef HAVE_DLOPEN const char *fname = argv[1]; char *name = strdup(fname); char *cc = strrchr(name,'.'); if(cc){ cc[0] = 0; } else { fprintf(stderr,"%s: cannot strip extension\n",name); exit(1); } if(!dlopen_preflight(fname)){ err(1,"dlopen_preflight - cannot open %s: %s",fname,dlerror()); } void *lib=dlopen(fname, RTLD_LAZY); if(lib==0) errx(1,"dlopen: %s\n",dlerror()); fn=(scanner_t *)dlsym(lib, name); if(fn==0) errx(1,"dlsym: %s\n",dlerror()); #else #ifdef HAVE_LOADLIBRARY /* Use Win32 LoadLibrary function */ /* See http://msdn.microsoft.com/en-us/library/ms686944(v=vs.85).aspx */ const char *fname = "hello.DLL"; HINSTANCE hinstLib = LoadLibrary(TEXT(fname)); if(hinstLib==0) errx(1,"LoadLibrary(%s) failed",fname); MYPROC fn = (MYPROC)GetProcAddress(hinstLib,"hello"); if(fn==0) errx(1,"GetProcAddress(%s) failed","hello"); #endif #endif uint8_t buf[100]; pos0_t p0(""); sbuf_t sbuf(p0,buf,sizeof(buf),sizeof(buf),false); feature_recorder_set fs(0); scanner_params sp(scanner_params::startup,sbuf,fs); recursion_control_block rcb(0,"STAND",true); scanner_info si; sp.info = &si; (*fn)(sp,rcb); std::cout << "Loaded scanner '" << si.name << "' by " << si.author << "\n"; dlclose(lib); return 0; }
static void tryPath(const char* path) { if ( dlopen_preflight(path) ) { void* handle = dlopen(path, RTLD_LAZY); if ( handle == NULL ) { FAIL("dlopen-non-canonical-path: dlopen(%s)", path); exit(0); } } else { FAIL("dlopen-non-canonical-path: dlopen_preflight(%s)", path); exit(0); } }
int main() { for (int i=0; i < 100; ++i) { dlopen_preflight("libfoo.dylib"); } // execute leaks command on myself char cmd[512]; sprintf(cmd, "leaks %u > /dev/null\n", getpid()); int result = system(cmd); if ( result == EXIT_SUCCESS ) PASS("dlopen_preflight-leak"); else FAIL("dlopen_preflight-leak"); return EXIT_SUCCESS; }
int main(int argc,char **argv) { if(argc!=2){ fprintf(stderr,"usage: %s scanner.so\n",argv[0]); fprintf(stderr,"type 'make plugins' to make available plugins\n"); exit(1); } /* Strip extension and path */ std::string fname = argv[1]; scanner_t *fn=0; std::string name = fname; size_t dot = name.rfind('.'); if(dot==std::string::npos){ fprintf(stderr,"%s: cannot strip extension\n",name.c_str()); exit(1); } name = name.substr(0,dot); /* Strip dir */ size_t slash = name.rfind('.'); if(slash!=std::string::npos){ name = name.substr(slash+1); } #ifdef HAVE_DLOPEN if(fname.find('.')==std::string::npos){ fname = "./" + fname; // fedora requires a complete path name } #ifdef HAVE_DLOPEN_PREFLIGHT if(!dlopen_preflight(fname.c_str())){ fprintf(stderr,"dlopen_preflight - cannot open %s: %s",fname.c_str(),dlerror()); exit(1); } #endif void *lib=dlopen(fname.c_str(), RTLD_LAZY); if(lib==0){ fprintf(stderr,"fname=%s\n",fname.c_str()); fprintf(stderr,"dlopen: %s\n",dlerror()); exit(1); } fn=(scanner_t *)dlsym(lib, name.c_str()); if(fn==0){ fprintf(stderr,"dlsym: %s\n",dlerror()); exit(1); } #endif #ifdef HAVE_LOADLIBRARY /* Use Win32 LoadLibrary function */ /* See http://msdn.microsoft.com/en-us/library/ms686944(v=vs.85).aspx */ HINSTANCE hinstLib = LoadLibrary(TEXT(fname.c_str())); if(hinstLib==0){ fprintf(stderr,"LoadLibrary(%s) failed",fname.c_str()); exit(1); } MYPROC fn = (MYPROC)GetProcAddress(hinstLib,name.c_str()); if(fn==0){ fprintf(stderr,"GetProcAddress(%s) failed",name.c_str()); exit(1); } #endif feature_recorder_set fs(0,my_hasher,feature_recorder_set::NO_INPUT,feature_recorder_set::NO_OUTDIR); uint8_t buf[100]; pos0_t p0(""); sbuf_t sbuf(p0,buf,sizeof(buf),sizeof(buf),false); scanner_params sp(scanner_params::PHASE_STARTUP,sbuf,fs); recursion_control_block rcb(0,"STAND"); scanner_info si; sp.info = &si; (*fn)(sp,rcb); std::cout << "Loaded scanner '" << si.name << "' by " << si.author << "\n"; #ifdef HAVE_DLOPEN dlclose(lib); #endif return 0; }
bool toLibrary::isValidLibrary(QFileInfo path) { if ( !path.exists()) return false; QFile lib(path.absoluteFilePath()); if ( !lib.open(QIODevice::ReadOnly)) return false; #ifdef Q_OS_LINUX static char Elf_ident[16]; if ( lib.read(Elf_ident, sizeof(Elf_ident)) != sizeof(Elf_ident)) return false; if ( Elf_ident[0] != 0x7f || Elf_ident[1] != 'E' || Elf_ident[2] != 'L' || Elf_ident[3] != 'F' || #ifdef __x86_64__ Elf_ident[4] != 0x2 #else Elf_ident[4] != 0x1 #endif ) return false; lib.close(); #endif #ifdef Q_OS_WIN32 static char COFF_header[68]; quint32 offset; static char PE_header[6]; quint16 machine; if ( lib.read(COFF_header, sizeof(COFF_header)) != sizeof(COFF_header)) return false; if ( COFF_header[0] != 'M' || COFF_header[1] != 'Z' ) return false; memcpy(&offset, COFF_header + 60, sizeof(offset)); if ( lib.seek(offset) == false) return false; if ( lib.read(PE_header, sizeof(PE_header)) != sizeof(PE_header)) return false; memcpy(&machine, PE_header + 4, sizeof(machine)); if ( PE_header[0] != 'P' || PE_header[1] != 'E' || #ifdef Q_OS_WIN64 machine != 0x8664 #else machine != 0x014c #endif ) return false; #endif #ifdef Q_OS_MAC TLOG(5, toDecorator, __HERE__) << "Validating:" << path.absoluteFilePath() << std::endl; bool retval = dlopen_preflight(path.absoluteFilePath().toStdString().c_str()); if (retval) TLOG(5, toNoDecorator, __HERE__) << "dlopen_preflight:" << path.absoluteFilePath() << " OK" << std::endl; else TLOG(5, toNoDecorator, __HERE__) << "dlopen_preflight:" << path.absoluteFilePath() << std::endl << '\t' << dlerror() << std::endl; // return OK regarless of dlopen_preflight return // it returns OK only if fix_oralib.rb was run, or DYLD_LIBRARY_PATH is set return true; #endif return true; }