首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> C語言 >> C++ >> 關於C++

調用棧深度解析 (三):Windbg 腳本自動化遍歷調用棧參數

     編輯:關於C++

系列回顧

  • (一) Windbg 基礎調用棧查看命令 (k, kb, kp)
  • (二) x86 調用約定 (__stdcall/__cdecl) 參數棧佈局分析
  • (三) 本文:DScript 腳本自動化提取棧幀參數

演示程序:遞歸累加


#include <stdio.h>
int SumToOne(int d, int sum) {
    sum += d;
    if (d != 1) sum = SumToOne(d-1, sum);
    else sum = sum; // 斷點設置處
    return sum;
}
void main() {
    int sum = SumToOne(10, 0);
    printf("sum=%d", sum);
}

在 sum = sum; 處下斷點,調用棧深度 11 幀 (main + 10 次遞歸)。

Windbg 腳本:DumpStack.txt


.printf "Dump %d frames\n", ${$arg1}
r $t1 = @ebp;               // 初始化幀指針
.for (r $t0 = 1; $t0 <= ${$arg1}; r $t0 = $t0 + 1) {
    .printf "frame %d, d=%d sum=%d\n", $t0, poi($t1+8), poi($t1+0xC);
    r $t1 = poi($t1);       // 移動到上一幀 ebp
}

執行與輸出


0:000> $$>a< "DumpStack.txt" a
Dump 10 frames
frame 1, d=10 sum=10
frame 2, d=9 sum=19
frame 3, d=8 sum=27
...
frame 10, d=1 sum=55

腳本語法詳解

語法含義
$$>a< "file" args帶參數執行腳本文件 (a 表示傳參)
${$arg1}引用第 1 個傳入參數 (十六進制,a=10)
r $t1 = expr賦值給偽寄存器/別名 (類比 C 宏)
poi(addr)解引用內存地址 (等價 C *addr),MASM 語法
.for (init; cond; step) { }循環控制結構
.printf "fmt", args格式化輸出

算法邏輯:手動棧回溯

  1. 初始幀指針: @ebp 指向當前幀基址
  2. 參數偏移: __stdcall 從右向左壓棧,ebp+8 = 第 1 參數 d,ebp+0xC = 第 2 參數 sum
  3. 上一幀: [ebp] 保存調用者 ebp,poi(@ebp) 即上一幀基址
  4. 迭代: 循環 arg1 次,逐幀輸出參數

擴展應用

  • 添加返回地址解析:poi($t1+4) 獲取 eip,配合 ln 顯示函數名
  • 支持變參/不同調用約定:動態計算參數偏移
  • 結合 .if/@$csp 實現條件斷點自動導出棧狀態

掌握 DScript,可將重複性調試任務自動化,構建專屬診斷工具庫,大幅提升疑難崩潰分析效率。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved