如何连接到VMware的管道并从正在运行的操作系统接收调试信息? [英] How do I connect to the VMware's pipe and receive debug information from the running OS?

查看:1180
本文介绍了如何连接到VMware的管道并从正在运行的操作系统接收调试信息?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试从VMware捕获调试信息。这可能是一个容易的任务,因为您可以将所有调试信息从VMware的操作系统重定向到命名管道,如很好地这里描述。它可以正常使用WinDbg,但我想创建我自己的应用程序将完全一样。所以我决定连接到VMware提供的命名管道并从中读取。



我可以连接到这个命名管道,在从管道读取时,得到无意义的结果。我将真正的代码简化为不安全的无限循环。在表单上备份和按钮就足够了,并使用以下示例代码。



我想我错了 ReadFile 部分代码,因为即使我已经阅读了可能适当的 BytesRead count,因此我得到无意义的字符串结果。另一个奇怪的是,在VMware的操作系统启动之后,即使大部分的调试信息都应该在这个时刻,我也可以从管道读取任何东西。



这篇文章这个答案

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

var
缓冲区: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或GENERIC_WRITE,0,@SecAttrs,OPEN_EXISTING,0,0);
Memo1.Lines.Add('CreateFile; PipeHandle ='+ IntToStr(PipeHandle));

缓冲区:= AllocMem(BufferSize + 1);

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

如果BytesToRead> 0然后
begin
BytesRead:= 0;
Memo1.Lines.Add('PeekNamedPipe; BytesInPipe ='+ IntToStr(BytesInPipe)+'; BytesToRead ='+ IntToStr(BytesToRead));

如果ReadFile(PipeHandle,Buffer [0],BytesToRead,BytesRead,nil)然后
begin
缓冲区[BufferSize]:=#0;
// OemToAnsi(Buffer,Buffer); //没有这行我得到以下日志

Memo1.Lines.Add('ReadFile; BytesToRead ='+ IntToStr(BytesToRead)+'; BytesRead ='+ IntToStr(BytesRead));
Memo1.Lines.Add('ReadFile; Buffer ='+ String(Buffer));
结束
结束
直到
(BytesToRead = 0);

Application.ProcessMessages;
直到
(Tag = 1);
结束

这是我想要的东西;在这些行(在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\\\
tkrnlpa.exe
PeekNamedPipe; BytesInPipe = 1; BytesToRead = 1
ReadFile; BytesToRead = 1; BytesRead = 1
ReadFile; Buffer = 0OWS\system32\\\
tkrnlpa.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\\\
tkrnlpa.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;缓冲区= 000

我正在使用非Unicode Delphi 2007在Windows 7上使用管理员权限UAC关闭。也许我完全错了也许我需要与管道通信,不仅从它读取。任何人都可以建议我做错什么?有谁有经验吗?



非常感谢

感谢

解决方案

这个答案作为起点,我意识到我会让这个东西漫长的冬天。



编辑:

由于我只需要在虚拟机上捕获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 /


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

解决方案

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/

这篇关于如何连接到VMware的管道并从正在运行的操作系统接收调试信息?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆