Windows逆向工程入门之堆栈回溯

打印 上一主题 下一主题

主题 966|帖子 966|积分 2898

马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。

您需要 登录 才可以下载或查看,没有账号?立即注册

x

  • 公开视频 -> 链接点击跳转公开课程
  • 博客首页 -> ​​​链接点击跳转博客主页
目录
堆栈回溯
效果
代码
符号解析
符号信息
示例代码
DBG
IDA


堆栈回溯

效果


代码

  1. #include <iostream>
  2. #include <iomanip>
  3. void PrintCallBack()
  4. {
  5.         // 栈帧结构
  6.         int StackFrameCount = 0;
  7.         // 栈帧获取
  8.         int* varEbp = 0;
  9.         __asm
  10.         {
  11.                 mov[varEbp], ebp
  12.         }
  13.         // 堆栈回溯
  14.         while (varEbp)
  15.         {
  16.                 /*
  17.                         PrintCallBack
  18.                                 [EBP + 0] -> FUN3.EBP
  19.                                 [EBP + 4] -> FUN3.RETADDR
  20.                         FUN3
  21.                                 [EBP + 0] -> FUN2.EBP
  22.                                 [EBP + 4] -> FUN2.RETADDR
  23.                 */
  24.                 // 返回地址
  25.                 int varRetAddr = varEbp[1];
  26.                 if (!varRetAddr) return;
  27.                 std::cout << "StackFrameCount -> " << std::setw(2) << std::setfill('0') << std::dec << StackFrameCount << "\t";
  28.                 std::cout << "RetAddr -> " << std::showbase << std::hex << varRetAddr << std::endl;
  29.                 varEbp = (int*)varEbp[0];
  30.                 StackFrameCount++;
  31.         }
  32. }
  33. void Fun3()
  34. {
  35.         //[EBP + 0] -> FUN2.EBP
  36.         //[EBP + 4] -> FUN2.RETADDR
  37.         PrintCallBack();
  38. }
  39. void Fun2()
  40. {
  41.         //[EBP + 0] -> FUN1.EBP
  42.         //[EBP + 4] -> FUN1.RETADDR
  43.         Fun3();
  44. }
  45. void Fun1()
  46. {
  47.         //[EBP + 0] -> MAIN.EBP
  48.         //[EBP + 4] -> MAIN.RETADDR
  49.         Fun2();
  50. }
  51. int main()
  52. {
  53.         Fun1();
  54.         return 0;
  55. }
复制代码

符号解析

符号信息


示例代码

  1. #include <iostream>
  2. #include <Windows.h>
  3. #include <DbgHelp.h>
  4. #pragma comment(lib, "dbghelp.lib")
  5. void PrintCallBack()
  6. {
  7.         WORD wFrameCount = 0;
  8.         HANDLE hProcess = NULL;
  9.         PVOID pStack[100] = { 0 };
  10.         SYMBOL_INFO* symInfo = NULL;
  11.         hProcess = GetCurrentProcess();
  12.         // 符号解析
  13.         if (SymInitialize(hProcess, NULL, TRUE) == FALSE) return;
  14.         // 获取栈帧
  15.         wFrameCount = RtlCaptureStackBackTrace(1, 100, pStack, NULL);
  16.         // 符号信息
  17.         symInfo = (SYMBOL_INFO*)malloc(sizeof(SYMBOL_INFO) + MAX_PATH);
  18.         memset(symInfo, 0, sizeof(SYMBOL_INFO) + MAX_PATH);
  19.         symInfo->SizeOfStruct = sizeof(SYMBOL_INFO);
  20.         symInfo->MaxNameLen = 255;
  21.         // 回溯信息
  22.         for (size_t i = 0; i < wFrameCount; i++)
  23.         {
  24.                 CHAR strModule[MAX_PATH] = { 0 };
  25.                 DWORD dwModuleBase = NULL;
  26.                 SymFromAddr(hProcess, (DWORD64)pStack[i], 0, symInfo);
  27.                 dwModuleBase = SymGetModuleBase(hProcess, (DWORD64)pStack[i]);
  28.                 GetModuleFileNameA((HMODULE)dwModuleBase, strModule, MAX_PATH);
  29.                 if (dwModuleBase)
  30.                 {
  31.                         std::cout << "---------------------------------------" << std::endl;
  32.                         std::cout << "ModuleName -> " << strModule << std::endl;
  33.                         std::cout << "FunctnName -> " << symInfo->Name << std::endl;
  34.                         std::cout << "FunStrAddr -> " << "0x" << std::hex << symInfo->Address << std::endl;
  35.                         std::cout << "FunRetAddr -> " << "0x" << std::hex << (DWORD)pStack[i] << std::endl;
  36.                         std::cout << "ModuleAddr -> " << "0x" << std::hex << dwModuleBase << std::endl;
  37.                 }
  38.         }
  39. }
  40. void Fun3()
  41. {
  42.         PrintCallBack();
  43. }
  44. void Fun2()
  45. {
  46.         Fun3();
  47. }
  48. void Fun1()
  49. {
  50.         Fun2();
  51. }
  52. int main()
  53. {
  54.         Fun1();
  55.         return 0;
  56. }
复制代码
DBG




  • visual studio中设置工程项目属性

    • 随机基址 - 否
    • 固定基址 - 是

  • F11运行工程项目转到反汇编检察MAIN函数地址
  • DBG启动调试程序
  • CTRL + G 转到指定MAIN函数地址
  • 通过函数头部下断方式检察栈顶数据返回地址进行堆栈回溯



IDA



  • 加载指定PE文件
  • Function窗口中搜刮MAIN
  • 选中函数过程名点击X展开交叉引用窗口
 



免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。
回复

使用道具 举报

0 个回复

倒序浏览

快速回复

您需要登录后才可以回帖 登录 or 立即注册

本版积分规则

梦见你的名字

金牌会员
这个人很懒什么都没写!
快速回复 返回顶部 返回列表