Как просмотреть содержимое переменной типа LPVOID

#c #visual-c #windbg

#c #visual-c #windbg

Вопрос:

У меня есть функция C, которая принимает параметр типа LPVOID. Передаваемые значения представляют собой отдельный массив символов . Как я могу привести параметр, чтобы увидеть входящее значение в Visual studio / windbg?

Комментарии:

1. Прямое приведение к char* не работает?

2. Ну, да. Поскольку у вас есть нули, разделяющие их. Вам придется перебирать их вручную.

Ответ №1:

Вы можете сделать это в скрипте. Будет работать что-то вроде следующего, что предполагает строки char * и что список заканчивается двойными нулями (например, MULTI_SZ):

 $$ Print a MULTI_SZ value in the debugger. Note that 
$$ this script assume a char* string

$$ Grab the argument to the script
r @$t0 = ${$arg1}

$$ while *str != NULL
.while (by(@$t0) != 0) 
{

    $$ Print the string
    da @$t0

    $$ There's no strlen in this language, so find the NULL
    .while (by(@$t0) != 0) 
    {
        r @$t0 = @$t0   1
    }

    $$ String points to the NULL. Add one.
    r @$t0 = @$t0   1
}
  

Сохраните в текстовый файл, а затем запустите следующее в WinDbg:

 0:000> $$>a<c:dumpsmultisz.txt 0x012210ec
012210ec  "Foo"
012210f0  "Bar"
012210f4  "FooBar"
  

Ответ №2:

Нет приведения, которое позволило бы вам наблюдать это в окнах просмотра. Для VS вам нужно будет открыть окно памяти по адресу в начале блока, разделенного нулем.

В WinDbg команда db <my_address> сбрасывает необработанную память вместе с преобразованием ASCII. Если размер блока превышает 128 байт, добавьте опцию l в команду. Например, это выведет первые 0x200 байт для локальной переменной pVoid:
db poi pVoid l200

Ответ №3:

Простое приведение к char* должно работать.

   void f(LPVOID s)
  {
      char* ss = (char*) s; // put breakpoint here or watch the variable
      for(char* r = ss; *r != ''; r  = (strlen(r) 1)) { // iterate the string
          printf("%s n", r);
       }   
  }
  

Ответ №4:

опять очень поздний ответ, но dpa в windbg можно использовать для печати списка

 lpvoid:>dir /b
lpvoid.cpp

lpvoid:>type lpvoid.cpp
#include <stdio.h>
#include <windows.h>

    int somefunc(LPVOID blah)
    {
        printf("%sn",*(PCHAR *)blah);
        return 0;
    }
    int main (void)
    {
        PCHAR foo[] = { "yay" , "boy" , "dog" , "cat" , "monkey" , "weedinducedweird
    o" };
        somefunc( foo);
        return 0;
    }

    lpvoid:>cl /Zi /nologo lpvoid.cpp
    lpvoid.cpp

    lpvoid:>dir /b *.exe
    lpvoid.exe

    lpvoid:>lpvoid.exe
    yay
  

установите bp на somefunc или, если у вас нет символов на адресе, например, bp 401020,
используйте dpa для аргумента (бла-бла-бла) или используйте dpa @esp 8

     lpvoid:>cdb -c "bp somefunc "dpa poi(blah) l?6;q";g;q" lpvoid.exe | grep -A 6
     yay
    0013ff60  00417c60 "yay"
    0013ff64  00417c64 "boy"
    0013ff68  00417c68 "dog"
    0013ff6c  00417c6c "cat"
    0013ff70  00417c70 "monkey"
    0013ff74  00417c78 "weedinducedweirdo"
    quit:
  

предполагая, что здесь нет символов

 lpvoid:>cdb -c "bp 401020 "dpa (@esp 8) l?6;q";g;q" lpvoid.exe | grep -A 6 ya
y
0013ff60  00417c60 "yay"
0013ff64  00417c64 "boy"
0013ff68  00417c68 "dog"
0013ff6c  00417c6c "cat"
0013ff70  00417c70 "monkey"
0013ff74  00417c78 "weedinducedweirdo"
quit: