在android5.0上,安装apk时,在把apk中的dex文件转换为oat文件过程中,会校验dex文件头中的magic字段,要求为“dex\n035”;
一般dex文件头中,magic字段是“dex\n035\0”;
如果dex文件头中的magic字段,被修改成了“dex\n036\0”,使用adb install安装应用时,会报 Failure [INSTALL_FAILED_DEXOPT],如下日志:
E dex2oat : Failed to open dex from file descriptor for zip file '/data/app/com.test/base.apk': Failed to open dex file '/data/app/com.test/base.apk' from memory: Unrecognized version number in /data/app/com.test/base.apk: 0 3 6
if (! DexFile::OpenFromZip(*zip_archive.get(), zip_location, &error_msg, &dex_files)) {
LOG(ERROR) << "Failed to open dex from file descriptor for zip file '" << zip_location
<< "': " << error_msg;
return EXIT_FAILURE;
}
2、/art/runtime/Dex_file.cc
namespace art {
const byte DexFile::kDexMagic[] = { 'd', 'e', 'x', '\n' };
const byte DexFile::kDexMagicVersion[] = { '0', '3', '5', '\0' }; ==》为什么必须是035,后面再找找原因吧
bool DexFile:: Init(std::string* error_msg) {
if (! CheckMagicAndVersion(error_msg)) {
return false;
}
return true;
}
bool DexFile:: CheckMagicAndVersion(std::string* error_msg) const {
if (! IsMagicValid(header_->magic_)) {
std::ostringstream oss;
oss << "Unrecognized magic number in " << GetLocation() << ":"
<< " " << header_->magic_[0]
<< " " << header_->magic_[1]
<< " " << header_->magic_[2]
<< " " << header_->magic_[3];
*error_msg = oss.str();
return false;
}
if (! IsVersionValid(header_->magic_)) {
std::ostringstream oss;
oss << "Unrecognized version number in " << GetLocation() << ":"
<< " " << header_->magic_[4]
<< " " << header_->magic_[5]
<< " " << header_->magic_[6]
<< " " << header_->magic_[7];
*error_msg = oss.str();
return false;
}
return true;
}
bool DexFile::IsMagicValid(const byte* magic) {
return (memcmp(magic, kDexMagic, sizeof(kDexMagic)) == 0);
}
bool DexFile:: IsVersionValid(const byte* magic) {
const byte* version = &magic[sizeof(kDexMagic)];
return (memcmp(version, kDexMagicVersion, sizeof(kDexMagicVersion)) == 0);
}
}
3、/dalvik/libdex/DexFile.h
/* DEX file magic number */
#define DEX_MAGIC "dex\n"
/* current version, encoded in 4 bytes of ASCII */
#define DEX_MAGIC_VERS "036\0"
/*
* older but still-recognized version (corresponding to Android API levels 13 and earlier
*/
#define DEX_MAGIC_VERS_API_13 "035\0" =》老版本的magic version是035
/* same, but for optimized DEX header */
#define DEX_OPT_MAGIC "dey\n"
#define DEX_OPT_MAGIC_VERS "036\0" =》优化的dex文件,magic version是036
参考:
http://blog.csdn.net/luoshengyang/article/details/39307813
http://www.netmite.com/android/mydroid/dalvik/docs/dex-format.html
http://www.retrodev.com/android/dexformat.html
http://bbs.pediy.com/showthread.php?t=177114
http://blog.mssun.me/technology/android-art-runtime-2-dex2oat/
http://guoh.org/lifelog/2013/02/run-dalvik-on-x86/
一般dex文件头中,magic字段是“dex\n035\0”;
如果dex文件头中的magic字段,被修改成了“dex\n036\0”,使用adb install安装应用时,会报 Failure [INSTALL_FAILED_DEXOPT],如下日志:
E dex2oat : Failed to open dex from file descriptor for zip file '/data/app/com.test/base.apk': Failed to open dex file '/data/app/com.test/base.apk' from memory: Unrecognized version number in /data/app/com.test/base.apk: 0 3 6
android 5.0 源码
if (! DexFile::OpenFromZip(*zip_archive.get(), zip_location, &error_msg, &dex_files)) {
LOG(ERROR) << "Failed to open dex from file descriptor for zip file '" << zip_location
<< "': " << error_msg;
return EXIT_FAILURE;
}
2、/art/runtime/Dex_file.cc
namespace art {
const byte DexFile::kDexMagic[] = { 'd', 'e', 'x', '\n' };
const byte DexFile::kDexMagicVersion[] = { '0', '3', '5', '\0' }; ==》为什么必须是035,后面再找找原因吧
bool DexFile:: Init(std::string* error_msg) {
if (! CheckMagicAndVersion(error_msg)) {
return false;
}
return true;
}
bool DexFile:: CheckMagicAndVersion(std::string* error_msg) const {
if (! IsMagicValid(header_->magic_)) {
std::ostringstream oss;
oss << "Unrecognized magic number in " << GetLocation() << ":"
<< " " << header_->magic_[0]
<< " " << header_->magic_[1]
<< " " << header_->magic_[2]
<< " " << header_->magic_[3];
*error_msg = oss.str();
return false;
}
if (! IsVersionValid(header_->magic_)) {
std::ostringstream oss;
oss << "Unrecognized version number in " << GetLocation() << ":"
<< " " << header_->magic_[4]
<< " " << header_->magic_[5]
<< " " << header_->magic_[6]
<< " " << header_->magic_[7];
*error_msg = oss.str();
return false;
}
return true;
}
bool DexFile::IsMagicValid(const byte* magic) {
return (memcmp(magic, kDexMagic, sizeof(kDexMagic)) == 0);
}
bool DexFile:: IsVersionValid(const byte* magic) {
const byte* version = &magic[sizeof(kDexMagic)];
return (memcmp(version, kDexMagicVersion, sizeof(kDexMagicVersion)) == 0);
}
}
3、/dalvik/libdex/DexFile.h
/* DEX file magic number */
#define DEX_MAGIC "dex\n"
/* current version, encoded in 4 bytes of ASCII */
#define DEX_MAGIC_VERS "036\0"
/*
* older but still-recognized version (corresponding to Android API levels 13 and earlier
*/
#define DEX_MAGIC_VERS_API_13 "035\0" =》老版本的magic version是035
/* same, but for optimized DEX header */
#define DEX_OPT_MAGIC "dey\n"
#define DEX_OPT_MAGIC_VERS "036\0" =》优化的dex文件,magic version是036
参考:
http://blog.csdn.net/luoshengyang/article/details/39307813
http://www.netmite.com/android/mydroid/dalvik/docs/dex-format.html
http://www.retrodev.com/android/dexformat.html
http://bbs.pediy.com/showthread.php?t=177114
http://blog.mssun.me/technology/android-art-runtime-2-dex2oat/
http://guoh.org/lifelog/2013/02/run-dalvik-on-x86/