Dynamic Analysis Cleanup

This commit is contained in:
Konloch 2021-07-06 21:21:06 -07:00
parent 02115c4820
commit 7eda960981
12 changed files with 140 additions and 147 deletions

View file

@ -110,18 +110,31 @@ import static the.bytecode.club.bytecodeviewer.util.MiscUtils.guessLanguage;
public class BytecodeViewer public class BytecodeViewer
{ {
//TODO fix this for tab dragging & better tab controls
public static boolean EXPERIMENTAL_TAB_CODE = false; public static boolean EXPERIMENTAL_TAB_CODE = false;
public static boolean DEV_MODE = false; //if true error streams as preserved
//the launch args called on BCV
public static String[] launchArgs; public static String[] launchArgs;
public static MainViewerGUI viewer = null;
public static ClassNodeLoader loader = new ClassNodeLoader(); //might be insecure due to assholes targeting BCV, //the GUI reference
public static SecurityMan sm = new SecurityMan(); //might be insecure due to assholes targeting BCV, public static MainViewerGUI viewer;
public static Refactorer refactorer = new Refactorer();
public static List<FileContainer> files = new ArrayList<>(); //all of BCV's loaded files/classes/etc //All of the opened resources (Files/Classes/Etc)
public static List<FileContainer> files = new ArrayList<>();
//All of the created processes (Decompilers/etc)
public static List<Process> createdProcesses = new ArrayList<>(); public static List<Process> createdProcesses = new ArrayList<>();
//Security Manager for dynamic analysis debugging
public static SecurityMan sm = new SecurityMan(); //might be insecure due to assholes targeting BCV,
//Refactorer
public static Refactorer refactorer = new Refactorer();
//GSON Reference
public static final Gson gson = new GsonBuilder().setPrettyPrinting().create(); public static final Gson gson = new GsonBuilder().setPrettyPrinting().create();
//Threads
private static final Thread versionChecker = new Thread(new VersionChecker(), "Version Checker"); private static final Thread versionChecker = new Thread(new VersionChecker(), "Version Checker");
private static final Thread pingBack = new Thread(new PingBack(), "Pingback"); private static final Thread pingBack = new Thread(new PingBack(), "Pingback");
private static final Thread installFatJar = new Thread(new InstallFatJar(), "Install Fat-Jar"); private static final Thread installFatJar = new Thread(new InstallFatJar(), "Install Fat-Jar");

View file

@ -1,6 +1,12 @@
package the.bytecode.club.bytecodeviewer; package the.bytecode.club.bytecodeviewer;
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import the.bytecode.club.bytecodeviewer.api.ClassNodeLoader;
import the.bytecode.club.bytecodeviewer.obfuscators.mapping.Refactorer;
import java.io.File; import java.io.File;
import java.io.PrintStream;
/** /**
* General program constants, to use this class include everything as a wildcard static import: * General program constants, to use this class include everything as a wildcard static import:
@ -35,6 +41,9 @@ public class Constants
public static String enjarifyWorkingDirectory = getBCVDirectory() + fs + "enjarify_" + enjarifyVersion; public static String enjarifyWorkingDirectory = getBCVDirectory() + fs + "enjarify_" + enjarifyVersion;
public static final String[] SUPPORTED_FILE_EXTENSIONS = new String[]{"jar", "zip", "class", "apk", "xapk", "dex", "war", "jsp"}; public static final String[] SUPPORTED_FILE_EXTENSIONS = new String[]{"jar", "zip", "class", "apk", "xapk", "dex", "war", "jsp"};
public static final PrintStream ERR = System.err;
public static final PrintStream OUT = System.out;
/** /**
* Returns the BCV directory * Returns the BCV directory
* *

View file

@ -46,8 +46,9 @@ import static the.bytecode.club.bytecodeviewer.Constants.*;
* *
* @author Konloch * @author Konloch
*/ */
public class BytecodeViewer { public class BytecodeViewer
{
private static ClassNodeLoader loader = new ClassNodeLoader(); //might be insecure due to assholes targeting BCV,
private static URLClassLoader cl; private static URLClassLoader cl;
/** /**
@ -56,7 +57,7 @@ public class BytecodeViewer {
* @return * @return
*/ */
public static ClassNodeLoader getClassNodeLoader() { public static ClassNodeLoader getClassNodeLoader() {
return the.bytecode.club.bytecodeviewer.BytecodeViewer.loader; return loader;
} }
/** /**
@ -132,8 +133,8 @@ public class BytecodeViewer {
* Creates a new instance of the ClassNode loader. * Creates a new instance of the ClassNode loader.
*/ */
public static void createNewClassNodeLoaderInstance() { public static void createNewClassNodeLoaderInstance() {
the.bytecode.club.bytecodeviewer.BytecodeViewer.loader.clear(); loader.clear();
the.bytecode.club.bytecodeviewer.BytecodeViewer.loader = new ClassNodeLoader(); loader = new ClassNodeLoader();
} }
/** /**

View file

@ -1,22 +1,6 @@
package the.bytecode.club.bytecodeviewer.api; package the.bytecode.club.bytecodeviewer.api;
import java.awt.BorderLayout; import the.bytecode.club.bytecodeviewer.gui.components.SystemConsole;
import java.awt.Dimension;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import javax.swing.JButton;
import javax.swing.JCheckBox;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTextField;
import the.bytecode.club.bytecodeviewer.BytecodeViewer;
import the.bytecode.club.bytecodeviewer.Resources;
import the.bytecode.club.bytecodeviewer.gui.components.JFrameConsole;
import the.bytecode.club.bytecodeviewer.gui.components.SearchableJTextArea;
import the.bytecode.club.bytecodeviewer.gui.components.listeners.PressKeyListener;
import the.bytecode.club.bytecodeviewer.gui.components.listeners.ReleaseKeyListener;
/*************************************************************************** /***************************************************************************
* Bytecode Viewer (BCV) - Java & Android Reverse Engineering Suite * * Bytecode Viewer (BCV) - Java & Android Reverse Engineering Suite *
@ -42,7 +26,7 @@ import the.bytecode.club.bytecodeviewer.gui.components.listeners.ReleaseKeyListe
* @author Konloch * @author Konloch
*/ */
public class PluginConsole extends JFrameConsole public class PluginConsole extends SystemConsole
{ {
public PluginConsole(String pluginName) public PluginConsole(String pluginName)
{ {

View file

@ -1,5 +1,8 @@
package the.bytecode.club.bytecodeviewer.gui.components; package the.bytecode.club.bytecodeviewer.gui.components;
import the.bytecode.club.bytecodeviewer.BytecodeViewer;
import the.bytecode.club.bytecodeviewer.Constants;
import java.io.PrintStream; import java.io.PrintStream;
import static the.bytecode.club.bytecodeviewer.Constants.nl; import static the.bytecode.club.bytecodeviewer.Constants.nl;
@ -30,34 +33,30 @@ import static the.bytecode.club.bytecodeviewer.Constants.nl;
*/ */
public class JFrameConsolePrintStream extends JFrameConsole public class JFrameConsolePrintStream extends JFrameConsole
{ {
private final PrintStream originalOut; private final JTextAreaOutputStream textAreaOutputStreamOut;
private final PrintStream newPrintStream; private final JTextAreaOutputStream textAreaOutputStreamErr;
private final JTextAreaOutputStream s;
public JFrameConsolePrintStream(String title, PrintStream originalOut) public JFrameConsolePrintStream(String title)
{ {
super(title); super(title);
this.originalOut = originalOut; textAreaOutputStreamOut = new JTextAreaOutputStream(getTextArea(), System.out);
textAreaOutputStreamErr = new JTextAreaOutputStream(getTextArea(), System.err);
s = new JTextAreaOutputStream(getTextArea()); System.setOut(new PrintStream(textAreaOutputStreamOut));
newPrintStream = new PrintStream(s); System.setErr(new PrintStream(textAreaOutputStreamErr));
} }
public void finished() public void finished()
{ {
if (originalOut != null) System.setErr(Constants.ERR);
System.setErr(originalOut); System.setOut(Constants.OUT);
}
public PrintStream getNewPrintStream()
{
return newPrintStream;
} }
public void pretty() public void pretty()
{ {
s.update(); textAreaOutputStreamOut.update();
textAreaOutputStreamErr.update();
String[] test; String[] test;
if (getTextArea().getText().split("\n").length >= 2) if (getTextArea().getText().split("\n").length >= 2)
test = getTextArea().getText().split("\n"); test = getTextArea().getText().split("\n");

View file

@ -3,6 +3,7 @@ package the.bytecode.club.bytecodeviewer.gui.components;
import javax.swing.*; import javax.swing.*;
import java.io.IOException; import java.io.IOException;
import java.io.OutputStream; import java.io.OutputStream;
import java.io.PrintStream;
/*************************************************************************** /***************************************************************************
* Bytecode Viewer (BCV) - Java & Android Reverse Engineering Suite * * Bytecode Viewer (BCV) - Java & Android Reverse Engineering Suite *
@ -30,10 +31,12 @@ public class JTextAreaOutputStream extends OutputStream
{ {
private final StringBuilder sb = new StringBuilder(); private final StringBuilder sb = new StringBuilder();
private final JTextArea textArea; private final JTextArea textArea;
private final PrintStream og;
public JTextAreaOutputStream(JTextArea textArea) public JTextAreaOutputStream(JTextArea textArea, PrintStream og)
{ {
this.textArea = textArea; this.textArea = textArea;
this.og = og;
} }
public void update() public void update()
@ -45,5 +48,6 @@ public class JTextAreaOutputStream extends OutputStream
public void write(int b) throws IOException public void write(int b) throws IOException
{ {
sb.append((char) b); sb.append((char) b);
og.write(b);
} }
} }

View file

@ -6,10 +6,9 @@ import javax.swing.JCheckBox;
import javax.swing.JFrame; import javax.swing.JFrame;
import javax.swing.JLabel; import javax.swing.JLabel;
import javax.swing.JTextField; import javax.swing.JTextField;
import org.objectweb.asm.tree.ClassNode;
import org.objectweb.asm.tree.MethodNode;
import the.bytecode.club.bytecodeviewer.BytecodeViewer;
import the.bytecode.club.bytecodeviewer.Resources; import the.bytecode.club.bytecodeviewer.Resources;
import the.bytecode.club.bytecodeviewer.api.ASMResourceUtil;
import the.bytecode.club.bytecodeviewer.plugin.PluginManager; import the.bytecode.club.bytecodeviewer.plugin.PluginManager;
import the.bytecode.club.bytecodeviewer.plugin.preinstalled.EZInjection; import the.bytecode.club.bytecodeviewer.plugin.preinstalled.EZInjection;
@ -37,8 +36,10 @@ import the.bytecode.club.bytecodeviewer.plugin.preinstalled.EZInjection;
* @author Konloch * @author Konloch
*/ */
public class RunOptions extends JFrame { public class RunOptions extends JFrame
public RunOptions() { {
public RunOptions()
{
this.setIconImages(Resources.iconList); this.setIconImages(Resources.iconList);
setSize(new Dimension(250, 402)); setSize(new Dimension(250, 402));
setResizable(false); setResizable(false);
@ -62,49 +63,33 @@ public class RunOptions extends JFrame {
debugMethodCalls.setBounds(6, 59, 232, 23); debugMethodCalls.setBounds(6, 59, 232, 23);
getContentPane().add(debugMethodCalls); getContentPane().add(debugMethodCalls);
txtThebytecodeclubexamplemainlstring = new JTextField(); mainMethodFQN = new JTextField();
JButton btnNewButton = new JButton("Execute"); JButton btnNewButton = new JButton("Execute");
btnNewButton.setBounds(6, 345, 232, 23); btnNewButton.setBounds(6, 345, 232, 23);
getContentPane().add(btnNewButton); getContentPane().add(btnNewButton);
boolean b = false; mainMethodFQN.setText(ASMResourceUtil.findMainMethod("the/bytecode/club/Example.main"));
for (ClassNode classNode : BytecodeViewer.getLoadedClasses()) {
for (Object o : classNode.methods.toArray()) {
MethodNode m = (MethodNode) o;
if (m.name.equals("main") && m.desc.equals("([Ljava/lang/String;)V")) { mainMethodFQN.setBounds(6, 233, 232, 20);
if (!b) { getContentPane().add(mainMethodFQN);
b = true; mainMethodFQN.setColumns(10);
txtThebytecodeclubexamplemainlstring
.setText(classNode.name + "." + m.name);
}
}
}
}
if (!b)
txtThebytecodeclubexamplemainlstring.setText("the/bytecode/club/Example.main");
txtThebytecodeclubexamplemainlstring.setBounds(6, 233, 232, 20);
getContentPane().add(txtThebytecodeclubexamplemainlstring);
txtThebytecodeclubexamplemainlstring.setColumns(10);
JLabel lblNewLabel = new JLabel("Debug Classes (Seperate with , ):"); JLabel lblNewLabel = new JLabel("Debug Classes (Seperate with , ):");
lblNewLabel.setBounds(10, 89, 228, 14); lblNewLabel.setBounds(10, 89, 228, 14);
getContentPane().add(lblNewLabel); getContentPane().add(lblNewLabel);
textField = new JTextField(); debugClasses = new JTextField();
textField.setText("*"); debugClasses.setText("*");
textField.setBounds(6, 111, 232, 20); debugClasses.setBounds(6, 111, 232, 20);
getContentPane().add(textField); getContentPane().add(debugClasses);
textField.setColumns(10); debugClasses.setColumns(10);
textField_1 = new JTextField(); socksProxy = new JTextField();
textField_1.setText("127.0.0.1:9150"); socksProxy.setText("127.0.0.1:9150");
textField_1.setColumns(10); socksProxy.setColumns(10);
textField_1.setBounds(6, 172, 232, 20); socksProxy.setBounds(6, 172, 232, 20);
getContentPane().add(textField_1); getContentPane().add(socksProxy);
final JCheckBox forceProxy = new JCheckBox("Force Proxy (socks5, host:port):"); final JCheckBox forceProxy = new JCheckBox("Force Proxy (socks5, host:port):");
forceProxy.setBounds(6, 142, 232, 23); forceProxy.setBounds(6, 142, 232, 23);
@ -130,8 +115,8 @@ public class RunOptions extends JFrame {
.isSelected(), injectHooks.isSelected(), .isSelected(), injectHooks.isSelected(),
debugMethodCalls.isSelected(), invokeMethod debugMethodCalls.isSelected(), invokeMethod
.isSelected(), .isSelected(),
txtThebytecodeclubexamplemainlstring.getText(), false, false, textField mainMethodFQN.getText(), false, false, debugClasses
.getText(), textField_1.getText(), forceProxy .getText(), this.socksProxy.getText(), forceProxy
.isSelected(), .isSelected(),
launchReflectionKit.isSelected(), console.isSelected(), launchReflectionKit.isSelected(), console.isSelected(),
chckbxPrintToTerminal.isSelected())); chckbxPrintToTerminal.isSelected()));
@ -140,8 +125,8 @@ public class RunOptions extends JFrame {
} }
private static final long serialVersionUID = -2662514582647810868L; private static final long serialVersionUID = -2662514582647810868L;
private final JTextField txtThebytecodeclubexamplemainlstring; private final JTextField mainMethodFQN;
private final JCheckBox debugMethodCalls; private final JCheckBox debugMethodCalls;
private final JTextField textField; private final JTextField debugClasses;
private final JTextField textField_1; private final JTextField socksProxy;
} }

View file

@ -18,18 +18,19 @@ package the.bytecode.club.bytecodeviewer.gui.components;
* along with this program. If not, see <http://www.gnu.org/licenses/>. * * along with this program. If not, see <http://www.gnu.org/licenses/>. *
***************************************************************************/ ***************************************************************************/
import the.bytecode.club.bytecodeviewer.BytecodeViewer;
/** /**
* A simple console GUI. * A simple console GUI.
* *
* @author Konloch * @author Konloch
*/ */
public class SystemOutConsole extends JFrameConsolePrintStream public class SystemConsole extends JFrameConsolePrintStream
{ {
public SystemOutConsole(String title) public SystemConsole(String title)
{ {
super(title, System.out); super(title);
System.setOut(getNewPrintStream());
} }
private static final long serialVersionUID = -6666940545499937508L; private static final long serialVersionUID = -6666940545499937508L;

View file

@ -1,40 +0,0 @@
package the.bytecode.club.bytecodeviewer.gui.components;
/***************************************************************************
* Bytecode Viewer (BCV) - Java & Android Reverse Engineering Suite *
* Copyright (C) 2014 Kalen 'Konloch' Kinloch - http://bytecodeviewer.com *
* *
* 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/>. *
***************************************************************************/
import the.bytecode.club.bytecodeviewer.BytecodeViewer;
/**
* A simple console GUI.
*
* @author Konloch
*/
public class SystemErrConsole extends JFrameConsolePrintStream
{
public SystemErrConsole(String title)
{
super(title, System.err);
if(!BytecodeViewer.DEV_MODE)
System.setErr(getNewPrintStream());
}
private static final long serialVersionUID = -6556940545421437508L;
}

View file

@ -5,7 +5,7 @@ import the.bytecode.club.bytecodeviewer.BytecodeViewer;
import the.bytecode.club.bytecodeviewer.compilers.Compiler; import the.bytecode.club.bytecodeviewer.compilers.Compiler;
import the.bytecode.club.bytecodeviewer.decompilers.Decompiler; import the.bytecode.club.bytecodeviewer.decompilers.Decompiler;
import the.bytecode.club.bytecodeviewer.gui.components.SearchableRSyntaxTextArea; import the.bytecode.club.bytecodeviewer.gui.components.SearchableRSyntaxTextArea;
import the.bytecode.club.bytecodeviewer.gui.components.SystemErrConsole; import the.bytecode.club.bytecodeviewer.gui.components.SystemConsole;
import the.bytecode.club.bytecodeviewer.gui.resourceviewer.viewer.ClassViewer; import the.bytecode.club.bytecodeviewer.gui.resourceviewer.viewer.ClassViewer;
import the.bytecode.club.bytecodeviewer.gui.util.PaneUpdaterThread; import the.bytecode.club.bytecodeviewer.gui.util.PaneUpdaterThread;
import the.bytecode.club.bytecodeviewer.util.JarUtils; import the.bytecode.club.bytecodeviewer.util.JarUtils;
@ -74,11 +74,7 @@ public class ResourceViewPanel
if(textArea == null || !textArea.isEditable()) if(textArea == null || !textArea.isEditable())
return true; return true;
//WARNING: Any errors thrown will get swallowed by this class SystemConsole errConsole = new SystemConsole("Java Compile Issues");
//if it fails to display it may be hiding exceptions you can't see
//make sure to enable DEV_MODE in BytecodeViewer
SystemErrConsole errConsole = new SystemErrConsole("Java Compile Issues");
errConsole.setText("Error compiling class: " + viewer.cn.name + errConsole.setText("Error compiling class: " + viewer.cn.name +
nl + "Keep in mind most decompilers cannot produce compilable classes" + nl + "Keep in mind most decompilers cannot produce compilable classes" +
nl + nl); nl + nl);

View file

@ -144,6 +144,7 @@ public class EZInjection extends Plugin {
public void execute(ArrayList<ClassNode> classNodeList) public void execute(ArrayList<ClassNode> classNodeList)
{ {
BytecodeViewer.updateBusyStatus(true); BytecodeViewer.updateBusyStatus(true);
gui.setText(""); gui.setText("");
if (console) if (console)
@ -273,11 +274,14 @@ public class EZInjection extends Plugin {
if (invokeMethod) if (invokeMethod)
{ {
//start print debugging
BytecodeViewer.sm.setPrinting(true);
// load all the classnodes into the classloader // load all the classnodes into the classloader
for (ClassNode cn : BytecodeViewer.getLoadedClasses()) for (ClassNode cn : BytecodeViewer.getLoadedClasses())
the.bytecode.club.bytecodeviewer.api.BytecodeViewer.getClassNodeLoader().addClass(cn); the.bytecode.club.bytecodeviewer.api.BytecodeViewer.getClassNodeLoader().addClass(cn);
print("Invoking " + invokeMethodInformation + ":" + nl + nl); print("Attempting to find " + invokeMethodInformation + ":" + nl + nl);
for (ClassNode classNode : classNodeList) for (ClassNode classNode : classNodeList)
{ {
@ -294,12 +298,17 @@ public class EZInjection extends Plugin {
{ {
if (m2.getName().equals(m.name)) if (m2.getName().equals(m.name))
{ {
print("Invoking " + invokeMethodInformation + ":" + nl + nl);
GraphicalReflectionKit kit = launchKit ? new GraphicalReflectionKit() : null;
try try
{ {
if(kit != null)
kit.setVisible(true);
m2.invoke(classNode.getClass().newInstance(), (Object[]) new String[1]); m2.invoke(classNode.getClass().newInstance(), (Object[]) new String[1]);
if (launchKit) print("Finished running " + invokeMethodInformation);
new GraphicalReflectionKit().setVisible(true);
} }
catch (Exception e) catch (Exception e)
{ {
@ -308,6 +317,14 @@ public class EZInjection extends Plugin {
e.printStackTrace(); e.printStackTrace();
print(sw.toString()); print(sw.toString());
} }
finally
{
//disable print debugging
BytecodeViewer.sm.setPrinting(false);
if(kit != null)
kit.setVisible(false);
}
} }
} }
} }

View file

@ -30,13 +30,17 @@ import java.security.Permission;
* @author Konloch * @author Konloch
*/ */
public class SecurityMan extends SecurityManager { public class SecurityMan extends SecurityManager
{
public void setBlocking() { private boolean blocking = true; //might be insecure due to assholes targeting BCV, however that's highly unlikely.
private boolean printing = false;
private boolean printingPackage = false;
public void resumeBlocking() {
blocking = true; blocking = true;
} }
public void stopBlocking() { //slightly safer security system than just a public static boolean being toggled public void pauseBlocking() { //slightly safer security system than just a public static boolean being toggled
String executedClass = Thread.currentThread().getStackTrace()[2].getClassName(); String executedClass = Thread.currentThread().getStackTrace()[2].getClassName();
if (executedClass.equals("the.bytecode.club.bytecodeviewer.decompilers.impl.KrakatauDecompiler") || if (executedClass.equals("the.bytecode.club.bytecodeviewer.decompilers.impl.KrakatauDecompiler") ||
executedClass.equals("the.bytecode.club.bytecodeviewer.decompilers.impl.KrakatauDisassembler") || executedClass.equals("the.bytecode.club.bytecodeviewer.decompilers.impl.KrakatauDisassembler") ||
@ -55,9 +59,17 @@ public class SecurityMan extends SecurityManager {
System.out.println(stackTraceElements.getClassName()); System.out.println(stackTraceElements.getClassName());
} }
} }
private boolean blocking = true; //might be insecure due to assholes targeting BCV, however that's highly unlikely. public void setPrinting(boolean printing)
{
this.printing = printing;
}
public void setPrintingPackage(boolean printingPackage)
{
this.printingPackage = printingPackage;
}
@Override @Override
public void checkExec(String cmd) { public void checkExec(String cmd) {
String[] whitelist = { String[] whitelist = {
@ -112,6 +124,8 @@ public class SecurityMan extends SecurityManager {
@Override @Override
public void checkConnect(String host, int port) { public void checkConnect(String host, int port) {
if(printing)
System.out.println("Connecting to: " + host + ":" + port);
} }
@Override @Override
@ -124,6 +138,8 @@ public class SecurityMan extends SecurityManager {
@Override @Override
public void checkDelete(String file) { public void checkDelete(String file) {
if(printing)
System.out.println("Deleting: " + file);
} }
@Override @Override
@ -135,6 +151,8 @@ public class SecurityMan extends SecurityManager {
@Override @Override
public void checkLink(String lib) { public void checkLink(String lib) {
if(printing)
System.out.println("Linking: " + lib);
} }
@SuppressWarnings("deprecation") @SuppressWarnings("deprecation")
@ -151,6 +169,8 @@ public class SecurityMan extends SecurityManager {
@SuppressWarnings("deprecation") @SuppressWarnings("deprecation")
public void checkPackageAccess(String pkg) { public void checkPackageAccess(String pkg) {
if(printingPackage)
System.out.println("Accessing: " + pkg);
} }
@Override @Override
@ -175,6 +195,8 @@ public class SecurityMan extends SecurityManager {
@Override @Override
public void checkRead(String file) { public void checkRead(String file) {
if(printing)
System.out.println("Reading: " + file);
} }
@Override @Override
@ -199,5 +221,7 @@ public class SecurityMan extends SecurityManager {
@Override @Override
public void checkWrite(String file) { public void checkWrite(String file) {
if(printing)
System.out.println("Writing: " + file);
} }
} }