/* * Given an open optimized DEX file, map it into read-only shared memory and * parse the contents. * * Returns nonzero on error. */ int dvmDexFileOpenFromFd(int fd, DvmDex** ppDvmDex) { DvmDex* pDvmDex; DexFile* pDexFile; MemMapping memMap; int parseFlags = kDexParseDefault; int result = -1; if (gDvm.verifyDexChecksum) parseFlags |= kDexParseVerifyChecksum; if (lseek(fd, 0, SEEK_SET) < 0) { LOGE("lseek rewind failed\n"); goto bail; } if (sysMapFileInShmemWritableReadOnly(fd, &memMap) != 0) { LOGE("Unable to map file\n"); goto bail; } pDexFile = dexFileParse(memMap.addr, memMap.length, parseFlags); if (pDexFile == NULL) { LOGE("DEX parse failed\n"); sysReleaseShmem(&memMap); goto bail; } pDvmDex = allocateAuxStructures(pDexFile); if (pDvmDex == NULL) { dexFileFree(pDexFile); sysReleaseShmem(&memMap); goto bail; } //This seems like the best place to initialize the DvmDex mutex. dvmInitMutex(&pDvmDex->modLock); /* tuck this into the DexFile so it gets released later */ sysCopyMap(&pDvmDex->memMap, &memMap); *ppDvmDex = pDvmDex; result = 0; bail: return result; }
/* Given an open optimized DEX file, map it into read-only shared memory and parse the contents. Returns nonzero on error. 给定一个打开的已优化的DEX文件,映射到只读共享内存并且解析内容。 错误返回非0。 */ int dvmDexFileOpenFromFd(int fd, DvmDex** ppDvmDex) { DvmDex* pDvmDex; DexFile* pDexFile; MemMapping memMap; int parseFlags = kDexParseDefault; int result = -1; if (gDvm.verifyDexChecksum) parseFlags |= kDexParseVerifyChecksum; if (lseek(fd, 0, SEEK_SET) < 0) { ALOGE("lseek rewind failed"); goto bail; } if (sysMapFileInShmemWritableReadOnly(fd, &memMap) != 0) { ALOGE("Unable to map file"); goto bail; } pDexFile = dexFileParse((u1*)memMap.addr, memMap.length, parseFlags); if (pDexFile == NULL) { ALOGE("DEX parse failed"); sysReleaseShmem(&memMap); goto bail; } pDvmDex = allocateAuxStructures(pDexFile); if (pDvmDex == NULL) { dexFileFree(pDexFile); sysReleaseShmem(&memMap); goto bail; } /* tuck this into the DexFile so it gets released later */ sysCopyMap(&pDvmDex->memMap, &memMap); pDvmDex->isMappedReadOnly = true; *ppDvmDex = pDvmDex; result = 0; bail: return result; }
/* * Map the specified DEX file read-only (possibly after expanding it into a * temp file from a Jar). Pass in a MemMapping struct to hold the info. * If the file is an unoptimized DEX file, then byte-swapping and structural * verification are performed on it before the memory is made read-only. * * The temp file is deleted after the map succeeds. * * This is intended for use by tools (e.g. dexdump) that need to get a * read-only copy of a DEX file that could be in a number of different states. * * If "tempFileName" is NULL, a default value is used. The temp file is * deleted after the map succeeds. * * If "quiet" is set, don't report common errors. * * Returns 0 (kUTFRSuccess) on success. */ UnzipToFileResult dexOpenAndMap(const char* fileName, const char* tempFileName, MemMapping* pMap, bool quiet) { UnzipToFileResult result = kUTFRGenericFailure; int len = strlen(fileName); char tempNameBuf[32]; bool removeTemp = false; int fd = -1; if (len < 5) { if (!quiet) { fprintf(stderr, "ERROR: filename must end in .dex, .zip, .jar, or .apk\n"); } result = kUTFRBadArgs; goto bail; } if (strcasecmp(fileName + len -3, "dex") != 0) { if (tempFileName == NULL) { /* * Try .zip/.jar/.apk, all of which are Zip archives with * "classes.dex" inside. We need to extract the compressed * data to a temp file, the location of which varies. * * On the device we must use /sdcard because most other * directories aren't writable (either because of permissions * or because the volume is mounted read-only). On desktop * it's nice to use the designated temp directory. */ if (access("/tmp", W_OK) == 0) { sprintf(tempNameBuf, "/tmp/dex-temp-%d", getpid()); } else if (access("/sdcard", W_OK) == 0) { sprintf(tempNameBuf, "/sdcard/dex-temp-%d", getpid()); } else { fprintf(stderr, "NOTE: /tmp and /sdcard unavailable for temp files\n"); sprintf(tempNameBuf, "dex-temp-%d", getpid()); } tempFileName = tempNameBuf; } result = dexUnzipToFile(fileName, tempFileName, quiet); if (result == kUTFRSuccess) { //printf("+++ Good unzip to '%s'\n", tempFileName); fileName = tempFileName; removeTemp = true; } else if (result == kUTFRNotZip) { if (!quiet) { fprintf(stderr, "Not Zip, retrying as DEX\n"); } } else { if (!quiet && result == kUTFRNoClassesDex) { fprintf(stderr, "Zip has no classes.dex\n"); } goto bail; } } result = kUTFRGenericFailure; /* * Pop open the (presumed) DEX file. */ fd = open(fileName, O_RDONLY | O_BINARY); if (fd < 0) { if (!quiet) { fprintf(stderr, "ERROR: unable to open '%s': %s\n", fileName, strerror(errno)); } goto bail; } if (sysMapFileInShmemWritableReadOnly(fd, pMap) != 0) { fprintf(stderr, "ERROR: Unable to map '%s'\n", fileName); goto bail; } /* * This call will fail if the file exists on a filesystem that * doesn't support mprotect(). If that's the case, then the file * will have already been mapped private-writable by the previous * call, so we don't need to do anything special if this call * returns non-zero. */ sysChangeMapAccess(pMap->addr, pMap->length, true, pMap); if (dexSwapAndVerifyIfNecessary((u1*) pMap->addr, pMap->length)) { fprintf(stderr, "ERROR: Failed structural verification of '%s'\n", fileName); goto bail; } /* * Similar to above, this call will fail if the file wasn't ever * read-only to begin with. This is innocuous, though it is * undesirable from a memory hygiene perspective. */ sysChangeMapAccess(pMap->addr, pMap->length, false, pMap); /* * Success! Close the file and return with the start/length in pMap. */ result = kUTFRSuccess; bail: if (fd >= 0) close(fd); if (removeTemp) { /* this will fail if the OS doesn't allow removal of a mapped file */ if (unlink(tempFileName) != 0) { fprintf(stderr, "WARNING: unable to remove temp '%s'\n", tempFileName); } } return result; }
/* * Given an open optimized DEX file, map it into read-only shared memory and * parse the contents. * * Returns nonzero on error. */ int dvmDexFileOpenFromFd(int fd, DvmDex** ppDvmDex) { DvmDex* pDvmDex; DexFile* pDexFile; MemMapping memMap; int parseFlags = kDexParseDefault; int result = -1; // //salma //Success here // All the file manipulation moved to the JarFile.cpp //DvmConfigFile* pDvmConfigFile; // int configFd = -1; // __android_log_print(ANDROID_LOG_DEBUG, "DVM DEBUG", "DvmDex.cpp: Try to open config.xml"); // configFd = open("/sdcard/config.xml", O_RDONLY); // if(configFd < 0) // __android_log_print(ANDROID_LOG_DEBUG, "DVM DEBUG", "DvmDex.cpp: FAIL Try to open config.xml"); // else{ // __android_log_print(ANDROID_LOG_DEBUG, "DVM DEBUG", "DvmDex.cpp: SUCCESS Try to open config.xml"); // //success // __android_log_print(ANDROID_LOG_DEBUG, "DVM DEBUG", "DvmDex.cpp: SUCCESS Start Parse config.xml"); // pDvmConfigFile = dvmConfigFileParse(configFd); // __android_log_print(ANDROID_LOG_DEBUG, "DVM DEBUG", "DvmDex.cpp: SUCCESS Finish Parse config.xml"); // dvmConfigFileDebug(pDvmConfigFile); // __android_log_print(ANDROID_LOG_DEBUG, "DVM DEBUG", "DvmDex.cpp: SUCCESS Finish Debug config.xml"); // } ////endsalma if (gDvm.verifyDexChecksum) parseFlags |= kDexParseVerifyChecksum; if (lseek(fd, 0, SEEK_SET) < 0) { ALOGE("lseek rewind failed"); goto bail; } if (sysMapFileInShmemWritableReadOnly(fd, &memMap) != 0) { ALOGE("Unable to map file"); goto bail; } pDexFile = dexFileParse((u1*)memMap.addr, memMap.length, parseFlags); if (pDexFile == NULL) { ALOGE("DEX parse failed"); sysReleaseShmem(&memMap); goto bail; } pDvmDex = allocateAuxStructures(pDexFile); if (pDvmDex == NULL) { dexFileFree(pDexFile); sysReleaseShmem(&memMap); goto bail; } /* tuck this into the DexFile so it gets released later */ sysCopyMap(&pDvmDex->memMap, &memMap); pDvmDex->isMappedReadOnly = true; *ppDvmDex = pDvmDex; result = 0; bail: return result; }