欢迎来到 嗅灵易学

零基础也能上手的脚本技术课,一对一答疑带你入门

放一段可以随处打印函数调用栈的代码

放一段可以随处打印函数调用栈的代码

原理不多说了,我们知道,GetThreadContext只能取得被挂起线程的上下文,所以我这里使用内嵌汇编得到当前地址eip和当前函数栈指针ebp
由于没有使用Debug Help API,当然也不想自己分析pdb文件,打印信息可以和map文件和cond文件对照使用,还是比较方便的
其实可以从teb中得到堆栈位置信息来确定最外层调用栈,这里偷懒了,但是不影响这段代码的实用性,呵呵。
使用这段代码跟踪的程序,最好将编译选项中的优化去掉,原因大家都知道的
void PrintStackTrace()
{
  DWORD dwAddr   = 0;
  DWORD dwChildEbp = 0;
  _asm call $+5;
  _asm pop eax;
  _asm mov dwAddr,eax;
  _asm mov dwChildEbp,ebp;
  DWORD dwRetAddr = *(DWORD*)(dwChildEbp+4);
  CString strMsg =  "Addr\t\tChildEbp\t\tRetAddr\r\n"
            "===============================\r\n";
  try
  {
    while (TRUE)//dwRetAddr != 0)
    {
      dwAddr = dwRetAddr;
      dwChildEbp = *(DWORD*)dwChildEbp;
      dwRetAddr = *(DWORD*)(dwChildEbp+4);
      CString strTemp;
      strTemp.Format("0x%08X\t0x%08X\t0x%08X\r\n",dwAddr,dwChildEbp,dwRetAddr);
      strMsg += strTemp;
    }
  }
  catch (...)
  {
    
    printf("%s",(LPCTSTR)strMsg);
  }
}

注意:上传附件及图片大小不得大于30M。

⚠️ 版权声明:
本博客所有内容(含教程、源码、工具)仅供个人技术学习与研究交流使用,严禁商用、倒卖、二次分发及非法用途。
未经作者书面授权,任何组织或个人不得转载、复制或用于其他平台,违者将追究相关责任。

0 0 0 举报
复制成功