1. #1

    Registriert seit
    19.11.2011
    Beiträge
    229
    Thanked 102 Times in 64 Posts

    Standard Prozess Module laden mit JNA

    Hi,
    versuche grad alle geladenen Module eines Prozesses auszulesen.

    In C# ist das ja ganz einfach:

    ProcessModuleCollection myProcessModuleCollection;
    ProcessModule myProcessModule = null;
    try
    {
    myProcessModuleCollection = currentProcess.Modules;
    }


    Allerdings habe ich keine Ahnung wie ich in Java an diese Module rankomme.

    Arbeite in Java mit: JNA und Psapi
    Geändert von DANP (22.11.2013 um 16:16 Uhr)


  2. #2
    Avatar von Nuebel
    Registriert seit
    23.11.2013
    Beiträge
    446
    Thanked 361 Times in 236 Posts

    Standard AW: Prozess Module laden mit JNA

    Muss es JNA sein?
    Ich habe mal ein Interface definiert, aber als ich es dann testen wollte, hatte ich die Schnauze voll.

    public interface Psapi extends StdCallLibrary {
    Psapi INSTANCE = (Psapi) Native.loadLibrary("Psapi", Psapi.class);

    /*
    * BOOL WINAPI EnumProcesses(
    * _Out_ DWORD *pProcessIds,
    * _In_ DWORD cb,
    * _Out_ DWORD *pBytesReturned
    * );
    */
    boolean EnumProcesses(
    DWORD[] pProcessIds,
    DWORD cb,
    IntByReference pBytesReturned
    );

    /*
    * BOOL WINAPI EnumProcessModules(
    * _IN_ HANDLE hProcess,
    * _Out_ HMODULE *lphModule,
    * _In_ DWORD cb,
    * _Out_ LPDWORD lpcbNeeded,
    * );
    */
    boolean EnumProcessModules(
    HANDLE hProcess,
    Pointer[] lphModule,
    DWORD cb,
    IntByReference lpcbNeeded
    );

    /*
    * DWORD WINAPI GetModuleFileNameEx(
    * _In_ HANDLE hProcess,
    * _In_opt_ HMODULE hModule,
    * _Out_ LPTSTR lpFilename,
    * _In_ DWORD nSize
    * );
    */
    DWORD GetModuleFileNameEx(
    HANDLE hProces,
    HMODULE hModule,
    String lpFilename,
    DWORD nSize
    );
    }


    Da ich mich nicht ansatzweise in JNA reingelesen habe, bin ich mir nicht sicher, ob es vorteilhaft ist, die JNA-äquivalenten Datentypwrapper zu benutzen anstatt primitive wo möglich. Es gibt auch Fälle, bei denen ein Array eines Typs erwartet wird, statt eines JNA-Pointers und umgekehrt.
    EnumProcesses habe ich noch mit einigem Gefummel hinbekommen, aber als es an die Module ging, hagelte es ERROR_ACCESS_DENIED und ERROR_INVALID_HANDLE. Wie gesagt, ich bin in JNA nicht firm.

    Mit JNI allerdings stell ich mir die Sache leicht vor. Käme das für dich in Betracht?

  3. The Following 2 Users Say Thank You to Nuebel For This Useful Post:

    Essah (24.11.2013), Kollegah (09.06.2015)

  4. #3

    Registriert seit
    19.11.2011
    Beiträge
    229
    Thanked 102 Times in 64 Posts

    Standard AW: Prozess Module laden mit JNA

    Deine Fehlermeldungen sehen für mich einfach wie falsche Startrechte beim Prozess aus.

    Aber klar - ich nehme alles was ich bekommen kann


  5. #4
    Avatar von Nuebel
    Registriert seit
    23.11.2013
    Beiträge
    446
    Thanked 361 Times in 236 Posts

    Standard AW: Prozess Module laden mit JNA

    Zitat Zitat von Nuebel
    Mit JNI allerdings stell ich mir die Sache leicht vor
    Diese Aussage nehme ich zurück!

    Zitat Zitat von DANP
    Deine Fehlermeldungen sehen für mich einfach wie falsche Startrechte beim Prozess aus.
    Für mich auch. Obwohl ich PROCESS_QUERY_INFORMATION | PROCESS_VM_READ setzte.


    Ich habe es weder mit JNA noch mit JNI geschafft, dein Vorhaben zu realisieren. Bin mir allerdings sicher, dass es möglich ist. Vielleicht werde ich mich bei Lust und Zeit soweit darin einarbeiten.
    Über einen anderen (nicht schönen) Weg bin ich trotzdem zu einer Lösung gekommen. Ich habe dieses Beispiel kompiliert, die Ausgabe ein bisschen verändert und in eine Datei umgeleitet. Dieses Programm rufe ich aus Java heraus auf (Achtung, quick&dirty):

    EnumProcessModules.cpp

    #include <windows.h>
    #include <tchar.h>
    #include <stdio.h>
    #include <psapi.h>
    #include <stdio.h>

    FILE *file;

    // To ensure correct resolution of symbols, add Psapi.lib to TARGETLIBS
    // and compile with -DPSAPI_VERSION=1

    int PrintModules(DWORD processID )
    {
    HMODULE hMods[1024];
    HANDLE hProcess;
    DWORD cbNeeded;
    unsigned int i;

    // Print the process identifier.

    fprintf(file, "Process ID: %u\n", processID );

    // Get a handle to the process.

    hProcess = OpenProcess( PROCESS_QUERY_INFORMATION |
    PROCESS_VM_READ,
    FALSE, processID );
    if (NULL == hProcess)
    return 1;

    // Get a list of all the modules in this process.

    if( EnumProcessModules(hProcess, hMods, sizeof(hMods), &cbNeeded))
    {
    for ( i = 0; i < (cbNeeded / sizeof(HMODULE)); i++ )
    {
    TCHAR szModName[MAX_PATH];

    // Get the full path to the module's file.

    if ( GetModuleFileNameEx( hProcess, hMods[i], szModName,
    sizeof(szModName) / sizeof(TCHAR)))
    {
    // Print the module name and handle value.

    fprintf(file, TEXT("\t%s (0x%08X)\n"), szModName, hMods[i] );
    }
    }
    }

    // Release the handle to the process.

    CloseHandle( hProcess );

    return 0;
    }

    int main( int argc, char *argv[] )
    {
    file = fopen (argv[1], "a+");

    DWORD aProcesses[1024];
    DWORD cbNeeded;
    DWORD cProcesses;
    unsigned int i;

    // Get the list of process identifiers.

    if ( !EnumProcesses( aProcesses, sizeof(aProcesses), &cbNeeded ) )
    return 1;

    // Calculate how many process identifiers were returned.

    cProcesses = cbNeeded / sizeof(DWORD);

    // Print the names of the modules for each process.

    for ( i = 0; i < cProcesses; i++ )
    {
    fprintf(file, "\n--- START ---\n");
    PrintModules(aProcesses[i] );
    fprintf(file, "--- END ---\n");
    }

    fclose(file);

    return 0;
    }


    EnumProcessModulesDemo.java

    import java.io.*;
    import java.util.*;

    public class EnumProcessModulesDemo {

    public static void main(String[] args) {
    EnumProcessModulesDemo epmd = new EnumProcessModulesDemo("processmodules.txt");
    epmd.printAll();
    }

    // ----------------------------------------------------

    private final String filename;

    public EnumProcessModulesDemo(String filename) {
    this.filename = filename;
    }

    public void printAll() {
    deleteFile();
    callExternalProgram();
    waitForFile();
    final List<String> information = readAll();
    for (String info : information) {
    System.out.println(info);
    }
    }

    private List<String> readAll() {
    final List<String> information = new ArrayList<>();
    try {
    final BufferedReader br = new BufferedReader(new FileReader(filename));
    StringBuilder sb = new StringBuilder();
    String line = "";
    while((line = br.readLine()) != null) {
    if (line.equals("--- END ---")) {
    information.add(sb.toString());
    continue;
    }
    if (line.equals("--- START ---")) {
    sb = new StringBuilder();
    continue;
    }
    sb.append(line + "\n");
    }
    } catch (IOException ioe) {
    ioe.printStackTrace();
    }
    return information;
    }

    private void callExternalProgram() {
    try {
    Runtime.getRuntime().exec("EnumProcessModules.exe " + filename);
    } catch (IOException ioe) {
    ioe.printStackTrace();
    }
    }

    private void deleteFile() {
    final File file = new File(filename);
    file.delete();
    }

    private void waitForFile() {
    final File file = new File(filename);
    while (!(file.isFile() && file.canRead())) {
    try {
    Thread.sleep(100);
    } catch (InterruptedException ie) {
    ie.printStackTrace();
    }
    }
    }
    }


    Folgende Ausgabe generiert das Java-Programm (Ausschnitt):


    Die Daten wurden von mir nur sehr rudimentär aufgearbeitet. In der Liste von Strings besteht ein Eintrag aus den Informationen eines Prozesses. Schöner wäre, wenn das C++-Programm eine XML-Ausgabe o.Ä. generiert, die dann hübsch von Java geparsed werden kann. Aber dazu hatte ich jetzt keine Lust mehr.

    Falls du an diesem Lösungsweg interessiert bist, ist im Anhang ein Archiv, das sämtlichen Code und das bereits kompilierte C++-Programm enthält.
    Angehängte Dateien Angehängte Dateien

  6. The Following User Says Thank You to Nuebel For This Useful Post:

    Kollegah (09.06.2015)

  7. #5

    Registriert seit
    19.11.2011
    Beiträge
    229
    Thanked 102 Times in 64 Posts

    Standard AW: Prozess Module laden mit JNA

    Zu deinem Problem:
    Versuch es mit diesen Rechten: 0x001F0FFF (PROCESS_ALL_ACCESS ).
    Die Lösung sieht nett aus. Ist allerdings für mich nicht praktikabel....

    Desweiteren suche ich weiter wie das in native Java mit seinen Frameworks gelöst werden kann !"


  8. #6
    Avatar von Nuebel
    Registriert seit
    23.11.2013
    Beiträge
    446
    Thanked 361 Times in 236 Posts

    Standard AW: Prozess Module laden mit JNA

    Ich habe mich noch einmal an JNA versucht, und bin dieses Mal etwas weiter gekommen.


    import java.util.ArrayList;
    import java.util.List;

    import com.sun.jna.Native;
    import com.sun.jna.Pointer;
    import com.sun.jna.platform.win32.Kernel32;
    import com.sun.jna.platform.win32.WinNT.HANDLE;
    import com.sun.jna.ptr.IntByReference;
    import com.sun.jna.win32.StdCallLibrary;


    public class JPsapiDemo {
    public static final int PROCESS_QUERY_INFORMATION = 0x0400;
    public static final int PROCESS_VM_READ = 0x0010;

    public static void main(String[] args) {
    final List<Integer> processIdList = getProcessIds();

    for (int i = 0; i < processIdList.size(); ++i) {
    HANDLE hProcess = Kernel32.INSTANCE.OpenProcess(
    PROCESS_QUERY_INFORMATION | PROCESS_VM_READ, false, processIdList.get(i));

    if (hProcess == null)
    continue;

    Pointer[] hMods = new Pointer[1024];
    IntByReference lpcbNeeded = new IntByReference();

    if (Psapi.INSTANCE.EnumProcessModules(hProcess, hMods, hMods.length, lpcbNeeded)) {
    for (int k = 0; k < lpcbNeeded.getValue() / Integer.SIZE * 4; ++k) {
    byte[] name = new byte[1024];
    if (0 != Psapi.INSTANCE.GetModuleFileNameExA(hProcess, hMods[k], name, 1024))
    System.out.println(Native.toString(name));
    }
    } else {
    System.err.println("EnumProcessModules: " + Native.getLastError());
    }

    System.out.println();
    }
    }

    public static List<Integer> getProcessIds() {
    final List<Integer> processIdList = new ArrayList<>();

    int[] pProcessIds = new int[1024];
    int cb = pProcessIds.length * Integer.SIZE;
    IntByReference pBytesReturned = new IntByReference();

    if(!Psapi.INSTANCE.EnumProcesses(pProcessIds, cb, pBytesReturned)) {
    System.err.println("EnumProcesses: " + Native.getLastError());
    }

    for (int i = 0; i < pProcessIds.length; ++i) {
    if (pProcessIds[i] != 0)
    processIdList.add(pProcessIds[i]);
    }

    return processIdList;
    }


    // ------------------------------------------------

    public interface Psapi extends StdCallLibrary {
    Psapi INSTANCE = (Psapi) Native.loadLibrary("Psapi", Psapi.class);

    /*
    * BOOL WINAPI EnumProcesses(
    * _Out_ DWORD *pProcessIds,
    * _In_ DWORD cb,
    * _Out_ DWORD *pBytesReturned
    * );
    */
    boolean EnumProcesses(int[] pProcessIds, int cb, IntByReference pBytesReturned);

    /*
    * BOOL WINAPI EnumProcessModules(
    * _IN_ HANDLE hProcess,
    * _Out_ HMODULE *lphModule,
    * _In_ DWORD cb,
    * _Out_ LPDWORD lpcbNeeded,
    * );
    */
    boolean EnumProcessModules(HANDLE hProcess, Pointer[] lphModule, int cb, IntByReference lpcbNeeded);

    /*
    * DWORD WINAPI GetModuleFileNameEx(
    * _In_ HANDLE hProcess,
    * _In_opt_ HMODULE hModule,
    * _Out_ LPTSTR lpFilename,
    * _In_ DWORD nSize
    * );
    */
    int GetModuleFileNameExA(HANDLE hProcess, Pointer hModule, byte[] lpFilename, int nSize);
    }
    }


    Ausgabe (Ausschnitt):


    Ich habe die Ausgabe mit der Ausgabe des C++-Programms verglichen und musste leider feststellen, dass die Ausgabe des Java-Programms nicht vollständig ist. Und zwar werden sämtliche 64-Bit-Module nicht erkannt. OS und JVM ist 64-Bit, aber aus mir unerklärlichen Gründen, sind die Prozesse scheinbar 32-Bit. Beispielsweise wird C:\Windows\system32\kernel32.dll geliefert statt C:\Windows\syswow64\kernel32.dll.

    Vielleicht hast du ja eine Idee, wie man diesen Umstand aus dem Weg räumen kann.

  9. The Following User Says Thank You to Nuebel For This Useful Post:

    Kollegah (09.06.2015)

  10. #7

    Registriert seit
    19.11.2011
    Beiträge
    229
    Thanked 102 Times in 64 Posts

    Standard AW: Prozess Module laden mit JNA

    Hi,
    einen ähnlichen Ansatz hatte ich auch schon. Kahm aber leider auf das gleiche Ergebnis.
    Um allerdings jetzt alle .dll Module anzeigen zu lassen gibt es das hier: EnumProcessModulesEx function (Windows)

    Einfach funktion um ein 0x03 erweitern und man bekommt alle module aufgelistet. (Für mein Beispiel fehlt allerdings eine bestimmte dll immernoch .... damn it)


Ähnliche Themen

  1. Module Tree Viewer Tool - Wer war des? oÔ
    Von Bubble Gum im Forum Ressourcen
    Antworten: 8
    Letzter Beitrag: 20.05.2013, 15:41
  2. :-Token (Module) parsen/schreiben
    Von Brainy im Forum Sourcecode
    Antworten: 3
    Letzter Beitrag: 11.07.2012, 20:01
  3. [Java] Module Protocol
    Von Flav im Forum Sourcecode
    Antworten: 0
    Letzter Beitrag: 09.04.2012, 03:38
  4. Merkwürdiger Prozess
    Von !lkay im Forum Internet und Technik
    Antworten: 1
    Letzter Beitrag: 10.03.2012, 14:01
  5. Tastendruck in Prozess senden
    Von Gangstersheep im Forum Hochsprachen
    Antworten: 9
    Letzter Beitrag: 03.11.2011, 00:13
Diese Seite nutzt Cookies, um das Nutzererlebnis zu verbessern. Klicken Sie hier, um das Cookie-Tracking zu deaktivieren.