Frage

Ich bin Trapping für die Ausführung von einigen alten 16-Bit-Anwendungen, die unsere intern Leute nicht mehr verwendet werden sollen. Sie sind 1985 DOS-Anwendungen, so dass für sie Trapping war einfach ... jeder Prozess erfassen, die unter NTVDM.exe startet

Nun, das Problem ist, herauszufinden, welches Programm NTVDM tatsächlich unter der Haube läuft. Offenbar gibt es eine coupleof die 1985-Programme, die sie ausgeführt werden dürfen, sollten Sie auf, also muß ich die eigentlichen EXE Namen, um zu sehen, die unter NTVDM versteckt.

        WqlEventQuery query =
            new WqlEventQuery("__InstanceCreationEvent",
            new TimeSpan(0, 0, 1),
            "TargetInstance isa \"Win32_Process\"");

        ManagementEventWatcher watcher = new ManagementEventWatcher(query);

        watcher.EventArrived += new EventArrivedEventHandler(watcher_EventArrived);

        watcher.Start();


...


    static void watcher_EventArrived(object sender, EventArrivedEventArgs e)
    {
        ManagementBaseObject instance = (ManagementBaseObject)e.NewEvent["TargetInstance"];

        ProcessInfo PI = new ProcessInfo();
        PI.ProcessID = int.Parse(instance["ProcessID"].ToString());
        PI.ProcessName = instance["Name"].ToString();
        PI.ProcessPath = instance["ExecutablePath"].ToString();

        // Here's the part I need...
        PI.ActualEXE = ???;

        // ... do the magic on the PI class ...

        instance.Dispose();
    }

Wenn ich die Instanzinformationen erfassen, kann ich die Befehlszeile, aber die Argumente „-f -i10“ ... Es gibt keinen EXE-Namen auf der Kommandozeile. Gibt es eine andere Methode / Eigenschaft ich suchen soll den EXE-Namen der 16-Bit-Anwendung, um zu bestimmen, die tatsächlich ausgeführt wird?

UPDATE: Lassen Sie mich die Frage verfeinern: Wenn ich den NTVDM-Prozess finden kann, wie kann ich - programmatisch - den tatsächlichen Pfad zur EXE kennen, die unter ausgeführt wird

Danke.

War es hilfreich?

Lösung

Der Trick zu verwenden, ist nicht VDMEnumProcessWOW (die die VDMs gibt), aber VDMEnumTasksWOW . Die enumerator Funktion, die Sie an diese Funktion übergeben wird für jede 16-Bit-Aufgabe in der angegebenen VDM aufgerufen werden.

Ich habe es selbst nicht geprüft, sondern nach der Dokumentation, das Process Master , kommt es mit volle Quelle. Ich schlage vor, Sie laufen, um herauszufinden, ob sie die Informationen, die Sie brauchen, und wenn ja, können Sie diese Methode, um Ihre eigene Anwendung anwenden (es ist nicht auf Windows Vista läuft oder 7, verwendet er alte VB5-Code, es ist offenbar nicht kompatibel. Es sollte auf XP laufen).

Wenn die Dinge mit diesen Funktionen gehen nicht wie geplant, können Vista sein kann und den Hotfix in diesem Frage Stackoverflow , die ein Hotfix herunterzuladen, die wiederum hier beschrieben:

  

"Eine Anwendung, die verwendet die   VDMEnumProcessWOW Funktion   aufzuzählen virtuelle DOS-Maschinen zurückkehren   keine Ausgabe oder fehlerhafte Ausgabe auf einem   Computer, auf dem eine 32-Bit   Version von Windows Vista "

Update: , während dies scheint vielversprechend, ich den Patch angewendet, lief mehrere Versionen des Codes, einschließlich Microsoft, und während sie alle arbeiten auf XP, sie nicht still (kein Fehler oder falscher Rückgabewert) auf Vista.


Der "irgendwie" Arbeits Code

Update: Ich experimentierte mit (unter anderem) mit dem folgenden Code, der in C # fein kompiliert (und kann einfacher geschrieben werden, aber ich wollte nicht führt ein Marschall-Fehler-Risiko). Wenn Sie diese Funktionen hinzufügen, können Sie rufen Enum16BitProcesses, welche die Dateinamen der EXE-Dateien der 16-Bit-Prozesse auf die Konsole schreiben.

Ich kann es nicht ausführen auf Vista 32 Bit. Aber vielleicht können andere versuchen, und kompilieren Sie es, oder den Fehler finden im Code. Es wäre schön zu wissen, ob es auf anderen Systemen funktioniert:

public class YourEnumerateClass
{
    public static void Enum16BitProcesses()
    {
        // create a delegate for the callback function
        ProcessTasksExDelegate procTasksDlgt = 
             new ProcessTasksExDelegate(YourEnumerateClass.ProcessTasksEx);

        // this part is the easy way of getting NTVDM procs
        foreach (var ntvdm in Process.GetProcessesByName("ntvdm"))
        {
            Console.WriteLine("ntvdm id = {0}", ntvdm.Id);
            int apiRet = VDMEnumTaskWOWEx(ntvdm.Id, procTasksDlgt, IntPtr.Zero);
            Console.WriteLine("EnumTaskWOW returns {0}", apiRet);
        }

    }

    // declaration of API function callback
    public delegate bool ProcessTasksExDelegate(
        int ThreadId,
        IntPtr hMod16,
        IntPtr hTask16,
        IntPtr ptrModName,
        IntPtr ptrFileName,
        IntPtr UserDefined
        );

    // the actual function that fails on Vista so far
    [DllImport("VdmDbg.dll", SetLastError = false, CharSet = CharSet.Auto)]
    public static extern int VDMEnumTaskWOWEx(
        int processId, 
        ProcessTasksExDelegate TaskEnumProc, 
        IntPtr lparam);

    // the actual callback function, on Vista never gets called
    public static bool ProcessTasksEx(
        int ThreadId,
        IntPtr hMod16,
        IntPtr hTask16,
        IntPtr ptrModName,
        IntPtr ptrFileName,
        IntPtr UserDefined
        )
    {
        // using PtrToStringAnsi, based on Matt's comment, if it fails, try PtrToStringAuto
        string filename = Marshal.PtrToStringAnsi(ptrFileName);
        Console.WriteLine("Filename of WOW16 process: {0}", filename);
        return false;       // false continues enumeration
    }

}

Update: Intriguing lesen durch den Ruhm Matt Pietrek. Mind the Satz, irgendwo in der Nähe des Ende:

  

"Für den Anfang MS-DOS-Programme   scheinen immer in separaten NTVDM laufen   Sitzungen. Ich war nie in der Lage ein bekommen   MS-DOS-Programm in der laufen   derselben Sitzung als 16-Bit-Windows-basierten   Programm. Ebenso wenig konnte ich zwei bekommen   unabhängig started-MS-DOS-basierte   Programme in der gleichen NTVDM laufen   Session. In der Tat, NTVDM Sitzungen   MS-DOS-Programme nicht zeigen, bis   in VDMEnumProcessWOW Aufzählungen. "

Es scheint, dass, um herauszufinden, welche Prozesse geladen werden, benötigen Sie einen Haken in NTVDM zu schreiben oder einen Zuhörer schreiben, den Zugriff auf die Datei überwacht. Wenn die Anwendung, die eine bestimmte DOS-Datei zu lesen versucht NTVDM.exe ist, dann ist es Bingo. Möglicherweise möchten Sie eine DLL schreiben, die sich nur auf NTVDM.exe angebracht ist, aber jetzt sind wir ein bisschen vor uns bekommen. Lange Rede kurzer Sinn: diese kleine Fahrt in NTVDM hatgezeigt „Möglichkeiten“, die real Hoaxes am Ende erschien.

Es gibt einen anderen Weg, aber die Zeit ist zu kurz, um ein Beispiel zu erstellen. Sie können in den DOS-Speichersegmente herumzustochern und die EXE in der Regel auf dem gleichen Segment geladen wird. Aber ich bin nicht sicher, ob das schließlich zu dem gleichen Ergebnis führen wird und ob es sich lohnt die Mühe.

Andere Tipps

Dies funktioniert für mich:

  • Folgen Sie den Anweisungen unter Beschreibung der Richtlinien für Softwareeinschränkung in Windows XP öffnen Sie die lokale oder Domänenrichtlinien-Editor.

  • Unter Richtlinien für Softwareeinschränkung. -> Zusätzliche Regeln mit der rechten Maustaste und New Hashregel wählen

  • Wechseln Sie zu (zum Beispiel) edit.com. Stellen Sie sicher, Sicherheitsstufe wird auf Unzulässig. Klicken Sie auf OK.

  

C:\>edit
  The system cannot execute the specified program.

(I erhalten die gleichen Ergebnisse aus command.com und cmd.exe - unter Win XP)

Link zu VDMDBG Funktionen , können Sie in der Lage sein zu P / Invoke „VDMEnumProcessWOW ()“, dann aufzuzählen Module innerhalb des Prozesses unter Verwendung PSAPI .

  

Hinweis in Bezug auf 16-Bit-DOS-Anwendungen:

     

Keine der VDMDBG Funktionen arbeiten mit   16-Bit-DOS-Anwendungen. aufzuzählen   DOS VDMs, müssen Sie eine andere verwenden,   Methode. Erstens könnten Sie   VDMEnumProcessWOW (), um eine Liste der   alle Win16 VDMs, und dann alle aufzählen   Instanzen von NTVDM.exe einige mit   anderes Schema (wie PSAPI). Irgendein   NTVDM.exe aus der vollständigen Aufzählung   das war nicht in der Win16-Liste a   DOS VDM. Sie können erstellen und beenden   16-Bit-DOS-Anwendungen mit   Createprocess () und   TerminateProcess ().

Ich hoffe, das hilft ...

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top