Search code examples
javalinuxexectrace

What is JAVA exec()uting?


I'm on Linux and I have a Java application (JAR archive) which is using exec() to do it's stuff. I need to find out which commands is that application exec()uting... I tried strace and jstack but without any results. Suppose that the app is calling exec("ls"), can I find that ls command just by grepping output of above programs?

So the question is: Is there a simple way to watch what is Java application executing with exec() ?

Edit for better situation overview:

Suppose that in Java app i have a button with onclick listener which calls static function from another class.In that function is exec("ls"); called. When I click that button I see this in strace:

futex(0x7f14a6f799d0, FUTEX_WAIT, 4968, NULLDownload button clicked ! Trying SCP FROM... <unfinished ...>

Trying SCP FROM.. is just my sout in that button handler right before calling exec().

Another edit: Thank you guys, but I'm talking from OS point of view... Suppose that I'm sysadmin and I downloaded JAR. I want to know (from outside) what is that JAR doing - I'm only interested in programs started from exec()

So I tried strace but it shows nothing about calling that command from exec... Maybe it is logging too much low level calls for this...

Then i tried jstack -m but I can't find anything looking like that command from exec. I tried grepping string but with no luck.


Solution

  • Ok, what I'm going to propose is a veeeeeeeeeery rudimentary way of doing things, but it might be what you are looking for.

    As you probably know, a .jar file is just a ZIP archive comprised of Java .class files. If you just need to get a peek at which commands are going to be executed, and if you know the class that is supposed to execute them, you can just extract the class files from the jar file with gzip and then use strings on them to look for commands.

    For example, here's the most simple class I could think of that uses exec():

    import java.io.IOException;
    
    public class Main {
        public static void main(String[] args) {
            try {
                Runtime.getRuntime().exec("/bin/ls");
            } catch (IOException ignored) {}
        }
    }
    

    If you do strings Main.class you should get something like this:

    [...]$ strings Main.class
    <init>
    Code
    LineNumberTable
    LocalVariableTable
    this
    LMain;
    main
    ([Ljava/lang/String;)V
    args
    [Ljava/lang/String;
    StackMapTable
    SourceFile
            Main.java
    /bin/ls
    java/io/IOException
    Main
    java/lang/Object
    java/lang/Runtime
    getRuntime
    ()Ljava/lang/Runtime;
    exec
    '(Ljava/lang/String;)Ljava/lang/Process;
    

    As you can see, /bin/ls can be identified as a string. This should work in most cases, unless your Java program is constructing commands in a weird way, like using a char array to create command strings during runtime just to obscure the commands being executed (in which case I'd be highly suspicious of such a program).

    However, if you want to see the commands executing in real time, I'm afraid you'll need to resort to some monitoring utility, since most commands would be too short-lived to even appear on top and the like.

    EDIT: Regarding strace: I had a look at Java's native C code for UNIX systems and it seems that it actually uses the execvpe() system call to run all commands launched with Runtime.exec():

        execvpe(argv[0], argv, envv);
    

    So, in theory, you should be able to run strace -e execvpe <java command...> to list every command executed (as well as every other call to execvpe() -- you'll need to filter a bit more, that's true).