/* 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.frame;
import java.awt.Dimension;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.Vector;
import javax.swing.JButton;
import javax.swing.JInternalFrame;
import javax.swing.JScrollPane;
import javax.swing.JTextField;
import de.rub.syssec.saaf.application.search.BytecodeSearcher;
import de.rub.syssec.saaf.gui.FilterTable;
import de.rub.syssec.saaf.gui.editor.FileTree;
import de.rub.syssec.saaf.model.application.ApplicationInterface;
import de.rub.syssec.saaf.model.application.CodeLineInterface;
/**
* Calls the search for patterns in smali bytecode.
*/
public class FoundBytecodeFrame extends JInternalFrame {
private static final long serialVersionUID = -6243385366339287049L;
private final JButton searchBtn;
private final JScrollPane jScrollPane;
private FilterTable table;
private FileTree fileTree;
private final JTextField patternField;
private Vector<CodeLineInterface> resultVec = new Vector<CodeLineInterface>();
private static final String[] TABLE_COLUMNS = { "File", "Line", "Content", "Is code?" };
private final ApplicationInterface app;
public FoundBytecodeFrame(final ApplicationInterface app, final FileTree fileTree) {
super("Search in SMALI Bytecode Files - "+ app.getApplicationName(), true, true, true, true);
this.app = app;
patternField = new javax.swing.JTextField();
searchBtn = new javax.swing.JButton();
jScrollPane = new javax.swing.JScrollPane();
this.fileTree = fileTree;
searchBtn.setText("Search");
searchBtn.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent evt) {
performSearch(evt);
}
});
jScrollPane.setHorizontalScrollBarPolicy(JScrollPane.HORIZONTAL_SCROLLBAR_ALWAYS);
table = new FilterTable(resultVec, TABLE_COLUMNS, fileTree);
jScrollPane.setViewportView(table);
javax.swing.GroupLayout layout = new javax.swing.GroupLayout(getContentPane());
getContentPane().setLayout(layout);
layout.setHorizontalGroup(
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(layout.createSequentialGroup()
.addGap(20, 20, 20)
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addComponent(searchBtn)
.addComponent(patternField, javax.swing.GroupLayout.DEFAULT_SIZE, 469, Short.MAX_VALUE))
.addGap(31, 31, 31))
.addComponent(jScrollPane, javax.swing.GroupLayout.Alignment.TRAILING, javax.swing.GroupLayout.DEFAULT_SIZE, 520, Short.MAX_VALUE)
);
layout.setVerticalGroup(
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(layout.createSequentialGroup()
.addGap(23, 23, 23)
.addComponent(patternField, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
.addComponent(searchBtn)
.addGap(12, 12, 12)
.addComponent(jScrollPane, javax.swing.GroupLayout.DEFAULT_SIZE, 183, Short.MAX_VALUE))
);
JScrollPane scrollPane = new JScrollPane(table);
add(scrollPane);
this.setPreferredSize(new Dimension(800, 400));
}
protected void performSearch(ActionEvent evt) {
String pattern = patternField.getText();
if (pattern == null || pattern.trim().isEmpty()) return;
resultVec = BytecodeSearcher.searchPattern(app, pattern);
table = new FilterTable(resultVec, TABLE_COLUMNS, fileTree);
jScrollPane.setViewportView(table);
}
}