예제 #1
0
    def __parse(self, line, index, lid):
        self.buf = line
        self.index = index
        self.name = self.buf[1:]
        self.lid = lid

        log("LabelNode: " + self.name + " parsed!")
예제 #2
0
    def __parse(self, lines):
        #log("FieldNode: " + line + " parsing")
        self.buf = lines

        i = self.buf[0].find('=')
        segs = []
        if i > 0:
            segs = self.buf[0][:i].split()
            self.value = self.buf[0][i + 1:].strip()
        else:
            segs = self.buf[0].split()
        self.access = segs[1:-1]
        self.name, self.descriptor = segs[-1].split(':')
        log("FieldNode: " + self.name + " parsed!")
예제 #3
0
 def __parse(self, foldername):
     print("parsing %s..." % foldername)
     self.foldername = foldername
     for (path, dirs, files) in os.walk(self.foldername):
         for f in files:
             name = os.path.join(path, f)
             rel_path = os.path.relpath(name, self.foldername)
             if rel_path.find("annotation") == 0:
                 continue
             ext = os.path.splitext(name)[1]
             if ext != '.smali': continue
             self.smali_files.append(name)
             folder, fn = os.path.split(rel_path)
             self.classes.append(
                 classnode.ClassNode(filename=name, folder=folder))
     # print repr(self.smali_files)
     log("SmaliTree parsed!")
예제 #4
0
 def __parse(self, foldernames):
     for foldername in foldernames:
         print("parsing %s..." % foldername)
         for (path, dirs, files) in os.walk(foldername):
             ''''''
             # ToDo: exclude specific function need consideration for exact copy
             # if self._is_exluded(path, foldername):
             #     continue
             ''''''
             for f in files:
                 name = os.path.join(path, f)
                 rel_path = os.path.relpath(name, foldername)
                 if rel_path.find("annotation") == 0:
                     continue
                 ext = os.path.splitext(name)[1]
                 if ext != '.smali': continue
                 self.smali_files.append(name)
                 folder, fn = os.path.split(rel_path)
                 self.classes.append(
                     classnode.ClassNode(filename=name, folder=folder))
         log("SmaliTree parsed!")
예제 #5
0
    def __parse(self, lines):
        self.buf = lines
        segs = self.buf[0].split()
        self.access = segs[1:-1]
        self.descriptor = segs[-1]
        self.name = self.descriptor.split('(', 1)[0]
        self.__parse_desc()

        start = 1
        # .registers <register-num>
        segs = self.buf[1].split()
        if segs[0] == ".locals":
            self.registers = int(segs[1])
            start = 2

        index = 0
        lid = 0
        try_node_cache = []
        k = start
        while k < len(self.buf) - 1:
            line = self.buf[k]
            segs = line.split()
            if not self.synchronized and line.startswith("monitor"):
                self.synchronized = True
            # :<label-name>
            if segs[0][0] == ":":
                label = LabelNode(line, index, lid)
                self.labels[label.name] = label
                lid += 1
            elif line.startswith('.line') or segs[0] == ".prologue" or \
                line.startswith(".end local") or segs[0] == ".local" or \
                segs[0] == ".restart":
                pass
            # .catch <classname> {<label1> ..  <label2>} <label3>
            # .catchall {<label1> ..  <label2>} <label3>
            elif segs[0] == ".catch" or segs[0] == ".catchall": 
                try_node_cache.append(line)
            elif segs[0] == ".packed-switch" or segs[0] == ".sparse-switch":
                lb = self.labels[self.buf[k - 1][1:]]
                lines = [line]
                k += 1
                line = self.buf[k]
                lines.append(line)
                segs = line.split()
                while segs[0] != ".end":
                    k += 1
                    line = self.buf[k]
                    lines.append(line)
                    segs = line.split()
                SwitchNode(lines, lb)
            elif segs[0] == ".param":
                ''' Annotations added with parameters'''
                lines = [line]
                next_line = self.buf[k + 1]
                next_segs = next_line.split()
                if next_line.startswith(".annotation"):
                    # is possible that .annotation is not closed by '.end annotation'?
                    while next_line.startswith(".annotation"):
                        k += 1
                        while not next_line.startswith(".end annotation") or \
                        next_line.startswith(".end param"): # != ".end param":
                            lines.append(next_line)
                            k += 1
                            next_line = self.buf[k]
                        lines.append(next_line)
                        if next_line == ".end annotation":
                            next_line = self.buf[k + 1]
                            if next_line == ".end param":
                                lines.append(next_line)
                                k += 1
                self.parameters.append(CodeBlockNode(lines))
            elif segs[0] == ".array-data":
                lb = self.labels[self.buf[k - 1][1:]]
                lines = [line]
                k += 1
                line = self.buf[k]
                lines.append(line)
                segs = line.split()
                while segs[0] != ".end":
                    k += 1
                    line = self.buf[k]
                    lines.append(line)
                    segs = line.split()
                ArrayDataNode(lines, lb)
            elif segs[0] == ".annotation":
                k += 1
                lines = [line]
                line = self.buf[k]
                lines.append(line)
                segs = line.split()
                while (segs[0] != ".end" or segs[1] != "annotation"):
                    k += 1
                    line = self.buf[k]
                    lines.append(line)
                    segs = line.split()
                self.annotations.append(CodeBlockNode(lines))
            else:
                self.insns.append(insnnode.InsnNode(line))
                index += 1
            k += 1
        
        for line in try_node_cache:
            segs = line.split()
            start = self.labels[segs[-4][2:]]
            end = self.labels[segs[-2][1:-1]]
            handler = self.labels[segs[-1][1:]]
            self.tries.append(TryNode(line, start, end, handler))
        try_node_cache = []

        if self.name == "<init>":
            self.is_constructor = True
        log("MethodNode: " + self.name + " parsed!")
예제 #6
0
    def __parse(self, file_path, buf, folder):
        if file_path:
            self.file_path = file_path
            f = open(self.file_path, 'r', encoding='utf-8')
        elif buf:
            f = StringIO.StringIO(buf)
        else:
            return

        self.folder = folder
        self.full_folder, self.file_name = os.path.split(file_path)

        line = f.readline()
        while line:
            if line.isspace():
                line = f.readline()
                continue
            line = line.strip()
            segs = line.split()
            # .source <source-file>
            if segs[0] == ".source":
                self.source = ' '.join(segs[1:])
            # .class <access-spec> <class-name>
            elif segs[0] == ".class":
                self.name = segs[-1]
                # <access-spec>: public, final, super, interface, abstract
                self.access = segs[1:-1]
            # .super <class-name>
            elif segs[0] == ".super":
                self.super_name = segs[1]
            elif segs[0] == ".interface":
                print("can't parse .interface")
                sys.exit(1)
            elif segs[0] == ".implements":
                self.implements.append(segs[1])
            elif segs[0] == ".field":
                lines = [line]
                line = f.readline()
                if not line.isspace():
                    line = line.strip()
                    annotation_lines = []
                    if line.startswith(".annotation"):
                        while not line.startswith(".end field"):
                            annotation_lines.append(line)
                            line = f.readline()
                            if line.isspace():
                                line = f.readline()
                            line = line.strip()

                    if line == ".end field":
                        # annotations is inside a field
                        lines.extend(annotation_lines)
                        lines.append(line)
                    else:
                        # when annotations are not included inside the field
                        self.annotations.append(CodeBlockNode(annotation_lines))
                self.fields.append(FieldNode(lines))
                continue
            elif segs[0] == ".method":
                lines = [line]
                line = f.readline()
                while line:
                    if line.isspace():
                        line = f.readline()
                        continue
                    line = line.strip()
                    lines.append(line)
                    segs = line.split(None, 2)
                    if segs[0] == ".end" and segs[1] == "method":
                        break
                    line = f.readline()
                self.methods.append(methodnode.MethodNode(lines))
            elif segs[0] == ".annotation":
                # there may be subannotations
                lines = [line]
                line = f.readline()
                while line:
                    if line.isspace():
                        line = f.readline()
                        continue
                    line = line.strip()
                    lines.append(line)
                    segs = line.split(None, 2)
                    if segs[0] == ".end" and segs[1] == "annotation":
                        break
                    line = f.readline()
                self.annotations.append(CodeBlockNode(lines))
            elif segs[0] == '#':
                if len(segs) > 1 and segs[1] == 'annotations':
                    self.annotations_comment = line
                if len(segs) > 2 and segs[2] == 'fields':
                    self.fields_comment = line
                if len(segs) > 2 and segs[2] == 'methods':
                    self.methods_comment = line
                pass
            line = f.readline()
        f.close()
        log("ClassNode: " + self.name + " parsed!")