本文主要是介绍简单的从odex或oat文件中解压出dex文件,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!
目前解压这两种文件的方法都是用apktool,然而还有一种简单的方法。
odex和oat是dex文件的一种优化,但是解压他们的方法是相同的。
首先用WinHex打开一个odex文件,我们可以看到dex 035这个字符串,其实这个地方就是dex文件开始的位置,根据dex文件的数据结构可知向后再偏移32个字节就是dex文件的大小。于是从头的偏移位置向后取出dex大小个字节就是dex文件的内容。
我们再来看boot.oat这个文件,打开后搜索字符串dex,找到dex 035,一个boot.oat中有多个dex文件头,说明boot.oat中有多个dex文件,而普通oat文件里一般只有一个。我们可以用同样的方法将他们解压出来
于是我们可以写一个java程序,用于解压odex和oat文件。基本思想是在内存中搜索dex文件头,记录下偏移。再获取dex文件大小。然后获取这块区域的字节,写出文件。
import java.io.IOException;
import java.io.RandomAccessFile;
import java.nio.ByteBuffer;
import java.nio.MappedByteBuffer;
import java.nio.channels.FileChannel;public class DEODEX {/*** 从内存中搜索数据,并返回在内存中的偏移***/public static int findPos(MappedByteBuffer data, int offset, byte[] found) {for (int i = offset; i < data.capacity(); i++){boolean bFound = true;for (int j = 0; j < found.length; j++) {bFound = bFound && data.get(i + j) == found[j];}if (bFound) {return i;}}return -1;}private static void write_to_file(MappedByteBuffer buffer, int offset, int dexsize, int file_count, String out)throws IOException {RandomAccessFile file = new RandomAccessFile(String.format("%s%02d.dex", out, file_count), "rw");FileChannel channel = file.getChannel();byte[] data = new byte[dexsize];buffer.position(offset);buffer.get(data);ByteBuffer bw = ByteBuffer.wrap(data);channel.write(bw);channel.close();file.close();}public static void oat2dex(String in, String out) throws IOException {RandomAccessFile raf = new RandomAccessFile(in, "rw");// 内存映射文件FileChannel channel = raf.getChannel();MappedByteBuffer buffer = channel.map(FileChannel.MapMode.READ_WRITE, 0, raf.length());int file_count = 0;int length = (int) raf.length();//dex头byte[] magic = { 0x64, 0x65, 0x78, 0x0A, 0x30, 0x33, 0x35, 0x00 };int offset = 0;while (offset != -1) {offset = findPos(buffer, offset + 8, magic);if (offset == -1) { // 未发现dex magicbreak;}int dexsize = (buffer.get(offset + 35) << 24) | (buffer.get(offset + 34) & 0xff) << 16| (buffer.get(offset + 33) & 0xff) << 8 | (buffer.get(offset + 32) & 0xff);if (offset + dexsize > length)continue;write_to_file(buffer, offset, dexsize, ++file_count, out);}channel.close();raf.close();}
}
调用这个方法后,我们得到了dex文件
OK,这是boot.oat中的文件,随便拿一个出来测试一下。转换成jar,用jdgui打开
大功告成
这篇关于简单的从odex或oat文件中解压出dex文件的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!