frida / frida-gum

Cross-platform instrumentation and introspection library written in C
https://frida.re
Other
727 stars 240 forks source link

DbgHelp Symbols not available - 2nd attach - OpenJDK Windows #811

Open FrankSpierings opened 1 month ago

FrankSpierings commented 1 month ago

Issue description

I was looking fixing the debugging of Windows based Java applications, using OpenJDK from Microsoft and the debugging symbols, available here; https://learn.microsoft.com/en-gb/java/openjdk/download.

While attempting to fix an issue where several methods won't be found by frida-java-bridge, I noticed that DebugSymbol.findFunctionsMatching("*") would not return anything, when attached to the same Java process a second time.

Issue reproduction

  1. To reproduce, the following sample UI application can be used.

HelloWorldGui.java

import javax.swing.*;

public class HelloWorldGUI {
    public static void main(String[] args) {
        // Create the GUI on the Event Dispatch Thread
        SwingUtilities.invokeLater(() -> createAndShowGUI());
    }

    private static void createAndShowGUI() {
        // Create and set up the window
        JFrame frame = new JFrame("Hello World GUI");
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

        // Create and set up the content pane
        JLabel label = new JLabel("Hello, World!");
        frame.getContentPane().add(label);

        // Display the window
        frame.pack();
        frame.setLocationRelativeTo(null); // Center the window
        frame.setVisible(true);
    }
}
  1. Running it with OpenJDK 17 on Windows (also make sure the debug symbols (pdb's) are placed next to the binaries)
C:\jdk-17.0.11+9\bin\java.exe HelloWorldGUI.java
  1. Attach to the process using Frida, run DebugSymbol.findFunctionsMatching("*"), this should result in a large list of ptr's. If not, the debug symbols are likely missing.

  2. Detach frida

  3. Reattach frida and run DebugSymbol.findFunctionsMatching("*"). BUG HERE The list is now empty.

Additional investigation

function GetCurrentProcess() {
  return (new NativeFunction(Module.getExportByName("Kernel32.dll", "GetCurrentProcess"), "pointer", []))();
}

function SymCleanup(process) {
  return (
    new NativeFunction(
      Module.getExportByName("dbghelp.dll", "SymCleanup"), "bool", [
        "pointer",
      ]))(
        process
      );
}

var result = SymCleanup(GetCurrentProcess());
console.log("SymCleanup", result);