TL;DR: I know a program creates and then deletes files in /tmp. How can I intercept them for examination ?


There's a particular .jar file, which I don't trust; for some reason its source code contains an ftm method and has capability to make connections, which is evident from network-related syscalls in output of strace (and when I mean connection, I don't mean unix domain sockets, it's AF_INET6). I've examined with Wireshark and saw no outgoing TCP or UDP connections during it's use.

However, I still don't quite trust it. From the output of strace I've seen that it's creating temporary files in /tmp and then deletes them. Is there a way to intercept those files to examine their contents ?

  • 3
    LD_PRELOAD intercepting unlink before calling java.... serverfault.com/questions/75927/blocking-rm-rf-for-application – Rui F Ribeiro Sep 10 '18 at 20:50
  • @RuiFRibeiro Thanks for the link. Tried the suggestion, made unlink.so. Now difference between ls /tmp before and after running the command. I'm no expert on shared libraries, or Java, but seems like unlink.so wasn't used by it, so just a guess but maybe Java doesn't use unlink(). I'm hoping someone can suggest a more or less universal way, because I want this to work consistently. I don't care how the program in question is done, I just want to see its temp files. – Sergiy Kolodyazhnyy Sep 10 '18 at 21:00
  • does strace show anything being written to said files? (strace may need flags to increase how much it logs) – thrig Sep 10 '18 at 21:01
  • @thrig With strace -f -e open,write,unlink java -jar file.jar input.txt I see there are writes to particular file descriptors. There's openat(AT_FDCWD, "/tmp/imageio1355028222376675525.tmp", O_WRONLY|O_CREAT|O_EXCL, 0600) = 16 , and data written to it appears to be the header of the output png file. So it writes output file to tmp first. I also see another temp file being opened and reopened as fd 4: openat(AT_FDCWD, "/tmp/hsperfdata_xie", O_RDONLY|O_NONBLOCK|O_CLOEXEC|O_DIRECTORY) = 4 But I don't see any writes to fd 4. Makes no sense to create O_RDONLY file and keep it empty – Sergiy Kolodyazhnyy Sep 10 '18 at 21:12
  • 2
    As to the files rather than your Q, /tmp/hsperfdata_$user/ is 'HotSpot performance data' created automatically by the Sun/Oracle/OpenJDK JVM (which is codenamed HotSpot) with the JVM pid as filename and used by utilities like jps jstat jmap jconsole. See e.g. stackoverflow.com/questions/76327/… stackoverflow.com/questions/3806758/… – dave_thompson_085 Sep 11 '18 at 1:09

Better yet, if you want to reverse engineer a nefarious Java binary, rather than trying to intercept files, decompile the suspect .jar file.

For it, you can use CFR - another java decompiler

CFR will decompile modern Java features - up to and including much of Java 9, but is written entirely in Java 6, so will work anywhere

To use, simply run the specific version jar, with the class name(s) you want to decompile (either as a path to a class file, or as a fully qualified classname on your classpath). (--help to list arguments).

Alternately, to decompile an entire jar, simply provide the jar path, and if you want to emit files (which you probably do!) add --outputdir /tmp/putithere

There are no lack of alternatives, however the CFR project seems to be well maintained, having a 2018 update.

Disclaimer: I have not done reverse engineering to Java/JAR binaries since 2005

  • 2
    While this is a great answer to the A/B problem presented in the question, it doesn't actually answer it as written. – Nonny Moose Sep 11 '18 at 2:00
  • @NonnyMoose Indeed. I proposed the OP a LD_PRELOAD in comments but apparently something is amiss. – Rui F Ribeiro Sep 11 '18 at 6:14

Note: improved solution posted at duplicate question

From reading How to access temporary file straight after creation? I got the idea of using inotify and creating a hard-link to file itself. This of course is a race condition, since file could be unlinked before hard link is created, however I did manage to recover the data in the temporary file the application is creating. Here's a short pipeline put together in terminal tab A, with terminal tab B running the actual command:

inotifywait -m -r /tmp/hsperfdata_xie/ 2>&1 | 
while IFS= read -r line; do 

    awk '$2 == "CREATE"{system("ln /tmp/hsperfdata_xie/"$3" /tmp/BACKUP")}' <<< "$line"
    echo "$line" # unnecessary, only if you want to know what's inotify is writing

The 3 disadvantages are:

  • race condition (explained above)
  • I put together awk very quickly for one specific file; but a more general and flexible awk command that parses inotifywatch output and joins pathnames $1 with filenames in $3 would have to take a bit of time to parse the lines, sprintf() everything to variable, and pass to system(), which may go back to previous bullet point - by the time parsing is done, there's no file to link.
  • requires two terminal tabs, although one could put the whole pipeline into background. A smarter way would be to have a full Python script with forked subprocesses and actually use inotify Python modules ( which maybe something I'll do in future).

As for file in question, it appears as some form of binary data, with recurring 0...sun.rt._sync_Inflations and 0...sun.rt._sync_Deflations strings (which may be related to Java multithreading). But for the purpose of this question, it's irrelevant - we already have. The only thing I wanted is to obtain the file itself.

Not the answer you're looking for? Browse other questions tagged or ask your own question.