参考文章:http://www.freebuf.com/articles/terminal/166307.html
国外大神源码:https://github.com/CheckPointSW/android_unpacker
系统源代码:Android6.0.1_r2
修改源码中的dex_file.cc文件:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 |
//------------------------------------------------------------------ // DEX file unpacking //------------------------------------------------------------------ struct stat st; // let's limit processing file list LOG(WARNING) << "File_magic: Filename: "<<filename; if (strstr(filename, "/data/data") != NULL) { LOG(WARNING) << "File_magic: DEX file unpacking launched"; char* fn_out = new char[PATH_MAX]; strcpy(fn_out, filename); strcat(fn_out, "__unpacked_dex"); int fd_out = open(fn_out, O_WRONLY | O_CREAT | O_EXCL, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH); if (!fstat(fd.get(), &st)) { char* addr = (char*)mmap(NULL, st.st_size, PROT_READ, MAP_PRIVATE, fd.get(), 0); int ret=write(fd_out, addr, st.st_size); ret+=1; munmap(addr, st.st_size); } close(fd_out); delete[] fn_out; } else { LOG(WARNING) << "File_magic: DEX file unpacking not launched"; } //------------------------------------------------------------------ int n = TEMP_FAILURE_RETRY(read(fd.get(), magic, sizeof(*magic))); if (n != sizeof(*magic)) { *error_msg = StringPrintf("Failed to find magic in '%s'", filename); return -1; } if (lseek(fd.get(), 0, SEEK_SET) != 0) { *error_msg = StringPrintf("Failed to seek to beginning of file '%s' : %s", filename, strerror(errno)); return -1; } return fd.release(); } bool DexFile::GetChecksum(const char* filename, uint32_t* checksum, std::string* error_msg) { CHECK(checksum != nullptr); uint32_t magic; // Strip ":...", which is the location const char* zip_entry_name = kClassesDex; const char* file_part = filename; std::string file_part_storage; if (DexFile::IsMultiDexLocation(filename)) { file_part_storage = GetBaseLocation(filename); file_part = file_part_storage.c_str(); zip_entry_name = filename + file_part_storage.size() + 1; DCHECK_EQ(zip_entry_name[-1], kMultiDexSeparator); } ScopedFd fd(OpenAndReadMagic(file_part, &magic, error_msg)); if (fd.get() == -1) { DCHECK(!error_msg->empty()); return false; } if (IsZipMagic(magic)) { std::unique_ptr<ZipArchive> zip_archive( ZipArchive::OpenFromFd(fd.release(), filename, error_msg)); if (zip_archive.get() == nullptr) { *error_msg = StringPrintf("Failed to open zip archive '%s' (error msg: %s)", file_part, error_msg->c_str()); return false; } std::unique_ptr<ZipEntry> zip_entry(zip_archive->Find(zip_entry_name, error_msg)); if (zip_entry.get() == nullptr) { *error_msg = StringPrintf("Zip archive '%s' doesn't contain %s (error msg: %s)", file_part, zip_entry_name, error_msg->c_str()); return false; } *checksum = zip_entry->GetCrc32(); return true; } if (IsDexMagic(magic)) { std::unique_ptr<const DexFile> dex_file( DexFile::OpenFile(fd.release(), filename, false, error_msg)); if (dex_file.get() == nullptr) { return false; } + //------------------------------------------------------------------ + // DEX file unpacking + //------------------------------------------------------------------ + + struct stat st; + // let's limit processing file list + + LOG(WARNING) << "File_magic: Filename: "<<filename; + if (strstr(filename, "/data/data") != NULL) { + LOG(WARNING) << "File_magic: DEX file unpacking launched"; + char* fn_out = new char[PATH_MAX]; + strcpy(fn_out, filename); + strcat(fn_out, "__unpacked_dex"); + + int fd_out = open(fn_out, O_WRONLY | O_CREAT | O_EXCL, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH); + + if (!fstat(fd.get(), &st)) { + char* addr = (char*)mmap(NULL, st.st_size, PROT_READ, MAP_PRIVATE, fd.get(), 0); + int ret=write(fd_out, addr, st.st_size); + ret+=1; + munmap(addr, st.st_size); + } + + close(fd_out); + delete[] fn_out; + } else { + LOG(WARNING) << "File_magic: DEX file unpacking not launched"; + } + //------------------------------------------------------------------ + int n = TEMP_FAILURE_RETRY(read(fd.get(), magic, sizeof(*magic))); if (n != sizeof(*magic)) { *error_msg = StringPrintf("Failed to find magic in '%s'", filename); |
然后就是编译源代码,烧录ROM,即可。
使用方式:
安装APK,运行APP,然后adb shell
一般会在/data/data/com.xxx.xxx/的目录下面,能够找到xxxxclasses.dex__unpacked_oat 的文件名,使用adb pull从android目录中拖出,使用Jadx或JEB工具打开即可。