Domanda

Sto eseguendo il trapping per l'esecuzione di alcune vecchie applicazioni a 16 bit che la nostra gente interna non dovrebbe più utilizzare. Sono app DOS del 1985, quindi il trapping per loro è stato facile ... catturare qualsiasi processo avviato da NTVDM.exe

Ora, il problema è scoprire quale programma NTVDM è effettivamente in esecuzione sotto il cofano. Apparentemente ci sono un paio di programmi del 1985 che DOVREBBERO essere autorizzati a eseguire, quindi ho bisogno di vedere il vero nome EXE che si nasconde sotto 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();
    }

Quando acquisisco le informazioni sull'istanza, posso ottenere la riga di comando, ma gli argomenti sono " -f -i10 " ... Non esiste un nome EXE nella riga di comando. Esiste un altro metodo / proprietà che dovrei cercare per determinare il nome EXE dell'applicazione a 16 bit attualmente in esecuzione?

AGGIORNAMENTO: Consentitemi di affinare la domanda: se riesco a trovare il processo NTVDM, come posso - a livello di programmazione - conoscere il percorso effettivo del file EXE che viene eseguito sotto?

Grazie.

È stato utile?

Soluzione

Il trucco non è usare VDMEnumProcessWOW (che fornisce i VDM), ma per utilizzare VDMEnumTasksWOW . La funzione di enumerazione che passi a questa funzione verrà chiamata per ogni attività a 16 bit nel VDM specificato.

Non l'ho verificato da solo, ma secondo la documentazione, questo la libreria di CodeProject fa esattamente questo, se passi il valore enum PROC16. È C ++, se hai bisogno di aiuto per compilare quel codice e chiamarlo da C #, fammelo sapere e ti faccio un esempio.

Un programma che utilizza questa tecnica è Process Master , viene fornito con fonte completa. Ti suggerisco di eseguirlo per scoprire se fornisce le informazioni necessarie e, in tal caso, puoi applicare questo metodo alla tua applicazione (non funziona su Windows Vista o 7, utilizza il vecchio codice VB5, a quanto pare non lo è compatibile. Dovrebbe funzionare su XP).

Se le cose con queste funzioni non vanno come previsto, potrebbe essere su Vista e potrebbe essere necessario l'aggiornamento rapido descritto in questo Domanda StackOverflow , che punta a download di un aggiornamento rapido , che a sua volta è descritto qui :

  

" Un'applicazione che utilizza il   VDMEnumProcessWOW su   enumera i ritorni di macchine virtuali virtuali   nessun output o output errato su a   computer che esegue un 32 bit   versione di Windows Vista "

Update: mentre questo sembra promettente, ho applicato la patch, ho eseguito diverse versioni del codice, incluso quello di Microsoft, e mentre funzionano tutti su XP, falliscono silenziosamente (nessun errore o valore di ritorno errato) su Vista.


La "quota" " codice di lavoro

Update: Ho sperimentato (tra gli altri) il seguente codice, che si compila bene in C # (e può essere scritto più semplice, ma non volevo correre un rischio di errore commissario). Quando aggiungi queste funzioni, puoi chiamare Enum16BitProcesses , che scriverà i nomi dei file dei file EXE dei processi a 16 bit sulla Console.

Non riesco a eseguirlo su Vista a 32 bit. Ma forse altri possono provare a compilarlo o trovare l'errore nel codice. Sarebbe bello sapere se funziona su altri sistemi:

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: Intrigante letto dalla nota Matt Pietrek. Attenzione alla frase, da qualche parte vicino alla fine:

  

" Per cominciare, programmi basati su MS-DOS   sembra funzionare sempre in NTVDM separato   sessioni. Non sono mai stato in grado di ottenere un   Programma basato su MS-DOS da eseguire in   stessa sessione di un Windows a 16 bit   programma. Né sono riuscito a ottenerne due   avviato in modo indipendente basato su MS-DOS   programmi da eseguire nello stesso NTVDM   sessione. In effetti, sessioni NTVDM   i programmi MS-DOS in esecuzione non vengono visualizzati   nelle enumerazioni VDMEnumProcessWOW. "

Sembra che, per scoprire quali processi vengono caricati, dovrai scrivere un hook in NTVDM o scrivere un listener che controlli l'accesso al file. Quando l'applicazione che tenta di leggere un determinato file DOS è NTVDM.exe, è bingo. Potresti voler scrivere una DLL collegata solo a NTVDM.exe, ma ora stiamo andando un po 'più avanti di noi stessi. Per farla breve: questo

Altri suggerimenti

Questo funziona per me:

  • Seguire le istruzioni in Descrizione dei criteri di restrizione software in Windows XP a aprire l'editor delle politiche locali o di dominio.

  • Sotto Politiche di restrizione software - > Regole aggiuntive, fai clic con il pulsante destro del mouse e seleziona Nuova regola hash.

  • Cerca (ad esempio) edit.com . Assicurarsi che il Livello di sicurezza sia impostato su Non consentito. Fai clic su OK.

Ora,

  

C: \ > modifica
   Il sistema non può eseguire il programma specificato.

(Ottengo gli stessi risultati da command.com e cmd.exe - sotto Win XP)

Da questo link sulle funzioni VDMDBG , potresti essere in grado di P / Invocare " VDMEnumProcessWOW () " ;, quindi enumera i moduli all'interno del processo usando PSAPI .

  

Nota relativa alle applicazioni DOS a 16 bit:

     

Nessuna delle funzioni VDMDBG funziona con   Applicazioni DOS a 16 bit. Enumerare   DOS VDM, devi usarne un altro   metodo. Innanzitutto, potresti usare   VDMEnumProcessWOW () per creare un elenco di   tutti i VDM Win16 e quindi enumerare tutti   istanze di NTVDM.exe che ne utilizzano alcune   altro schema (come PSAPI). Qualunque   NTVDM.exe dall'enumerazione completa   che non era nell'elenco Win16 è un   DOS VDM. È possibile creare e terminare   Applicazioni DOS a 16 bit con   CreateProcess () e   TerminateProcess ().

Spero che aiuti ...

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top