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!")
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!")
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!")
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!")
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!")
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!")