Menu

Are there any options to change the search path for DLLs via Launch4j?

2023-10-20
2024-02-08
  • Infinite Blue

    Infinite Blue - 2023-10-20

    I'm currently looking into an issue with our launch4j wrapped application where one of the DLLs that is brought in by a library in our application (cryptbase.dll) appears to be vulnerable to a DLL injection attack.

    If we place a file named cryptbase.dll alongside the launch4j generated EXE file, the application crashes before any loading is done showing that it's pulled in the "malicious" DLL. (In this case, this DLL was provided to me as a test case for demonstrating a DLL hijacking issue.) However, if I run the JAR file that was wrapped using Launch4J, no such error occurs, which leads me to believe there is some DLL loading for JNI being performed by/filtered through Launch4j.

    When using ProcessMonitor to identify the files that are being opened, I get the following event recorded if the cryptbase.dll file is not present alongside the EXE showing that it was requested by the Launch4j wrapped EXE:

    23:17.0 <wrapped.exe> 35552 CreateFile C:\<applicationfolder>\CRYPTBASE.DLL NAME NOT FOUND Desired Access: Read Attributes, Disposition: Open, Options: Open Reparse Point, Attributes: n/a, ShareMode: Read, Write, Delete, AllocationSize: n/a</applicationfolder></wrapped.exe>

    If the DLL is present, the application crashes before it has a chance to report on it. This DLL is expected to be loaded based on the java application's use of the WinDPAPI4j library, though I'd have expected the JVM to make the request rather than the wrapped executable.


    From Microsoft's documentation around the DLL search path (https://learn.microsoft.com/en-us/windows/win32/dlls/dynamic-link-library-security) they mention that by default, the first location searched is along side the application. So this is likely why it's being picked up, but I'm not familiar enough with launch4j / windows programming to know if there's anything that can be done.

    --

    With the background out of the way, my question is whether or not there is any way, through an option already in the library or that could be coded into the library that would allow me to tell Launch4J to ignore the application directory when searching for DLL files? I know that the application will never need to load a DLL placed alongside it, and would like to just eliminate that as a search option entirely.

    Thank you!

     
  • Grzegorz Kowal

    Grzegorz Kowal - 2023-10-22

    Hi,

    If the DLL is present, the application crashes before it has a chance to report on it. This DLL is expected to be loaded based on the java application's use of the WinDPAPI4j library, though I'd have expected the JVM to make the request rather than the wrapped executable.

    If you are using the launch4j JNI wrapper then the JVM instance is created within the wrapped executable process, so it does make sense that you see that this executable is trying to gain access. The wrapper itself loads only the jvm.dll and its dependencies, what you are observing must be the effect of the Java application. It difficult to say why it crashes, perhaps due to the JNI wrapper missing some functionality. Try using the standard wrapper if possible.

    Best regards,
    Grzegorz

     
  • Infinite Blue

    Infinite Blue - 2023-11-16

    Apologies for the delay, but at the very least I can now point to where the problem appears to be coming in from.

    Our configuration is using the launch4j-maven-plugin to perform the final Launch4j wrapping of the JAR file. We're using standard GUI mode (<headertype>gui</headertype>) with a splash screen.

    We are using the WinDPAPI4j library during startup to decrypt an encrypted string. During testing, one of our testers found that it was possible to create a dummy DLL file alongside the application EXE file and cause the application to crash. The tester used a properly compiled DLL that would display a dialog to demonstrate DLL hijacking, but I'm able to reproduce the problem using just a text file named appropriately.

    With a text file, it displays an error dialog instead of crashing silently: "<pathtoexefolder>/cryptbase.dll is either not designed to run on Windows or it contains an error. Try installing the program again using the original installation media or contact your system administrator or the software vendor for support. Error status 0xc0000020."</pathtoexefolder>

    The strange thing is, the DLL import / crash only appears to be brought in if we're using headerType gui with a splash screen configured. If I change to console mode, or remove the splash screen from the launch4j configuration, I'm no longer able to reproduce the crash.

    I'm not very well versed in Windows programming, so I'm curious if you'd know or be able to figure out what might differ between gui / console and gui with splash screen that could cause Windows to suddenly want to bring in this dependency only in the GUI with Splash screen case?

    I have put together some code that can reproduce the problem, though I wanted to confirm whether or not you wanted me to post it on github, or send the content through some other means. What would work best?

     
    • Lilianne E. Blaze

      Try setting " java.library.path" System property to where your lib is supposed to be very early during the program start, before any class that can directly or indirectly access that lib gets loaded.
      I had a similar problem in GraalVM - it crashed when glass.dll was on the path.
      https://github.com/gluonhq/substrate/issues/1190
      https://github.com/gluonhq/scenebuilder/pull/358/files

       
      • Infinite Blue

        Infinite Blue - 2024-02-08

        Funny enough, as part of my launch4j config, I already set the -Djava.library.path option for my application to a location that does not include the executable file. I don't think I can get any earlier than that, but I guess it depends on when the JVM processes the command line options.

        I just find it weird that the problem in my case is only reproducible with the splash screen option configured, and does not reproduce if I don't have the splash screen configured.

         

Log in to post a comment.

Want the latest updates on software, tech news, and AI?
Get latest updates about software, tech news, and AI from SourceForge directly in your inbox once a month.