Pergunta

Eu estou prendendo para a execução de algumas aplicações de 16 bits antigos que nossos pais internos não deve mais ser utilizado. Eles são 1985 aplicativos do DOS, assim prendendo para eles foi fácil ... captura de qualquer processo que lançamentos sob NTVDM.exe

Agora, o problema é descobrir qual o programa NTVDM realmente está sendo executado sob o capô. Aparentemente, há um coupleof os programas de 1985 que eles devem ser autorizados a correr, então eu preciso ver o nome EXE real que está escondido sob 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 eu capturar as informações de exemplo, posso obter a linha de comando, mas os argumentos são "-f -i10" ... Não há nome EXE na linha de comando. Existe algum outro método / propriedade que eu deveria estar olhando para determinar o nome EXE da aplicação de 16 bits que está realmente funcionando?

UPDATE: Deixe-me refinar a pergunta: Se eu posso encontrar o processo NTVDM, como pode I - programaticamente - sabe o caminho real para o EXE que está sendo executado sob

Graças.

Foi útil?

Solução

O truque não é para uso VDMEnumProcessWOW (que dá os VDMs), mas para usar VDMEnumTasksWOW . A função de recenseador que você passa para esta função será chamada para cada tarefa de 16 bits no VDM especificado.

Eu não tenho verificado isso sozinho, mas de acordo com a documentação, este biblioteca de CodeProject faz exatamente isso, se você passar o valor PROC16 enum. É de C ++, se precisar de ajuda compilar esse código e chamá-lo de C #, deixe-me saber e eu vou lhe dar um exemplo.

Um programa que usa esta técnica é Processo Mestre , ele vem com fonte completo. Eu sugiro que você executá-lo para saber se ele dá a informação que você precisa, e se assim for, você pode aplicar esse método para o seu próprio aplicativo (ele não é executado no Windows Vista ou 7, que utiliza código VB5 de idade, aparentemente não é compatível. Ele deve ser executado no XP).

Se as coisas com estas funções não saem como planejado, você pode estar no Vista e pode precisar a correcção descrita neste StackOverflow pergunta , que aponta para download de um hotfix , que é por sua vez descrito aqui :

"Um aplicativo que usa a função VDMEnumProcessWOW para enumerar Virtual DOS máquinas retornos nenhuma saída ou saída incorreta em um computador que está executando a 32-bit versão do Windows Vista "

Atualização: enquanto isso parece promissor, eu apliquei o patch, correu várias versões do código, incluindo os da Microsoft, e enquanto todos eles funcionam no XP, eles falham silenciosamente (nenhum erro ou valor de retorno errado) em Vista.


O código "meio" trabalhando

Atualização: Eu experimentei com (entre outros) com o seguinte código, que compila bem em C # (e pode ser escrita mais simples, mas eu não queria correm um risco marechal-erro). Ao adicionar estas funções, você pode chamar Enum16BitProcesses, que vai escrever os nomes de arquivo dos arquivos EXE dos 16 processos bit para o console.

Eu não pode executá-lo no Vista de 32 bits. Mas, talvez, outros podem tentar compilá-lo, ou encontrar o erro no código. Seria bom saber se ele funciona em outros sistemas:

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
    }

}

Atualização: Intrigante leia pela fama Matt Pietrek. Mente a frase, em algum lugar perto do fim:

"Para começar, programas baseados em MS-DOS parecem sempre correr em NTVDM separado sessões. Eu nunca fui capaz de obter uma programa para ser executado no MS-DOS-based mesma sessão como um baseado em Windows de 16 bits programa. Nem fui capaz de obter dois baseada em MS-DOS iniciados independentemente programas sejam executados no mesmo NTVDM sessão. Na verdade, sessões NTVDM executando programas MS-DOS não aparecem em enumerações VDMEnumProcessWOW. "

Parece que, para descobrir quais processos são carregados, você precisa escrever um gancho no NTVDM ou escrever um ouvinte que monitora o acesso ao arquivo. Quando o aplicativo que tenta ler um determinado arquivo DOS é NTVDM.exe, é bingo. Você pode querer escrever uma DLL que é somente ligado a NTVDM.exe, mas agora estamos recebendo uma frente de nós mesmos bit. Para encurtar a história: este pequeno passeio para NTVDM temmostrados "possibilidades" que apareceram hoaxes reais no final.

Há uma outra maneira, mas o tempo é curto demais para criar um exemplo. Você pode picar em torno dos segmentos de memória do DOS e do EXE normalmente é carregado ao mesmo segmento. Mas não estou certo se isso acabará por levar ao mesmo resultado e se vale a pena o esforço.

Outras dicas

Isso funciona para mim:

  • Siga as instruções em descrição das políticas de restrição de software no Windows XP para abrir o editor de política local ou de domínio.

  • Políticas de restrição em Software -.> Regras adicionais, clique direito e selecione Nova regra de hash

  • Procurar para (por exemplo) edit.com. Certifique-se de Nível de Segurança está definido como Não permitido. Clique em OK.

Agora,

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

(I obter os mesmos resultados de command.com e cmd.exe - sob Win XP)

A partir este link sobre as funções VDMDBG , você pode ser capaz de P / Invoke "VDMEnumProcessWOW ()", então enumerar os módulos dentro do processo usando PSAPI .

Nota sobre aplicações de 16 bits:

Nenhum dos VDMDBG funções de trabalho com aplicações de 16 bits. para enumerar DOS VDMs, você precisa usar outro método. Primeiro, você poderia usar VDMEnumProcessWOW () para fazer uma lista de todos Win16 VDMs, e, em seguida, enumerar todos ocorrências de NTVDM.exe usando alguns outro esquema (tais como PSAPI). Qualquer NTVDM.exe da enumeração completa que não estava na lista Win16 é um DOS VDM. Você pode criar e encerrar 16-bit aplicações DOS com CreateProcess () e TerminateProcess ().

Espero que ajude ...

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top