DASCA/com.logicalhacking.dasca.cr.../src/main/scala/com/logicalhacking/dasca/crosslanguage/builder/DalvikLineNumberCalculator....

58 lines
2.1 KiB
Scala

/*
* (C) Copyright 2010-2015 SAP SE.
*
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
*/
package com.logicalhacking.dasca.crosslanguage.builder
import java.io.File
import scala.collection.JavaConverters._
import scala.io.Source
import scala.{ Option => ? }
import com.ibm.wala.dalvik.classLoader.DexIMethod
import com.ibm.wala.ipa.callgraph.CallGraph
import org.apache.commons.io.FileUtils
object DalvikLineNumberCalculator {
val MethodRegex = """\s*\.method (.+)""".r
val LineRegex = """\s*\.line ([0-9]+)\s*""".r
val AnnotationRegex = """\s*\.annotation .+""".r
val EndAnnotationRegex = """\s*\.end annotation\s*""".r
val InstructionRegex = """\s*[a-zA-Z].*""".r
def setLineNumbers(apkUnzipDir: File, cg: CallGraph) = {
for (
node <- cg.iterator().asScala;
method <- ?(node.getMethod).collect({ case m: DexIMethod => m })
) {
val path = method.getDeclaringClass.getName.toString().substring(1) + ".smali"
val smaliFile = new File(new File(apkUnzipDir, "smali"), path)
val methodString = method.getReference().getName().toString() + node.getMethod().getReference().getDescriptor()
var lastLine = -1
var inCorrectMethod = false
var correctMethodFound = false
var inAnnotation = false
var instCounter = 0
for (line <- FileUtils.readLines(smaliFile).asScala.takeWhile(_ => !correctMethodFound || inCorrectMethod)) line match {
case MethodRegex(rest) => {
inCorrectMethod = rest.endsWith(methodString)
if (inCorrectMethod) correctMethodFound = true
}
case LineRegex(line) if inCorrectMethod => lastLine = line.toInt
case AnnotationRegex() => inAnnotation = true
case EndAnnotationRegex() => inAnnotation = false
case InstructionRegex() if (inCorrectMethod && !inAnnotation) => {
method.setLineNumber(instCounter, lastLine)
instCounter += 1
}
case _ =>
}
}
}
}