示例#1
0
    def run(self, ctx):
        OUTDIR = IO.expandPath('~/JEB_PROJECT_BINARY_EXTRACTED')

        prj = ctx.getMainProject()
        print('=> Dumping binary units of project to directory: %s' % OUTDIR)

        for art in prj.getLiveArtifacts():
            for unit in art.getUnits():
                self.checkUnit(unit,
                               OUTDIR + '/' + art.getArtifact().getName())
示例#2
0
  def checkUnit(self, unit, basename, level=0):    
    basename2 = basename+'/'+unit.getName()

    unitsize = -1
    if isinstance(unit, IBinaryUnit):
      unitinput = unit.getInput()
      print('Creating dir: %s' % basename)
      if not os.path.exists(basename):
        os.makedirs(basename)
      try:
        print('Writing file: %s (%db)' % (basename2, unitinput.getCurrentSize()))
        f = File(basename2)
        data = IO.readInputStream(unitinput.getStream())
        IO.writeFile(f, data, 0, len(data))
      except Exception as e:
        print('An error occurred: %s' % e)
      basename2 = basename2 + '_sub'

    # recurse over children units
    for c in unit.getChildren():
      self.checkUnit(c, basename2, level + 1)
  def checkUnit(self, unit, basename, level=0):    
    basename2 = basename+'/'+unit.getName()

    unitsize = -1
    if isinstance(unit, IBinaryUnit):
      unitinput = unit.getInput()
      print('Creating dir: %s' % basename)
      if not os.path.exists(basename):
        os.makedirs(basename)
      try:
        print('Writing file: %s (%db)' % (basename2, unitinput.getCurrentSize()))
        f = File(basename2)
        data = IO.readInputStream(unitinput.getStream())
        IO.writeFile(f, data, 0, len(data))
      except Exception as e:
        print('An error occurred: %s' % e)
      basename2 = basename2 + '_sub'

    # recurse over children units
    for c in unit.getChildren():
      self.checkUnit(c, basename2, level + 1)
示例#4
0
  def decompileCodeUnit(self, codeUnit):
    # make sure the code unit is processed
    if not codeUnit.isProcessed():
      if not codeUnit.process():
        print('The code unit cannot be processed!')
        return

    decomp = DecompilerHelper.getDecompiler(codeUnit)
    if not decomp:
      print('There is no decompiler available for code unit %s' % codeUnit)
      return

    outdir = os.path.join(self.outputDir, codeUnit.getName() + '_decompiled')
    print('Output folder: %s' % outdir)

    if self.decompileNative and isinstance(codeUnit, INativeCodeUnit):
      for m in codeUnit.getMethods():
        a = m.getAddress()
        print('Decompiling: %s' % a)
        srcUnit = decomp.decompile(a)
        if srcUnit:
          self.exportSourceUnit(srcUnit, outdir)

    elif self.decompileDex and isinstance(codeUnit, IDexUnit):
      exp = DexDecompilerExporter(decomp)
      exp.setOutputFolder(IO.createFolder(outdir))

      # limit to 1 minute max per method
      exp.setMethodTimeout(1 * 60000)

      # limit to 15 minutes (total)
      exp.setTotalTimeout(15 * 60000)

      # set a callback to output real-time information about what's being decompiled
      from com.pnfsoftware.jeb.util.base import ProgressCallbackAdapter
      class DecompCallback(ProgressCallbackAdapter):
        def message(__self__, msg):
          print(msg)
      exp.setCallback(DecompCallback())

      # decompile & export
      if not exp.export():
        cnt = len(exp.getErrors())
        i = 1
        for sig, err in exp.getErrors().items():
          print('%d/%d DECOMPILATION ERROR: METHOD %s: %s' % (i, cnt, sig, err))
          i += 1
示例#5
0
    def decompileCodeUnit(self, codeUnit):
        # make sure the code unit is processed
        if not codeUnit.isProcessed():
            if not codeUnit.process():
                print('The code unit cannot be processed!')
                return

        decomp = DecompilerHelper.getDecompiler(codeUnit)
        if not decomp:
            print('There is no decompiler available for code unit %s' %
                  codeUnit)
            return

        outdir = os.path.join(self.outputDir,
                              codeUnit.getName() + '_decompiled')
        print('Output folder: %s' % outdir
              )  # created only if necessary, i.e. some contents was exported

        if not (
            (isinstance(codeUnit, INativeCodeUnit) and self.decompileNative) or
            (isinstance(codeUnit, IDexUnit) and self.decompileDex)):
            print('Skipping code unit: %s' %
                  UnitUtil.buildFullyQualifiedUnitPath(codeUnit))
            return

        # DecompilerExporter object
        exp = decomp.getExporter()
        exp.setOutputFolder(IO.createFolder(outdir))
        # limit to 1 minute max per method
        exp.setMethodTimeout(1 * 60000)
        # limit to 15 minutes (total)
        exp.setTotalTimeout(15 * 60000)

        # set a callback to output real-time information about what's being decompiled
        class DecompCallback(ProgressCallbackAdapter):
            def message(self, msg):
                print('%d/%d: %s' % (self.getCurrent(), self.getTotal(), msg))

        exp.setCallback(DecompCallback())
        # decompile & export
        if not exp.export():
            cnt = len(exp.getErrors())
            i = 1
            for sig, err in exp.getErrors().items():
                print('%d/%d DECOMPILATION ERROR: METHOD %s: %s' %
                      (i, cnt, sig, err))
                i += 1
示例#6
0
  def run(self, ctx):
    self.ctx = ctx

    engctx = ctx.getEnginesContext()
    if not engctx:
      print('Back-end engines not initialized')
      return

    projects = engctx.getProjects()
    if not projects:
      print('There is no opened project')
      return

    OUTDIR = IO.expandPath('~/JEB_PROJECT_BINARY_EXTRACTED')
    prj = projects[0]
    print('=> Dumping binary units of project to directory: %s' % OUTDIR)

    for art in prj.getLiveArtifacts():
      for unit in art.getUnits():
        self.checkUnit(unit, OUTDIR+'/'+art.getArtifact().getName())
  def run(self, ctx):
    self.ctx = ctx

    engctx = ctx.getEnginesContext()
    if not engctx:
      print('Back-end engines not initialized')
      return

    projects = engctx.getProjects()
    if not projects:
      print('There is no opened project')
      return

    OUTDIR = IO.expandPath('~/JEB_PROJECT_BINARY_EXTRACTED')
    prj = projects[0]
    print('=> Dumping binary units of project to directory: %s' % OUTDIR)

    for art in prj.getLiveArtifacts():
      for unit in art.getUnits():
        self.checkUnit(unit, OUTDIR+'/'+art.getArtifact().getName())
示例#8
0
    def run(self, ctx):

        # retrieve RTTI unit
        prj = ctx.getMainProject()
        if not prj:
            print('Need a project')
            return

        units = prj.findUnits(IBinaryUnit)
        if not units or len(units) == 0:
            print('Need RTTI unit')
            return

        rttiUnit = None
        for unit in units:
            if unit.getName() == 'run-time type information':
                rttiUnit = unit
        if not rttiUnit:
            print('Need RTTI unit')

        data = IO.readInputStream(rttiUnit.getInput().getStream())
        rttiText = ''.join(chr(c) for c in data)

        # parsing
        g = Digraph.create()
        curId = 0
        classToId = dict()
        virtualEdges = list()  # [[childId, parentId]]
        lines = rttiText.splitlines()[2:]  # skip header
        for line in lines:
            line = line.strip()[:-1]  # beautify
            if not line.startswith('class'):
                continue
            classes = line.split(CLASS_SEPARATOR)
            if len(classes) > 2:
                print('error: malformed line (%s)' % line)
                continue

            # register base class id
            baseClassName = classes[0][6:]
            if IGNORE_STD and baseClassName.startswith('std::'):
                continue
            if baseClassName not in classToId.keys():
                g.v(curId, None, baseClassName)
                classToId[baseClassName] = curId
                curId += 1
            print('baseClassName=%s' % baseClassName)

            # add edges for each parent, if any
            if len(classes) == 1:
                continue
            for parent in classes[1].split(PARENT_SEPARATOR):
                parentStr = parent.split()
                if len(parentStr) < 2:
                    print('error: malformed line (%s)' % line)
                    continue
                isPublic = parentStr[0] == 'public'
                isVirtual = parentStr[1] == 'virtual'
                parentStartIndex = 7 if isPublic else 8
                parentStartIndex += 8 if isVirtual else 0
                parentName = parent[parentStartIndex:]

                print('  parentName=%s, isPublic = %d, isVirtual = %d' %
                      (parentName, isPublic, isVirtual))

                if parentName not in classToId.keys():
                    g.v(curId, None, parentName)
                    classToId[parentName] = curId
                    curId += 1

                g.e(classToId[baseClassName], classToId[parentName])
                if isVirtual:
                    virtualEdges.append(
                        [classToId[baseClassName], classToId[parentName]])

        class Ext(GraphDialogExtensions):
            def getEdgeStyle(self, vertexId0, vertexId1):
                if [vertexId0, vertexId1] in virtualEdges:
                    # dashed edges to represent virtual inheritance
                    return EdgeStyle.DASHED
                return EdgeStyle.SOLID

            def getVertexShape(self, vertexId):
                return VertexShape.SQUARE_FILLED

        g.done()
        ctx.displayGraph('RTTI Class Relationship Graph', g, Ext())