如何连接到 VMware 的管道并从正在运行的操作系统接收调试信息?

发布于 2024-11-16 23:35:30 字数 4440 浏览 2 评论 0原文

我正在尝试从 VMware 捕获调试信息。这可能是一项简单的任务,因为您可以将所有调试信息从 VMware 操作系统重定向到命名管道,就像很好的 此处描述。它与 WinDbg 一起工作得很好,但我想创建我自己的应用程序,它的功能完全相同。因此,我决定连接到 VMware 提供的命名管道并从中读取数据。

我能够连接到该命名管道,但从管道读取数据时却得到毫无意义的结果。我已将实际代码简化为不安全的无限循环。在表单上有一个备忘录和按钮并使用以下示例代码就足够了。

我想我对代码的 ReadFile 部分是错误的,因为我什至得到了毫无意义的字符串结果如果我已经阅读了可能合适的 BytesRead 计数。另一个奇怪的事情是,在 VMware 的操作系统启动后,即使大多数调试信息应该在此时出现,我也无法从管道中读取任何其他内容。

我混合了这篇文章中的代码<一href="https://stackoverflow.com/questions/4893062/some-source-that-implements-named-pipes-communication-btw-service-applications-or/4906188#4906188">这个答案。

procedure TForm1.Button1Click(Sender: TObject);
const
  BufferSize = 1024;

var
  Buffer: PChar;
  BytesRead: DWORD;
  BytesInPipe: DWORD;
  BytesToRead: DWORD;
  PipeName: String;
  PipeHandle: THandle;
  SecAttrs: SECURITY_ATTRIBUTES;
  SecDescr: SECURITY_DESCRIPTOR;

begin
  InitializeSecurityDescriptor(@SecDescr, SECURITY_DESCRIPTOR_REVISION);
  SetSecurityDescriptorDacl(@SecDescr, True, nil, False);
  SecAttrs.lpSecurityDescriptor := @SecDescr;
  SecAttrs.nLength := SizeOf(SECURITY_ATTRIBUTES);
  SecAttrs.bInheritHandle := True;

  PipeName := '\\.\pipe\com_1';

  PipeHandle := CreateFile(PChar(PipeName), GENERIC_READ or GENERIC_WRITE, 0, @SecAttrs, OPEN_EXISTING, 0, 0);
  Memo1.Lines.Add('CreateFile; PipeHandle = '+IntToStr(PipeHandle));

  Buffer := AllocMem(BufferSize + 1);

  repeat
    repeat
      PeekNamedPipe(PipeHandle, nil, 0, nil, @BytesInPipe, nil);
      BytesToRead := Min(BufferSize, BytesInPipe);

      if BytesToRead > 0 then
        begin
          BytesRead := 0;
          Memo1.Lines.Add('PeekNamedPipe; BytesInPipe = '+IntToStr(BytesInPipe)+'; BytesToRead = '+IntToStr(BytesToRead));

          if ReadFile(PipeHandle, Buffer[0], BytesToRead, BytesRead, nil) then
            begin
              Buffer[BufferSize] := #0;
              // OemToAnsi(Buffer, Buffer); // without this line I'm getting the following log

              Memo1.Lines.Add('ReadFile; BytesToRead = '+IntToStr(BytesToRead)+'; BytesRead = '+IntToStr(BytesRead));
              Memo1.Lines.Add('ReadFile; Buffer = '+String(Buffer));
            end;
        end;
    until
      (BytesToRead = 0);

    Application.ProcessMessages;
  until
    (Tag = 1);
end;

这就是我所发现的;在这些行之后(在 WMware 操作系统启动时出现),没有其他内容通过管道。恐怕就是这样的协议。

CreateFile; PipeHandle = 240
PeekNamedPipe; BytesInPipe = 1; BytesToRead = 1
ReadFile; BytesToRead = 1; BytesRead = 1
ReadFile; Buffer = 0
PeekNamedPipe; BytesInPipe = 16; BytesToRead = 16
ReadFile; BytesToRead = 16; BytesRead = 16
ReadFile; Buffer = 000
PeekNamedPipe; BytesInPipe = 169; BytesToRead = 169
ReadFile; BytesToRead = 169; BytesRead = 169
ReadFile; Buffer = 0
PeekNamedPipe; BytesInPipe = 74; BytesToRead = 74
ReadFile; BytesToRead = 74; BytesRead = 74
ReadFile; Buffer = 
PeekNamedPipe; BytesInPipe = 28; BytesToRead = 28
ReadFile; BytesToRead = 28; BytesRead = 28
ReadFile; Buffer = DOWS\system32\ntkrnlpa.exe
PeekNamedPipe; BytesInPipe = 1; BytesToRead = 1
ReadFile; BytesToRead = 1; BytesRead = 1
ReadFile; Buffer = 0OWS\system32\ntkrnlpa.exe
PeekNamedPipe; BytesInPipe = 261; BytesToRead = 261
ReadFile; BytesToRead = 261; BytesRead = 261
ReadFile; Buffer = 000
PeekNamedPipe; BytesInPipe = 26; BytesToRead = 26
ReadFile; BytesToRead = 26; BytesRead = 26
ReadFile; Buffer = WS\system32\ntkrnlpa.exe
PeekNamedPipe; BytesInPipe = 288; BytesToRead = 288
ReadFile; BytesToRead = 288; BytesRead = 288
ReadFile; Buffer = 0000
PeekNamedPipe; BytesInPipe = 1; BytesToRead = 1
ReadFile; BytesToRead = 1; BytesRead = 1
ReadFile; Buffer = 0000
PeekNamedPipe; BytesInPipe = 218; BytesToRead = 218
ReadFile; BytesToRead = 218; BytesRead = 218
ReadFile; Buffer = 000
PeekNamedPipe; BytesInPipe = 69; BytesToRead = 69
ReadFile; BytesToRead = 69; BytesRead = 69
ReadFile; Buffer = 
PeekNamedPipe; BytesInPipe = 1; BytesToRead = 1
ReadFile; BytesToRead = 1; BytesRead = 1
ReadFile; Buffer = 0Ì]Â
PeekNamedPipe; BytesInPipe = 287; BytesToRead = 287
ReadFile; BytesToRead = 287; BytesRead = 287
ReadFile; Buffer = 000

我尝试在 Windows 7 上使用非 Unicode Delphi 2007 执行此操作,并关闭 UAC 并具有管理员权限。也许我完全错了;也许我需要与管道通信,而不仅仅是从中读取。谁能建议我我做错了什么?有人有这方面的经验吗?

非常感谢
问候

I'm trying to catch debug information from VMware. This might be an easy task because you can redirect all debug information from VMware's OS into the named pipe like is nicely described here. It works fine with WinDbg but I want to create my own application which will do exactly the same. So I've decided to connect to the named pipe provided by VMware and read from it.

I'm able to connect to that named pipe but I'm getting meaningless result when reading from the pipe. I've simplified the real code into the unsafe infinite loop. It's enough to have a memo and button on a form and use the following sample code.

I suppose I'm wrong with the ReadFile part of a code because I'm getting meaningless string results even if I have read maybe appropriate BytesRead count. Another strange thing is that after VMware's OS boots, nothing else I can read from the pipe even if the most of the debug info should come at that moment.

I've mixed this code from this article and this answer.

procedure TForm1.Button1Click(Sender: TObject);
const
  BufferSize = 1024;

var
  Buffer: PChar;
  BytesRead: DWORD;
  BytesInPipe: DWORD;
  BytesToRead: DWORD;
  PipeName: String;
  PipeHandle: THandle;
  SecAttrs: SECURITY_ATTRIBUTES;
  SecDescr: SECURITY_DESCRIPTOR;

begin
  InitializeSecurityDescriptor(@SecDescr, SECURITY_DESCRIPTOR_REVISION);
  SetSecurityDescriptorDacl(@SecDescr, True, nil, False);
  SecAttrs.lpSecurityDescriptor := @SecDescr;
  SecAttrs.nLength := SizeOf(SECURITY_ATTRIBUTES);
  SecAttrs.bInheritHandle := True;

  PipeName := '\\.\pipe\com_1';

  PipeHandle := CreateFile(PChar(PipeName), GENERIC_READ or GENERIC_WRITE, 0, @SecAttrs, OPEN_EXISTING, 0, 0);
  Memo1.Lines.Add('CreateFile; PipeHandle = '+IntToStr(PipeHandle));

  Buffer := AllocMem(BufferSize + 1);

  repeat
    repeat
      PeekNamedPipe(PipeHandle, nil, 0, nil, @BytesInPipe, nil);
      BytesToRead := Min(BufferSize, BytesInPipe);

      if BytesToRead > 0 then
        begin
          BytesRead := 0;
          Memo1.Lines.Add('PeekNamedPipe; BytesInPipe = '+IntToStr(BytesInPipe)+'; BytesToRead = '+IntToStr(BytesToRead));

          if ReadFile(PipeHandle, Buffer[0], BytesToRead, BytesRead, nil) then
            begin
              Buffer[BufferSize] := #0;
              // OemToAnsi(Buffer, Buffer); // without this line I'm getting the following log

              Memo1.Lines.Add('ReadFile; BytesToRead = '+IntToStr(BytesToRead)+'; BytesRead = '+IntToStr(BytesRead));
              Memo1.Lines.Add('ReadFile; Buffer = '+String(Buffer));
            end;
        end;
    until
      (BytesToRead = 0);

    Application.ProcessMessages;
  until
    (Tag = 1);
end;

Here's what I caugth; after those lines (which came at WMware's OS boot) nothing else comes through the pipe. I'm afraid it's such kind of a protocol.

CreateFile; PipeHandle = 240
PeekNamedPipe; BytesInPipe = 1; BytesToRead = 1
ReadFile; BytesToRead = 1; BytesRead = 1
ReadFile; Buffer = 0
PeekNamedPipe; BytesInPipe = 16; BytesToRead = 16
ReadFile; BytesToRead = 16; BytesRead = 16
ReadFile; Buffer = 000
PeekNamedPipe; BytesInPipe = 169; BytesToRead = 169
ReadFile; BytesToRead = 169; BytesRead = 169
ReadFile; Buffer = 0
PeekNamedPipe; BytesInPipe = 74; BytesToRead = 74
ReadFile; BytesToRead = 74; BytesRead = 74
ReadFile; Buffer = 
PeekNamedPipe; BytesInPipe = 28; BytesToRead = 28
ReadFile; BytesToRead = 28; BytesRead = 28
ReadFile; Buffer = DOWS\system32\ntkrnlpa.exe
PeekNamedPipe; BytesInPipe = 1; BytesToRead = 1
ReadFile; BytesToRead = 1; BytesRead = 1
ReadFile; Buffer = 0OWS\system32\ntkrnlpa.exe
PeekNamedPipe; BytesInPipe = 261; BytesToRead = 261
ReadFile; BytesToRead = 261; BytesRead = 261
ReadFile; Buffer = 000
PeekNamedPipe; BytesInPipe = 26; BytesToRead = 26
ReadFile; BytesToRead = 26; BytesRead = 26
ReadFile; Buffer = WS\system32\ntkrnlpa.exe
PeekNamedPipe; BytesInPipe = 288; BytesToRead = 288
ReadFile; BytesToRead = 288; BytesRead = 288
ReadFile; Buffer = 0000
PeekNamedPipe; BytesInPipe = 1; BytesToRead = 1
ReadFile; BytesToRead = 1; BytesRead = 1
ReadFile; Buffer = 0000
PeekNamedPipe; BytesInPipe = 218; BytesToRead = 218
ReadFile; BytesToRead = 218; BytesRead = 218
ReadFile; Buffer = 000
PeekNamedPipe; BytesInPipe = 69; BytesToRead = 69
ReadFile; BytesToRead = 69; BytesRead = 69
ReadFile; Buffer = 
PeekNamedPipe; BytesInPipe = 1; BytesToRead = 1
ReadFile; BytesToRead = 1; BytesRead = 1
ReadFile; Buffer = 0Ì]Â
PeekNamedPipe; BytesInPipe = 287; BytesToRead = 287
ReadFile; BytesToRead = 287; BytesRead = 287
ReadFile; Buffer = 000

I'm trying to do it with non Unicode Delphi 2007 on Windows 7 with Administrator rights with UAC turned off. Maybe I'm totally wrong; maybe I need to communicate with the pipe, not only read from it. Can anyone suggest me what I'm doing wrong ? Does anyone has an experience with it ?

Thanks a lot
Regards

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

随风而去 2024-11-23 23:35:30

这比我想象的要复杂得多。如果VMware仅将模拟串行端口连接到客户端管道(99.9%?),我很荣幸能够使用虚拟操作系统的内核调试器。实现以下来源中描述的协议意味着什么。感谢 这个答案 作为一个起点,我意识到我会让这些东西度过一个漫长的冬天。

编辑:
由于我只需要捕获虚拟机上的 OutputDebugString 消息并将它们发送到真实机器,因此我决定使用管道和到虚拟机的网络连接。

http://www.cnitblog.com/torch/articles/9429.html
http://www.qqread.com/soft-engineering/e300828.html
http://www.developerfusion.com/article/84367/kernel -and-remote-debuggers/

This is much more complex than I thought. In case that VMware only connects the simulated serial port to the client's pipe (99.9% ?) I have the honor to the kernel debugger of the virtual OS. What means to implement the protocol described in the following sources. Thanks to this answer as a starting point I realized I will let this stuff for a long winter times.

Edit:
Since I need only to catch OutputDebugString messages on the virtual machine and send them to the real machine I've decided to use pipes and the network connection to the virtual machine.

http://www.cnitblog.com/torch/articles/9429.html
http://www.qqread.com/soft-engineering/e300828.html
http://www.developerfusion.com/article/84367/kernel-and-remote-debuggers/

与风相奔跑 2024-11-23 23:35:30

由于Windows是一个Unicode系统,我猜你收到的字节是Unicode字符串。尝试将 Buffer 声明为 PWideChar 并看看会得到什么。或者切换到支持 Unicode 的 Delphi 版本。

As Windows is a Unicode system, I guess the bytes you receive are Unicode strings. Try to declare Buffer as PWideChar and see what you get. Alternatively switch to a Unicode capable Delphi version.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文