Skip to content

Commit

Permalink
Massive performance increase for process attach analysis
Browse files Browse the repository at this point in the history
  • Loading branch information
planetlevel committed Jan 14, 2022
1 parent 0ae27e4 commit c7c692c
Show file tree
Hide file tree
Showing 6 changed files with 750 additions and 21 deletions.
701 changes: 701 additions & 0 deletions hs_err_pid20082.log

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion src/main/java/com/contrastsecurity/Agent.java
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ public static void transform(String args, Instrumentation inst) {
}

reportResults( libs, filename );
Logger.log( "jbom complete. SBOM with " + libs.getLibraries().size() + " libraries written to " + filename );
Logger.log( "jbom complete" );
Logger.log( "==================================" );

agentRunning = false;
Expand Down
2 changes: 1 addition & 1 deletion src/main/java/com/contrastsecurity/CycloneDXModel.java
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@ public static Metadata makeMetadata() {

public void save( String filename ) {
try {
Logger.log( "Saving SBOM with " + getComponents().size() + " to " + filename );
Logger.log( "Saving SBOM with " + getComponents().size() + " components to " + filename );
BomJsonGenerator bomGenerator = BomGeneratorFactory.createJson(CycloneDxSchema.VERSION_LATEST, this);
String bomString = bomGenerator.toJsonString();
FileUtils.write(new File(filename), bomString, Charset.forName("UTF-8"), false);
Expand Down
28 changes: 20 additions & 8 deletions src/main/java/com/contrastsecurity/Jbom.java
Original file line number Diff line number Diff line change
Expand Up @@ -33,19 +33,19 @@ public class Jbom implements Runnable {
@CommandLine.Option(names = { "-h", "--host" }, description = "Hostname or IP address to connect to")
private String host = null;

@CommandLine.Option(names = { "-u", "--user" }, description = "Username of user to connect as")
@CommandLine.Option(names = { "-U", "--user" }, description = "Username of user to connect as")
private String user;

@CommandLine.Option(names = { "-p", "--pass" }, description = "Password for user" )
@CommandLine.Option(names = { "-P", "--password" }, description = "Password for user" )
private String pass;

@CommandLine.Option(names = { "-r", "--remote" }, defaultValue = "/tmp/jbom", description = "Remote directory to use" )
private String remoteDir = "/tmp/jbom";

@CommandLine.Option(names = { "-j", "--jvmpid" }, defaultValue = "all", description = "JVM PID to attach to or 'all'" )
@CommandLine.Option(names = { "-p", "--pid" }, defaultValue = "all", description = "Java process pid to attach to or 'all'" )
private String pid = "all";

@CommandLine.Option(names = { "-x", "--exclude" }, description = "JVM PID to exclude" )
@CommandLine.Option(names = { "-x", "--exclude" }, description = "Java process pid to exclude" )
private String exclude;

@CommandLine.Option(names = { "-f", "--file" }, description = "File to be scanned" )
Expand All @@ -60,6 +60,9 @@ public class Jbom implements Runnable {
@CommandLine.Option(names = { "-t", "--tag" }, description = "Tag to use in output filenames" )
private String tag;

@CommandLine.Option(names = { "-D", "--debug" }, description = "Enable debug output" )
private boolean debug = false;


public static void main(String[] args){
int exitCode = new CommandLine(new Jbom()).execute(args);
Expand All @@ -71,6 +74,7 @@ public void run() {

Jbom jbom = new Jbom();
jbom.printBanner();
Logger.setDebug( debug );

// remote
if ( host != null ) {
Expand Down Expand Up @@ -131,7 +135,7 @@ public void doLocalProcess(String pid, String exclude, String outputDir, String
}
} else {
Logger.log( "Analyzing local Java process with pid " + pid );
String name = outputDir + "/jbom-" + ( tag == null ? "" : "-" +tag ) + "-" + pid + ".json";
String name = outputDir + "/jbom" + ( tag == null ? "" : "-" +tag ) + "-" + pid + ".json";
generateBOM( pid, name);
}
}
Expand All @@ -152,7 +156,15 @@ public Libraries doLocalFile(String file, String outputDir) {
}

try{
String name = file.substring( 0, file.lastIndexOf('.'));
String name = file;
int idx = name.lastIndexOf('/');
if ( idx != -1 ) {
name = name.substring( idx + 1 );
}
idx = name.lastIndexOf('.');
if ( idx != -1 ) {
name = name.substring( 0, idx );
}
name = outputDir + "/jbom-" + name + ( tag == null ? "" : "-" +tag ) + ".json";
libs.runScan( f );
libs.save(name);
Expand Down Expand Up @@ -209,7 +221,7 @@ public void doRemoteDirectory(String dir, String outputDir, String host, String

// 2. run java -jar jbom.jar on remote server
Logger.log( "Connecting to " + host );
remote.exec( "java -jar " + agentFile.getAbsolutePath() + " -d " + dir + " -o " + remoteDir + " -p " + tag );
remote.exec( "java -jar " + agentFile.getAbsolutePath() + " -d " + dir + " -o " + remoteDir + " -p " + tag + ( debug ? " -D" : "" ));

// 3. download results and cleanup
File odir = new File( outputDir );
Expand Down Expand Up @@ -268,7 +280,7 @@ public void doRemoteProcess(String pid, String exclude, String outputDir, String
// 2. run java -jar jbom.jar on remote server
Logger.log( "Connecting to " + host );
String myPid = ByteBuddyAgent.ProcessProvider.ForCurrentVm.INSTANCE.resolve();
remote.exec( "java -jar " + agentFile.getAbsolutePath() + " -x " + myPid + " -o " + remoteDir + " -p " + tag );
remote.exec( "java -jar " + agentFile.getAbsolutePath() + " -x " + myPid + " -o " + remoteDir + " -p " + tag + ( debug ? " -D" : "" ));

// 3. download results and cleanup
File odir = new File( outputDir );
Expand Down
25 changes: 14 additions & 11 deletions src/main/java/com/contrastsecurity/Libraries.java
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,6 @@
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.TreeSet;
import java.util.jar.Attributes;
import java.util.jar.JarEntry;
import java.util.jar.JarFile;
Expand Down Expand Up @@ -57,11 +56,6 @@ public void addAllLibraries( Class clazz, String codesource ) {
// FIXME - change codesourceExamined to a Map<codesource, Library>
// increment library.classesUsed;

if ( codesourceExamined.contains( codesource ) ) {
return;
}
codesourceExamined.add( codesource );

if ( !isArchive( codesource ) ) {
return;
}
Expand All @@ -71,16 +65,24 @@ public void addAllLibraries( Class clazz, String codesource ) {
String filepath = decoded.substring( decoded.lastIndexOf(":") + 1);
String parts[] = filepath.split( "!/" );
String path = parts[0];

if ( codesourceExamined.contains( path ) ) {
return;
}
codesourceExamined.add( path );

File f = new File( path );
Library lib = new Library( parts[parts.length-1] ); // last segment
lib.parsePath( path );
lib.setType( Library.Type.LIBRARY );
lib.addProperty( "codesource", path );

Logger.debug( "MAIN: " + codesource );

// add Contrast custom properties
lib.addProperty("source", "Contrast Security - https://contrastsecurity.com");
lib.addProperty("tool", "jbom - https://github.com/Contrast-Security-OSS/jbom");
lib.setScope( Scope.REQUIRED );
lib.addProperty( "codesource", codesource );

libraries.add( lib );
invoked.add( lib );
Expand All @@ -98,10 +100,10 @@ public void addAllLibraries( Class clazz, String codesource ) {
// scan for nested libraries
JarInputStream jis3 = new JarInputStream( new FileInputStream( f ) );
JarFile jarfile = new JarFile( f );
scan( jarfile, jis3, codesource );
scan( jarfile, jis3, f.getAbsolutePath() );
} catch( Exception e ) {
Logger.log( "The safelog4j project needs your help to deal with unusual CodeSources." );
Logger.log( "Report issue here: https://github.com/Contrast-Security-OSS/safelog4j/issues/new/choose" );
Logger.log( "The jbom project needs your help to deal with unusual CodeSources." );
Logger.log( "Report issue here: https://github.com/Contrast-Security-OSS/jbom/issues/new/choose" );
Logger.log( "Please include:" );
Logger.log( " CodeSource: " + codesource );
e.printStackTrace();
Expand All @@ -128,7 +130,8 @@ public void scanInner( String codesource, JarFile jarFile, JarInputStream jis, J
// FIXME: set Scope.EXCLUDED for non-invoked libraries
innerlib.setScope( Scope.REQUIRED );
innerlib.parsePath( entry.getName() );
innerlib.addProperty( "codesource", codesource );
innerlib.addProperty( "codesource", jarFile.getName() + "!/" + entry.getName() );
Logger.debug( " INNER " + entry.getName() );

libraries.add( innerlib );
innerlib.setType( Library.Type.LIBRARY );
Expand Down
13 changes: 13 additions & 0 deletions src/main/java/com/contrastsecurity/Logger.java
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,23 @@
public class Logger {

public static SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss:SSS");
private static boolean debug = false;

public static void log( String msg ) {
String stamp = formatter.format(new Date());
String message = stamp + " TRACE --- [jbom] " + msg;
System.out.println( message );
}

public static void debug( String msg ) {
if ( debug ) {
String stamp = formatter.format(new Date());
String message = stamp + " DEBUG --- [jbom] " + msg;
System.out.println( message );
}
}

public static void setDebug(boolean debug) {
Logger.debug = debug;
}
}

0 comments on commit c7c692c

Please sign in to comment.