gpt4 book ai didi

c# - 在 NTVDM 下运行的 16 位应用程序

转载 作者:太空狗 更新时间:2023-10-29 20:15:23 25 4
gpt4 key购买 nike

我正在执行一些我们的内部人员不应再使用的旧 16 位应用程序。它们是 1985 年的 DOS 应用程序,因此很容易捕获它们……捕获在 NTVDM.exe 下启动的任何进程

现在,问题是找出 NTVDM 实际运行的是哪个程序。显然有几个 1985 程序应该被允许运行,所以我需要查看隐藏在 NTVDM 下的实际 EXE 名称。



 WqlEventQuery 查询 =
新的 WqlEventQuery("__InstanceCreationEvent",
新的时间跨度(0、0、1),
"TargetInstance isa\"Win32_Process\"");

ManagementEventWatcher 观察者 = new ManagementEventWatcher(query);

watcher.EventArrived += new EventArrivedEventHandler(watcher_EventArrived);

观察者.Start();


...


static void watcher_EventArrived(对象发送者,EventArrivedEventArgs e)
{
ManagementBaseObject 实例 = (ManagementBaseObject)e.NewEvent["TargetInstance"];

ProcessInfo PI = new ProcessInfo();
PI.ProcessID = int.Parse(实例["ProcessID"].ToString());
PI.ProcessName = instance["名称"].ToString();
PI.ProcessPath = instance["ExecutablePath"].ToString();

//这是我需要的部分...
PI.ActualEXE = ???;

//... 在 PI 类上施展魔法 ...

instance.Dispose();
}

当我捕获实例信息时,我可以得到命令行,但是参数是“-f -i10”......命令行上没有EXE名称。我是否应该查看任何其他方法/属性来确定实际运行的 16 位应用程序的 EXE 名称?

更新:让我细化一下问题:如果我能找到 NTVDM 进程,我如何以编程方式知道在其下执行的 EXE 的实际路径?

谢谢。

最佳答案

诀窍是不要使用 VDMEnumProcessWOW (它给出了 VDM),但要使用 VDMEnumTasksWOW .您传递给此函数的枚举器函数将为指定 VDM 中的每个 16 位任务调用。

我自己没有查过,但是根据文档,这个library of CodeProject如果您传入 PROC16 枚举值,则可以做到这一点。它是 C++,如果您需要帮助编译该代码并从 C# 调用它,请告诉我,我会给您举个例子。

使用此技术的程序是 Process Master ,它带有完整的源代码。我建议你运行它看看它是否提供了你需要的信息,如果是的话,你可以将此方法应用于你自己的应用程序(它不能在 Windows Vista 或 7 上运行,它使用旧的 VB5 代码,显然它不是兼容。它应该在 XP 上运行)。

如果这些功能没有按计划进行,您可能使用的是 Vista 并且可能需要此 StackOverflow question 中描述的修补程序, 指向 downloading a hotfix ,这又是described here :

"An application that uses theVDMEnumProcessWOW function toenumerate virtual DOS machines returnsno output or incorrect output on acomputer that is running a 32-bitversion of Windows Vista"

更新:虽然这看起来很有希望,但我应用了补丁,运行了多个版本的代码,包括 Microsoft 的,虽然它们都可以在 XP 上运行,但它们无声地失败了(没有错误,或错误的返回值)在 Vista 上。


“有点”工作代码

更新: 我尝试了(除其他外)以下代码,它在 C# 中编译良好(并且可以编写得更简单,但我不想冒编码(marshal)错误的风险)。当你添加这些函数时,你可以调用Enum16BitProcesses,它会将16位进程的EXE文件的文件名写入控制台。

我无法在 Vista 32 位上运行它。但也许其他人可以尝试编译它,或者找到代码中的错误。很高兴知道它是否适用于其他系统:

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
}

}

更新: Intriguing read由著名的 Matt Pietrek 创作。注意接近尾声的句子:

"For starters, MS-DOS-based programsseem to always run in separate NTVDMsessions. I was never able to get anMS-DOS-based program to run in thesame session as a 16-bit Windows-basedprogram. Nor was I able to get twoindependently started MS-DOS-basedprograms to run in the same NTVDMsession. In fact, NTVDM sessionsrunning MS-DOS programs don't show upin VDMEnumProcessWOW enumerations."

看来,要找出加载了哪些进程,您需要在 NTVDM 中编写一个 Hook 或编写一个监听器来监视对文件的访问。当试图读取某个 DOS 文件的应用程序是 NTVDM.exe 时,它​​就成功了。您可能想要编写仅附加到 NTVDM.exe 的 DLL,但现在我们有点超前了。长话短说:这次进入 NTVDM 的小旅程显示了最终出现真正恶作剧的“可能性”。

还有另一种方法,但是时间太短无法创建示例。您可以在 DOS 内存段中查找,EXE 通常加载在同一段中。但我不确定这最终是否会导致相同的结果以及是否值得付出努力。

关于c# - 在 NTVDM 下运行的 16 位应用程序,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1649827/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com