2015-10-14 20:01:52 +00:00
|
|
|
/*
|
|
|
|
* (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
|
|
|
|
*
|
|
|
|
*/
|
|
|
|
|
2017-05-21 14:58:16 +00:00
|
|
|
package com.logicalhacking.dasca.crosslanguage.builder
|
2015-10-14 20:01:52 +00:00
|
|
|
|
|
|
|
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 _ =>
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|