Question

Je suis en train de piéger pour l'exécution de certaines anciennes applications 16 bits que nos employés internes ne devraient plus utiliser. Ce sont des applications DOS de 1985, il était donc facile de s'y retrouver. Capturez tous les processus lancés sous NTVDM.exe

Maintenant, le problème est de savoir quel programme NTVDM tourne réellement sous le capot. Apparemment, quelques-uns des programmes de 1985 qu'ils DEVRAIENT être autorisés à exécuter, je dois donc voir le nom du fichier EXE caché sous NTVDM.

        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();
    }

Lorsque je capture les informations sur l'instance, je peux obtenir la ligne de commande, mais les arguments sont "-f -i10". ... Il n'y a pas de nom EXE sur la ligne de commande. Existe-t-il une autre méthode / propriété que je devrais consulter pour déterminer le nom EXE de l'application 16 bits en cours d'exécution?

UPDATE: Laissez-moi préciser la question: si je parviens à trouver le processus NTVDM, comment puis-je, par programmation, connaître le chemin d'accès réel à l'EXE exécuté?

Merci.

Était-ce utile?

La solution

L'astuce consiste à ne pas utiliser VDMEnumProcessWOW (qui donne les VDM), mais il faut utiliser VDMEnumTasksWOW . L'énumérateur que vous transmettez à cette fonction sera appelé pour chaque tâche 16 bits du VDM spécifié.

Je ne l'ai pas vérifié moi-même, mais selon la documentation, cela bibliothèque de CodeProject fait exactement cela, si vous transmettez la valeur PROC16 enum. C'est C ++, si vous avez besoin d'aide pour compiler ce code et l'appeler à partir de C #, faites-le moi savoir et je vous donnerai un exemple.

Un programme utilisant cette technique est le Master 20, il est livré avec source complète. Je vous suggère de l'exécuter pour savoir s'il fournit les informations dont vous avez besoin, et si c'est le cas, vous pouvez appliquer cette méthode à votre propre application (elle ne fonctionne pas sous Windows Vista ou 7, elle utilise l'ancien code VB5, ce n'est apparemment pas le cas. compatible. Il devrait fonctionner sous XP).

Si ces fonctions ne fonctionnent pas comme prévu, vous êtes peut-être sur Vista et avez besoin du correctif décrit dans le présent document question StackOverflow , qui pointe vers téléchargement d'un correctif , qui est à son tour décrit ici :

  

"Une application qui utilise le   Fonction VDMEnumProcessWOW pour   énumérer les retours virtuels des machines DOS   pas de sortie ou sortie incorrecte sur un   ordinateur qui exécute un 32 bits   version de Windows Vista "

Mise à jour , bien que cela semble prometteur, j'ai appliqué le correctif, exécuté plusieurs versions du code, y compris celles de Microsoft. Bien qu'elles fonctionnent toutes sous XP, elles échouent en silence. (pas d'erreur ou valeur de retour incorrecte) sous Vista.

Le "un peu" code de travail

Mise à jour: J'ai expérimenté (entre autres) le code suivant, qui compile bien en C # (et peut être écrit plus simplement, mais je ne voulais pas courir un risque d'erreur de maréchal). Lorsque vous ajoutez ces fonctions, vous pouvez appeler Enum16BitProcesses , qui écrira les noms de fichiers des fichiers EXE des processus 16 bits sur la console.

Je ne peux pas l'exécuter sur Vista 32 bits. Mais peut-être que d'autres peuvent essayer de le compiler ou de trouver l'erreur dans le code. Il serait bon de savoir si cela fonctionne sur d'autres systèmes:

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
    }

}

Mise à jour: Intriguant lu par le célèbre Matt Pietrek. Attention à la phrase, quelque part vers la fin:

  

"Pour commencer, les programmes MS-DOS   semblent toujours fonctionner dans NTVDM séparé   sessions. Je n'ai jamais pu obtenir un   Programme MS-DOS à exécuter dans le   même session qu'un Windows 16 bits   programme. Je ne pouvais pas non plus en avoir deux   indépendamment démarré sous MS-DOS   programmes à exécuter dans le même NTVDM   session. En fait, les sessions NTVDM   l'exécution de programmes MS-DOS n'apparaît pas   dans les énumérations VDMEnumProcessWOW. "

Il semble que pour savoir quels processus sont chargés, vous devez écrire un hook dans NTVDM ou écrire un écouteur qui surveille l'accès au fichier. Lorsque l'application qui tente de lire un certain fichier DOS est NTVDM.exe, il s'agit d'un bingo. Vous voudrez peut-être écrire une DLL uniquement liée à NTVDM.exe, mais nous avons maintenant un peu d'avance sur nous-mêmes. Longue histoire courte: cette

Autres conseils

Cela fonctionne pour moi:

  • Suivez les instructions de la Description des stratégies de restriction logicielle de Windows XP pour ouvrez l’éditeur de règles local ou de domaine.

  • Sous Stratégies de restriction logicielle - > Règles supplémentaires, cliquez avec le bouton droit de la souris et sélectionnez Nouvelle règle de hachage.

  • Accédez à (par exemple) edit.com . Assurez-vous que le niveau de sécurité est défini sur Interdit. Cliquez sur OK.

Maintenant,

  

C: \ > edit
   Le système ne peut pas exécuter le programme spécifié.

(Les mêmes résultats sont obtenus avec command.com et cmd.exe - sous Windows XP)

À partir de ce lien sur les fonctions VDMDBG , vous pourrez peut-être utiliser la fonction P / Invoke " VDMEnumProcessWOW () " ;, puis énumérer des modules dans le processus utiliser PSAPI .

  

Remarque concernant les applications DOS 16 bits:

     

Aucune des fonctions VDMDBG ne fonctionne avec   Applications DOS 16 bits. Énumérer   VDM DOS, vous devez utiliser un autre   méthode. Tout d'abord, vous pouvez utiliser   VDMEnumProcessWOW () pour faire une liste de   tous les VDM Win16, puis énumérer tous les   instances de NTVDM.exe utilisant certains   autre système (tel que PSAPI). Tout   NTVDM.exe à partir de l'énumération complète   ce n'était pas dans la liste Win16 est un   DOS VDM. Vous pouvez créer et terminer   Applications DOS 16 bits avec   CreateProcess () et   TerminateProcess ().

J'espère que ça aide ...

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top