首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何通过DbgHelp获取局部变量的值

如何通过DbgHelp获取局部变量的值
EN

Stack Overflow用户
提问于 2014-11-18 23:52:19
回答 1查看 431关注 0票数 1

如何通过DbgHelp获取局部变量的值?我尝试使用以下代码

代码语言:javascript
复制
#include <boost/scope_exit.hpp>

#include <Windows.h>
#include <Dbghelp.h>

#include <iostream>
#include <map>
#include <string>

#pragma comment(lib, "Dbghelp.lib")

BOOL CALLBACK enum_symbols_callback(PSYMBOL_INFO pSymInfo, ULONG SymbolSize, PVOID UserContext)
{
  if (SymbolSize == 0)
  {
    return TRUE;
  }

  auto* local_variables_info = reinterpret_cast<std::map<std::string, std::string>*>(UserContext);

  std::unique_ptr<unsigned char[]> bytes_read(new unsigned char[SymbolSize]);
  HANDLE cur_process_handle = GetCurrentProcess();
  SIZE_T number_of_bytes_actually_read;
  if (ReadProcessMemory(
    cur_process_handle
    , reinterpret_cast<void*>(pSymInfo->Address)
    , bytes_read.get()
    , SymbolSize
    , &number_of_bytes_actually_read) != 0)
  {
    unsigned char* bytes = bytes_read.get();
    local_variables_info->operator[](pSymInfo->Name) = std::to_string(pSymInfo->Value);
  }

  return TRUE; // Continue enumeration
}

std::map<std::string, std::string> get_local_variables_info()
{
  std::map<std::string, std::string> local_variables_info;

  HANDLE cur_process_handle = GetCurrentProcess();
  if (SymInitialize(cur_process_handle, NULL, TRUE) == FALSE)
  {
    return local_variables_info;
  }
  BOOST_SCOPE_EXIT_ALL(cur_process_handle)
  {
    SymCleanup(cur_process_handle);
  };

  const ULONG frames_to_skip = 0;
  const ULONG frames_to_capture = 1;
  void* stack[frames_to_capture];

  const USHORT frames = CaptureStackBackTrace(
    frames_to_skip
    , frames_to_capture
    , stack
    , NULL
  );
  if (frames != 1)
  {
    return local_variables_info;
  }

  IMAGEHLP_STACK_FRAME sf;
  sf.InstructionOffset = reinterpret_cast<DWORD_PTR>(stack[0]);
  if (SymSetContext(
    cur_process_handle,
    &sf,                  // The context 
    0                     // Not used 
  ) == FALSE)
  {
    return local_variables_info;
  }

  if (SymEnumSymbols(
    cur_process_handle,
    0,                      // 0 -> SymEnumSymbols will use the context set with SymSetContext
    0,                      // Mask must also be 0 to use the context
    enum_symbols_callback,
    &local_variables_info   // User-defined context
  ) == FALSE)
  {
    return local_variables_info;
  }

  return local_variables_info;
}

int main()
{
  int foo = 0;
  const auto& local_variables_info = get_local_variables_info();
  for (const std::pair<std::string, std::string> e : local_variables_info)
  {
    std::cout << e.first << ' ' << e.second << '\n';
  }
}

但是,像FFFFFFD4一样,reinterpret_cast<void*>(pSymInfo->Address)总是返回地址。

为什么?我做错了什么?我怎么才能修复它?

提前谢谢。

EN

回答 1

Stack Overflow用户

发布于 2014-12-03 17:31:57

您要查找的变量值的地址位于函数的起始地址(可从执行上下文的EBP寄存器访问),从堆栈中此变量位置的偏移量开始应用。在本例中(函数的局部变量),pSymInfo->Address成员存储变量相对于堆栈帧的偏移量。

(这里有一个解释:http://eli.thegreenplace.net/2011/02/04/where-the-top-of-the-stack-is-on-x86/)

因此,您要查找的地址是(EBP + pSymInfo-> address )

要获得函数的开始,您可以使用:

EBP register

  • StackWalk64() ->
  1. CONTEXT -> EBP -> enables to walk register
  2. StackWalk64()

to get context->to get context

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/26998377

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档