Package jadx.core.utils.files

Source Code of jadx.core.utils.files.InputFile

package jadx.core.utils.files;

import jadx.core.utils.AsmUtils;
import jadx.core.utils.exceptions.DecodeException;
import jadx.core.utils.exceptions.JadxException;

import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.jar.JarOutputStream;
import java.util.zip.ZipEntry;
import java.util.zip.ZipFile;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.android.dex.Dex;

public class InputFile {
  private static final Logger LOG = LoggerFactory.getLogger(InputFile.class);

  private final File file;
  private final Dex dexBuf;

  public InputFile(File file) throws IOException, DecodeException {
    if (!file.exists()) {
      throw new IOException("File not found: " + file.getAbsolutePath());
    }
    this.file = file;
    this.dexBuf = loadDexBuffer();
  }

  private Dex loadDexBuffer() throws IOException, DecodeException {
    String fileName = file.getName();
    if (fileName.endsWith(".dex")) {
      return new Dex(file);
    }
    if (fileName.endsWith(".class")) {
      return loadFromClassFile(file);
    }
    if (fileName.endsWith(".apk")) {
      Dex dex = loadFromZip(file);
      if (dex == null) {
        throw new IOException("File 'classes.dex' not found in file: " + file);
      }
      return dex;
    }
    if (fileName.endsWith(".jar")) {
      // check if jar contains 'classes.dex'
      Dex dex = loadFromZip(file);
      if (dex != null) {
        return dex;
      }
      return loadFromJar(file);
    }
    throw new DecodeException("Unsupported input file format: " + file);
  }

  private static Dex loadFromJar(File jarFile) throws DecodeException {
    try {
      LOG.info("converting to dex: {} ...", jarFile.getName());
      JavaToDex j2d = new JavaToDex();
      byte[] ba = j2d.convert(jarFile.getAbsolutePath());
      if (ba.length == 0) {
        throw new JadxException(j2d.isError() ? j2d.getDxErrors() : "Empty dx output");
      } else if (j2d.isError()) {
        LOG.warn("dx message: {}", j2d.getDxErrors());
      }
      return new Dex(ba);
    } catch (Throwable e) {
      throw new DecodeException("java class to dex conversion error:\n " + e.getMessage(), e);
    }
  }

  private static Dex loadFromZip(File file) throws IOException {
    ZipFile zf = new ZipFile(file);
    ZipEntry dex = zf.getEntry("classes.dex");
    if (dex == null) {
      zf.close();
      return null;
    }
    ByteArrayOutputStream bytesOut = new ByteArrayOutputStream();
    InputStream in = null;
    try {
      in = zf.getInputStream(dex);
      byte[] buffer = new byte[8192];
      int count;
      while ((count = in.read(buffer)) != -1) {
        bytesOut.write(buffer, 0, count);
      }
    } finally {
      if (in != null) {
        in.close();
      }
      zf.close();
    }
    return new Dex(bytesOut.toByteArray());
  }

  private static Dex loadFromClassFile(File file) throws IOException, DecodeException {
    File outFile = File.createTempFile("jadx-tmp-", System.nanoTime() + ".jar");
    outFile.deleteOnExit();
    FileOutputStream out = null;
    JarOutputStream jo = null;
    try {
      out = new FileOutputStream(outFile);
      jo = new JarOutputStream(out);
      String clsName = AsmUtils.getNameFromClassFile(file);
      if (clsName == null) {
        throw new IOException("Can't read class name from file: " + file);
      }
      FileUtils.addFileToJar(jo, file, clsName + ".class");
    } finally {
      if (jo != null) {
        jo.close();
      }
      if (out != null) {
        out.close();
      }
    }
    return loadFromJar(outFile);
  }

  public File getFile() {
    return file;
  }

  public Dex getDexBuffer() {
    return dexBuf;
  }

  @Override
  public String toString() {
    return file.toString();
  }
}
TOP

Related Classes of jadx.core.utils.files.InputFile

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.