【问题标题】:How to view content of variable of type LPVOID如何查看 LPVOID 类型变量的内容
【发布时间】:2011-09-29 05:41:57
【问题描述】:

我有一个采用 LPVOID 类型参数的 C 函数。传入的值是 \0 分隔的字符数组。如何转换参数以查看 Visual Studio / Windbg 中的传入值?

【问题讨论】:

  • 直接转换为char* 不起作用?
  • 嗯,是的。因为你有 NULL 分隔它们。您必须手动遍历它们。

标签: c visual-c++ windbg


【解决方案1】:

您可以在脚本中执行此操作。像下面这样的东西会起作用,它假设 char * 字符串并且列表以双 NULL 结尾(如 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:\dumps\multisz.txt 0x012210ec
012210ec  "Foo"
012210f0  "Bar"
012210f4  "FooBar"

【讨论】:

    【解决方案2】:

    没有可以让您在观察窗口中观察到的演员表。对于 VS,您必须在空分隔块开头的地址上打开一个内存窗口。

    在 WinDbg 命令中db &lt;my_address&gt; 转储原始内存以及 ASCII 转换。如果块大于 128 字节,则将选项 l 添加到命令中。例如,这将打印出局部变量 pVoid 的前 0x200 个字节:
    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 != '\0'; r += (strlen(r)+1)) { // iterate the string
                printf("%s \n", r);
             }   
        }
      

      【讨论】:

        【解决方案4】:

        又是一个很晚的答案,但可以利用 windbg 中的dpa 打印列表

        lpvoid:\>dir /b
        lpvoid.cpp
        
        lpvoid:\>type lpvoid.cpp
        #include <stdio.h>
        #include <windows.h>
        
            int somefunc(LPVOID blah)
            {
                printf("%s\n",*(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
        

        在 somefunc 上设置一个 bp,或者如果你在地址上没有符号,比如 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:
        

        【讨论】:

          猜你喜欢
          • 2012-12-14
          • 2012-08-15
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2018-01-25
          • 2011-08-05
          • 1970-01-01
          • 2018-04-12
          相关资源
          最近更新 更多