DalvikBytecodeAnalysis/src/main/scala/parser/Parser.scala

80 lines
2.0 KiB
Scala

package parser
import java.io.File
import dex._
import org.jf.dexlib2.dexbacked.{
DexBackedClassDef,
DexBackedDexFile,
DexBackedField,
DexBackedMethod
}
import org.jf.dexlib2.{DexFileFactory, Opcodes}
import utils.Utils
import scala.collection.JavaConverters._
class Parser(apkLocation: String) {
val apkFile = new File(apkLocation)
val dexFile: DexBackedDexFile =
DexFileFactory.loadDexFile(apkFile, Opcodes.forApi(21))
def dexApp: DexApp = {
val classes = parseClasses
new DexApp(
new AndroidXmlParser(apkLocation, classes).parseManifest(),
classes,
new EntryPointsProvider(classes).entryPoints(),
new SourcesSinksProvider().sourcesSinks()
)
}
private def parseClasses: Seq[DexClass] = {
dexFile.getClasses.asScala.toSeq
.filter(classFilter())
.map(
c =>
DexClass(
c.getType,
c.getSuperclass,
c.getInterfaces.asScala,
classFields(c.getFields.asScala.toSeq),
classMethods(c.getMethods.asScala.toSeq)
))
}
private def classFilter(): DexBackedClassDef => Boolean =
(t: DexBackedClassDef) => !t.getType.startsWith("Landroid/support")
private def methodFilter(): DexBackedMethod => Boolean =
(m: DexBackedMethod) => m.getImplementation != null
private def classFields(fields: Seq[DexBackedField]): Seq[DexField] =
fields
.map(
f =>
DexField(
f.getName,
Utils.removeClassPrefix(f.toString),
DexType(f.getType)
))
private def classMethods(methods: Seq[DexBackedMethod]): Seq[DexMethod] = {
methods
.filter(methodFilter())
.map(
m =>
DexMethod(
m.getName,
Utils.removeClassPrefix(m.toString),
m.getParameterTypes.asScala.map(t => DexType(t)),
DexType(m.getReturnType),
m.getImplementation.getRegisterCount,
m.getParameters.size(),
m.getImplementation.getInstructions.asScala.toSeq
))
}
}