Как мне подключиться к каналу VMware и получить отладочную информацию от работающей ОС? - PullRequest
2 голосов
/ 23 июня 2011

Я пытаюсь поймать отладочную информацию из VMware. Это может быть простой задачей, потому что вы можете перенаправить всю отладочную информацию из ОС VMware в именованный канал, как хорошо описано здесь . Он прекрасно работает с WinDbg, но я хочу создать собственное приложение, которое будет делать то же самое. Поэтому я решил подключиться к именованному каналу, предоставленному VMware, и прочитать его.

Я могу подключиться к этому именованному каналу, но получаю бессмысленный результат при чтении из канала. Я упростил реальный код в небезопасный бесконечный цикл. Достаточно иметь в форме напоминание и кнопку и использовать следующий пример кода.

Полагаю, я ошибаюсь с частью кода ReadFile, потому что я получаю бессмысленные строковые результаты, даже если прочитал, может быть, соответствующий BytesRead счет. Другая странная вещь заключается в том, что после загрузки ОС VMware больше ничего я не могу прочитать из канала, даже если большая часть отладочной информации должна появиться в этот момент.

Я смешал этот код из этой статьи и этого ответа .

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

Я пытаюсь сделать это с не Unicode Delphi 2007 на Windows 7 с правами администратора с отключенным UAC. Может быть, я совершенно не прав; возможно мне нужно общаться с каналом, а не только читать с него. Может кто-нибудь подсказать, что я делаю не так? У кого-нибудь есть опыт с этим?

Большое спасибо
Привет

Ответы [ 2 ]

1 голос
/ 24 июня 2011

Это намного сложнее, чем я думал. В случае, если VMware только подключает моделируемый последовательный порт к каналу клиента (99,9%?), Я имею честь отладчика ядра виртуальной ОС. Что значит для реализации протокола описано в следующих источниках. Благодаря этому ответу в качестве отправной точки я понял, что позволю этому материалу долго зимовать.

Edit:
Поскольку мне нужно только перехватить сообщения 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/

0 голосов
/ 23 июня 2011

Поскольку Windows - это система Unicode, я думаю, что байты, которые вы получаете, являются строками Unicode.Попробуйте объявить Buffer как PWideChar и посмотрите, что вы получите.Или же переключитесь на версию Delphi с поддержкой Unicode.

...