All Downloads are FREE. Search and download functionalities are using the official Maven repository.

io.joern.ghidra2cpg.passes.x86.X86FunctionPass.scala Maven / Gradle / Ivy

The newest version!
package io.joern.ghidra2cpg.passes.x86

import ghidra.program.model.listing.{Function, Program}
import io.joern.ghidra2cpg.utils.Decompiler
import io.joern.ghidra2cpg.passes.FunctionPass
import io.joern.ghidra2cpg.processors.X86Processor
import io.joern.ghidra2cpg.utils.Utils.*
import io.shiftleft.codepropertygraph.generated.Cpg
import io.shiftleft.codepropertygraph.generated.{EdgeTypes, nodes}
import io.shiftleft.codepropertygraph.generated.nodes.{NewBlock, NewMethod}

import scala.language.implicitConversions

class X86FunctionPass(
  currentProgram: Program,
  filename: String,
  functions: List[Function],
  cpg: Cpg,
  decompiler: Decompiler
) extends FunctionPass(X86Processor, currentProgram, functions, cpg, decompiler) {

  override def handleBody(
    diffGraphBuilder: DiffGraphBuilder,
    function: Function,
    methodNode: NewMethod,
    blockNode: NewBlock
  ): Unit = {
    val instructions = getInstructions(function)
    if (instructions.nonEmpty) {
      var prevInstructionNode = addCallOrReturnNode(instructions.head)
      handleArguments(diffGraphBuilder, instructions.head, prevInstructionNode, function)
      diffGraphBuilder.addEdge(blockNode, prevInstructionNode, EdgeTypes.AST)
      diffGraphBuilder.addEdge(methodNode, prevInstructionNode, EdgeTypes.CFG)
      instructions.drop(1).foreach { instruction =>
        val instructionNode = addCallOrReturnNode(instruction)
        diffGraphBuilder.addNode(instructionNode)
        handleArguments(diffGraphBuilder, instruction, instructionNode, function)
        diffGraphBuilder.addEdge(blockNode, instructionNode, EdgeTypes.AST)
        // Not connecting the previous instruction,
        // if it is an unconditional jump
        // JMP is x86 specific
        if (!prevInstructionNode.code.startsWith("JMP")) {
          diffGraphBuilder.addEdge(prevInstructionNode, instructionNode, EdgeTypes.CFG)
        }
        prevInstructionNode = instructionNode
      }
    }
  }
  override def runOnPart(diffGraphBuilder: DiffGraphBuilder, function: Function): Unit = {
    // we need it just once with default settings
    val blockNode: NewBlock = nodes.NewBlock().code("").order(0)
    val methodNode =
      createMethodNode(decompiler, function, filename, checkIfExternal(currentProgram, function.getName))
    val localGraphBuilder = Cpg.newDiffGraphBuilder
    val methodReturn      = createReturnNode()
    localGraphBuilder.addNode(methodNode)
    localGraphBuilder.addNode(blockNode)
    localGraphBuilder.addEdge(methodNode, blockNode, EdgeTypes.AST)
    localGraphBuilder.addNode(methodReturn)
    localGraphBuilder.addEdge(methodNode, methodReturn, EdgeTypes.AST)
    handleParameters(localGraphBuilder, function, methodNode)
    handleLocals(localGraphBuilder, function, blockNode)
    handleBody(localGraphBuilder, function, methodNode, blockNode)
    diffGraphBuilder.absorb(localGraphBuilder)

  }

}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy