/* * Copyright, Aspect Security, Inc. * * This file is part of JavaSnoop. * * JavaSnoop 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. * * JavaSnoop 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 JavaSnoop. If not, see <http://www.gnu.org/licenses/>. */ package com.aspect.snoop.ui.hook; import com.aspect.snoop.MethodWrapper; import com.aspect.snoop.agent.AgentLogger; import com.aspect.snoop.agent.SnoopAgent; import com.aspect.snoop.ui.choose.clazz.ChooseClassView; import com.aspect.snoop.util.ReflectionUtil; import com.aspect.snoop.util.UIUtil; import java.awt.Color; import java.awt.Component; import java.awt.event.MouseEvent; import java.awt.event.MouseListener; import java.lang.reflect.AccessibleObject; import java.lang.reflect.Constructor; import java.lang.reflect.Member; import java.lang.reflect.Method; import java.util.List; import javax.swing.JLabel; import javax.swing.JList; import javax.swing.JOptionPane; import javax.swing.ListCellRenderer; import org.jdesktop.application.Action; public class AddFunctionHookView extends javax.swing.JDialog { private static AccessibleObject selectedMethod; private static Class selectedClass; private static Class[] parameterTypes; private static Class returnType; private static boolean shouldInherit; private Class currentClass; private Method[] loadedMethods; private Constructor[] loadedConstructors; public boolean getShouldInherit() { return shouldInherit; } public Class getSelectedClass() { return selectedClass; } public AccessibleObject getSelectedMethod() { return selectedMethod; } public Class[] getParameterTypes() { return parameterTypes; } public AddFunctionHookView(java.awt.Frame parent, boolean modal, String classpath) { super(parent, modal); initComponents(); lstMethods.setCellRenderer( new ListCellRenderer() { public Component getListCellRendererComponent(JList list, Object value, int index, boolean isSelected, boolean cellHasFocus) { JLabel lbl = new JLabel(); if ( isSelected ) { lbl.setForeground(Color.white); lbl.setBackground(Color.blue); lbl.setOpaque(true); } Member m = (Member)value; String toShow = ReflectionUtil.getMethodDescription(m); lbl.setText(" " + toShow); return lbl; } } ); lstMethods.setListData(new Method[]{}); selectedClass = null; selectedMethod = null; parameterTypes = null; returnType = null; lstMethods.addMouseListener( new MouseListener() { public void mouseClicked(MouseEvent e) { if (e.getClickCount() == 2) { // user double clicked an item selection finalizeSelection(); dispose(); } } public void mousePressed(MouseEvent e) { } public void mouseReleased(MouseEvent e) { } public void mouseEntered(MouseEvent e) { } public void mouseExited(MouseEvent e) { } }); } /** This method is called from within the constructor to * initialize the form. * WARNING: Do NOT modify this code. The content of this method is * always regenerated by the Form Editor. */ @SuppressWarnings("unchecked") // <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents private void initComponents() { jLabel1 = new javax.swing.JLabel(); txtClass = new javax.swing.JTextField(); btnBrowseForClass = new javax.swing.JButton(); jLabel2 = new javax.swing.JLabel(); jScrollPane1 = new javax.swing.JScrollPane(); lstMethods = new javax.swing.JList(); btnAddWatch = new javax.swing.JButton(); chkShouldInherit = new javax.swing.JCheckBox(); btnSearchForFunction = new javax.swing.JButton(); setDefaultCloseOperation(javax.swing.WindowConstants.DISPOSE_ON_CLOSE); org.jdesktop.application.ResourceMap resourceMap = org.jdesktop.application.Application.getInstance(com.aspect.snoop.JavaSnoop.class).getContext().getResourceMap(AddFunctionHookView.class); setTitle(resourceMap.getString("Form.title")); // NOI18N setModalityType(java.awt.Dialog.ModalityType.APPLICATION_MODAL); setName("Form"); // NOI18N jLabel1.setText(resourceMap.getString("jLabel1.text")); // NOI18N jLabel1.setName("jLabel1"); // NOI18N txtClass.setText(resourceMap.getString("txtClass.text")); // NOI18N txtClass.setToolTipText(resourceMap.getString("txtClass.toolTipText")); // NOI18N txtClass.setName("txtClass"); // NOI18N txtClass.addActionListener(new java.awt.event.ActionListener() { public void actionPerformed(java.awt.event.ActionEvent evt) { txtClassActionPerformed(evt); } }); txtClass.addKeyListener(new java.awt.event.KeyAdapter() { public void keyTyped(java.awt.event.KeyEvent evt) { txtClassKeyTyped(evt); } }); javax.swing.ActionMap actionMap = org.jdesktop.application.Application.getInstance(com.aspect.snoop.JavaSnoop.class).getContext().getActionMap(AddFunctionHookView.class, this); btnBrowseForClass.setAction(actionMap.get("showChooseClassForm")); // NOI18N btnBrowseForClass.setText(resourceMap.getString("btnBrowseForClass.text")); // NOI18N btnBrowseForClass.setToolTipText(resourceMap.getString("btnBrowseForClass.toolTipText")); // NOI18N btnBrowseForClass.setFocusable(false); btnBrowseForClass.setName("btnBrowseForClass"); // NOI18N btnBrowseForClass.addActionListener(new java.awt.event.ActionListener() { public void actionPerformed(java.awt.event.ActionEvent evt) { btnBrowseForClassActionPerformed(evt); } }); jLabel2.setText(resourceMap.getString("jLabel2.text")); // NOI18N jLabel2.setName("jLabel2"); // NOI18N jScrollPane1.setName("jScrollPane1"); // NOI18N lstMethods.setModel(new javax.swing.AbstractListModel() { String[] strings = { "Item 1", "Item 2", "Item 3", "Item 4", "Item 5" }; public int getSize() { return strings.length; } public Object getElementAt(int i) { return strings[i]; } }); lstMethods.setName("lstMethods"); // NOI18N lstMethods.addKeyListener(new java.awt.event.KeyAdapter() { public void keyTyped(java.awt.event.KeyEvent evt) { lstMethodsKeyTyped(evt); } }); jScrollPane1.setViewportView(lstMethods); btnAddWatch.setFont(resourceMap.getFont("btnAddWatch.font")); // NOI18N btnAddWatch.setText(resourceMap.getString("btnAddWatch.text")); // NOI18N btnAddWatch.setToolTipText(resourceMap.getString("btnAddWatch.toolTipText")); // NOI18N btnAddWatch.setFocusable(false); btnAddWatch.setName("btnAddWatch"); // NOI18N btnAddWatch.addActionListener(new java.awt.event.ActionListener() { public void actionPerformed(java.awt.event.ActionEvent evt) { btnAddWatchActionPerformed(evt); } }); chkShouldInherit.setText(resourceMap.getString("chkShouldInherit.text")); // NOI18N chkShouldInherit.setToolTipText(resourceMap.getString("chkShouldInherit.toolTipText")); // NOI18N chkShouldInherit.setFocusable(false); chkShouldInherit.setName("chkShouldInherit"); // NOI18N btnSearchForFunction.setAction(actionMap.get("searchForFunction")); // NOI18N btnSearchForFunction.setText(resourceMap.getString("btnSearchForFunction.text")); // NOI18N btnSearchForFunction.setToolTipText(resourceMap.getString("btnSearchForFunction.toolTipText")); // NOI18N btnSearchForFunction.setFocusable(false); btnSearchForFunction.setName("btnSearchForFunction"); // NOI18N javax.swing.GroupLayout layout = new javax.swing.GroupLayout(getContentPane()); getContentPane().setLayout(layout); layout.setHorizontalGroup( layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) .addGroup(layout.createSequentialGroup() .addContainerGap() .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING) .addGroup(javax.swing.GroupLayout.Alignment.LEADING, layout.createSequentialGroup() .addComponent(jLabel1) .addGap(15, 15, 15) .addComponent(txtClass, javax.swing.GroupLayout.DEFAULT_SIZE, 308, Short.MAX_VALUE) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) .addComponent(btnBrowseForClass)) .addGroup(javax.swing.GroupLayout.Alignment.LEADING, layout.createSequentialGroup() .addComponent(jLabel2) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) .addGroup(layout.createSequentialGroup() .addGap(4, 4, 4) .addComponent(chkShouldInherit) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) .addComponent(btnSearchForFunction) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) .addComponent(btnAddWatch)) .addComponent(jScrollPane1, javax.swing.GroupLayout.DEFAULT_SIZE, 393, Short.MAX_VALUE)))) .addContainerGap()) ); layout.setVerticalGroup( layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) .addGroup(layout.createSequentialGroup() .addContainerGap() .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) .addComponent(jLabel1) .addComponent(txtClass, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) .addComponent(btnBrowseForClass)) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED) .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) .addComponent(jLabel2) .addGroup(layout.createSequentialGroup() .addComponent(jScrollPane1, javax.swing.GroupLayout.PREFERRED_SIZE, 91, javax.swing.GroupLayout.PREFERRED_SIZE) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) .addComponent(btnSearchForFunction) .addComponent(chkShouldInherit) .addComponent(btnAddWatch)))) .addContainerGap()) ); pack(); }// </editor-fold>//GEN-END:initComponents private void btnAddWatchActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_btnAddWatchActionPerformed if (lstMethods.getSelectedIndex() != -1) { finalizeSelection(); dispose(); } else { JOptionPane.showMessageDialog(this, "Please select a method to hook!"); } }//GEN-LAST:event_btnAddWatchActionPerformed private void btnBrowseForClassActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_btnBrowseForClassActionPerformed List<Class> classes = SnoopAgent.getAgentManager().getLoadedClasses(); ChooseClassView view = new ChooseClassView(this, classes); view.setVisible(true); UIUtil.waitForInput(view); if (view.getChosenClass() != null) { loadClassMethods(view.getChosenClass(), true); } }//GEN-LAST:event_btnBrowseForClassActionPerformed private void txtClassKeyTyped(java.awt.event.KeyEvent evt) {//GEN-FIRST:event_txtClassKeyTyped String substring = txtClass.getText(); if ( evt.getKeyChar() != java.awt.event.KeyEvent.VK_ENTER && evt.getKeyChar() != java.awt.event.KeyEvent.VK_BACK_SPACE && evt.getKeyChar() != java.awt.event.KeyEvent.VK_ESCAPE) { int pos = txtClass.getCaretPosition(); if ( pos != 0 ) { String s1 = substring.substring(0, pos); String s2 = substring.substring(pos,txtClass.getText().length()); substring = s1 + evt.getKeyChar() + s2; } else { substring += evt.getKeyChar(); } } try { currentClass = SnoopAgent.getAgentManager().getFromAllClasses(substring); loadClassMethods(currentClass,false); } catch (ClassNotFoundException ex) { lstMethods.setListData(new String[0]); } }//GEN-LAST:event_txtClassKeyTyped private void txtClassActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_txtClassActionPerformed if ( lstMethods.getModel().getSize() > 0 ) { lstMethods.setSelectedIndex(0); lstMethods.requestFocus(); } }//GEN-LAST:event_txtClassActionPerformed private void lstMethodsKeyTyped(java.awt.event.KeyEvent evt) {//GEN-FIRST:event_lstMethodsKeyTyped if ( evt.getKeyChar() == java.awt.event.KeyEvent.VK_ENTER ) { if ( lstMethods.getSelectedIndex() != -1 ) { btnAddWatch.doClick(); } } }//GEN-LAST:event_lstMethodsKeyTyped // Variables declaration - do not modify//GEN-BEGIN:variables private javax.swing.JButton btnAddWatch; private javax.swing.JButton btnBrowseForClass; private javax.swing.JButton btnSearchForFunction; private javax.swing.JCheckBox chkShouldInherit; private javax.swing.JLabel jLabel1; private javax.swing.JLabel jLabel2; private javax.swing.JScrollPane jScrollPane1; private javax.swing.JList lstMethods; private javax.swing.JTextField txtClass; // End of variables declaration//GEN-END:variables private void finalizeSelection() { selectedClass = currentClass; selectedMethod = (AccessibleObject)lstMethods.getSelectedValue(); parameterTypes = ReflectionUtil.getParameterTypes(selectedMethod); returnType = ReflectionUtil.getReturnType(selectedMethod); shouldInherit = chkShouldInherit.isSelected(); } private void loadClassMethods(Class clazz, boolean setClassName) { currentClass = clazz; loadedMethods = currentClass.getDeclaredMethods(); loadedConstructors = currentClass.getDeclaredConstructors(); Member[] entries = new Member[loadedMethods.length + loadedConstructors.length]; System.arraycopy(loadedMethods, 0, entries, 0, loadedMethods.length); System.arraycopy(loadedConstructors, 0, entries, loadedMethods.length, loadedConstructors.length); lstMethods.setListData(entries); if ( setClassName ) { txtClass.setText(currentClass.getName()); } if ( ReflectionUtil.isInterfaceOrAbstract(currentClass)) { chkShouldInherit.setSelected(true); chkShouldInherit.setEnabled(false); } else { chkShouldInherit.setSelected(false); chkShouldInherit.setEnabled(true); } } @Action public void searchForFunction() { List<Class> classes = SnoopAgent.getAgentManager().getLoadedClasses(); FunctionSearchView view = new FunctionSearchView(this, true, classes); view.setVisible(true); UIUtil.waitForInput(view); AccessibleObject method = view.getMethodChosen(); if ( method == null ) // indicates the user cancelled return; selectedClass = ReflectionUtil.getDeclaringClass(method); selectedMethod = method; parameterTypes = ReflectionUtil.getParameterTypes(method); shouldInherit = ReflectionUtil.isInterfaceOrAbstract(method); returnType = ReflectionUtil.getReturnType(method); dispose(); } public Class getReturnType() { return returnType; } }