/* SAAF: A static analyzer for APK files. * Copyright (C) 2013 syssec.rub.de * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see <http://www.gnu.org/licenses/>. */ package de.rub.syssec.saaf.gui.editor; import java.awt.Color; import java.io.File; import java.util.Vector; import javax.swing.text.DefaultStyledDocument; import javax.swing.text.MutableAttributeSet; import javax.swing.text.SimpleAttributeSet; import javax.swing.text.Style; import javax.swing.text.StyleConstants; import javax.swing.text.StyleContext; import de.rub.syssec.saaf.misc.Highlight; import de.rub.syssec.saaf.model.application.ApplicationInterface; /** * TODO: Revise this. Faster, better .... */ public class SmaliTextStyler { private static StyleContext sc = new StyleContext(); private static Style annotation; private static Style vars; private static Style jump; private static Style variablenStyle; private static Style opcode; private static MutableAttributeSet link; private String text; public SmaliTextStyler() { /* empty */ } static { annotation = sc.addStyle("annotation", sc.getStyle(StyleContext.DEFAULT_STYLE)); StyleConstants.setForeground(annotation, Color.gray); variablenStyle = sc.addStyle("VariablenStyle", null); StyleConstants.setForeground(variablenStyle, Color.green); opcode = sc.addStyle("opcode", null); StyleConstants.setForeground(opcode, Color.red); jump = sc.addStyle("jump", null); StyleConstants.setForeground(jump, Color.green); vars = sc.addStyle("vars", null); StyleConstants.setForeground(vars, Color.blue); link = new SimpleAttributeSet(); link.addAttribute(LinkEditorKit.LINK, "true"); link.addAttribute(StyleConstants.Underline, Boolean.TRUE); } /** * FIXME: Remove app reference, highlighting is slow * * @param app * @param doc * @param text_string * @return */ protected void highlightStrings(ApplicationInterface app, DefaultStyledDocument doc, String text_string) { text = text_string; // System.out.println(Application.smali_dir.getAbsolutePath()); // click stuff Vector<File> smaliClasss = app.getAllRawSmaliFiles(true); for (int i = 0; i < smaliClasss.size(); i++) { String class_name = smaliClasss .get(i) .getAbsolutePath() .substring( app.getBytecodeDirectory().getAbsolutePath().length(), smaliClasss.get(i).getAbsolutePath().length()); class_name = " L" + class_name.substring(1, class_name.length() - 6); linehighlight(doc, class_name, link); // System.out.println(smaliClasss.get(i).getAbsolutePath()); // System.out.println(class_name); } // Highlight(doc, "Lorg/me", link); // Highlight(doc, ".end", annotation); // Highlight(doc, ".method", annotation); // Highlight(doc, "invoke-direct", opcode); // linehighlight(doc, ".local", annotation); // linehighlight(doc, ".parameter", annotation); // linehighlight(doc, ".prologue", annotation); // linehighlight(doc, ".line", annotation); Vector<String> commands = Highlight.OP_CODES; for (int i = 0; i < commands.size(); i++) { highlight(doc, commands.get(i), opcode); } commands = Highlight.ANNOTATIONS; for (int i = 0; i < commands.size(); i++) { linehighlight(doc, commands.get(i), annotation); } Vector<String> signs = new Vector<String>(); signs.add("v"); signs.add("p"); for (int i = 0; i < signs.size(); i++) { for (int z = 100; z >= 0; z--) { highlight(doc, " " + signs.get(i) + z + "\n", vars); highlight(doc, " " + signs.get(i) + z + ",", vars); highlight(doc, " " + signs.get(i) + z + "}", vars); highlight(doc, "{" + signs.get(i) + z + ",", vars); highlight(doc, "{" + signs.get(i) + z + "}", vars); highlight(doc, "{" + signs.get(i) + z + " ..", vars); } } Vector<String> jumps = new Vector<String>(); jumps.add(":cond_"); jumps.add(":goto_"); jumps.add(":catch_"); jumps.add(":catchall_"); for (int i = 0; i < jumps.size(); i++) { for (int z = 100; z >= 0; z--) { highlight(doc, " " + jumps.get(i) + z, jump); } } } private void linehighlight(DefaultStyledDocument doc, String pattern, MutableAttributeSet type) { int pos = 0; // Search for pattern while ((pos = text.indexOf(pattern, pos)) >= 0) { // Create highlighter using private painter and apply around pattern // pos +1 damit leerzeichen vorher net unterstrichen wird -> wichtig // jedoch für die Erkennung doc.setCharacterAttributes(pos + 1, text.indexOf("\n", pos) - pos, type, false); pos += pattern.length(); } } private void highlight(DefaultStyledDocument doc, String pattern, MutableAttributeSet type) { int pos = 0; // Search for pattern while ((pos = text.indexOf(pattern, pos)) >= 0) { // Create highlighter using private painter and apply around pattern doc.setCharacterAttributes(pos, pattern.length(), type, false); pos += pattern.length(); } } }