x86架构基础
- 程序内存布局
- 低地址0x00000000至0x7FFFFFFF(用户态)
- 核心区域:栈、程序镜像、PEB/TEB、堆、DLL
- 栈:线程专属、LIFO结构、PUSH/POP指令
- 调用约定
- 定义:函数参数传递、返回值、栈清理规则
- 决定方:编译器/程序员自定义
- 函数返回机制
- 返回地址+参数+局部变量存储于栈帧
- 函数结束后从栈取返回地址恢复执行流
- CPU寄存器(32位共9个)
- 通用寄存器:EAX(算术)、EBX(基址)、ECX(计数)、EDX(数据)、ESI/EDI(串操作)
- 栈指针ESP:指向栈顶,跟踪栈最新位置
- 基指针EBP:指向函数调用时栈顶,定位栈帧数据
- 指令指针EIP:指向下一步执行指令,溢出攻击核心目标
WinDbg调试器基础
- 调试器选择原因
- 支持32/64位、用户态/内核态调试
- 自带脚本功能,兼容性优于OllyDbg/Immunity Debugger
- 含WinDbg Preview(Win10+),课程用标准版避兼容问题
- 核心概念
- 调试器角色:介于应用与CPU间的代理,操控执行流/访问内存
- 系统模式:用户态(ring3)(课程重点)、内核态(ring0)
- 汇编与操作码:汇编为机器码的人类可读形式,操作码为CPU识别的二进制序列
- 界面与操作
- 启动:课程VM预装,可从开始菜单/任务栏打开
- 附加进程:File→Attach to a Process(F6),附加后进程暂停
- 工作区:默认仅命令窗口,可自定义布局(反汇编/寄存器等窗口)
- 保存工作区:File菜单保存,跨调试会话使用
- 调试符号
- 作用:用名称替代内存地址,引用函数/结构/全局变量
- 格式:.PDB文件,微软为核心模块提供
- 配置:File→Symbol File Path,常用路径C:\symbols
- 加载:.reload /f强制加载,!sym noisy排查加载问题
WinDbg内存操作命令
- 反汇编:u命令
- 语法:u [地址/函数符号],无参数从EIP开始
- 示例:u kernel32!GetCurrentThread
- 读取内存:d*命令
- db:显示字节 | dw:显示字(2字节) | dd:显示双字(4字节) | dq:显示四字(8字节)
- dc/dW:显示同时带ASCII字符 | da:ASCII格式 | du:Unicode格式
- 扩展:L参数指定长度,poi命令解引用指针(dd poi(esp))
- 转储结构:dt命令
- 语法:dt [模块!结构名] [地址],无地址显示结构字段+偏移
- 参数:-r递归显示嵌套结构,可指定单个字段
- 扩展:??sizeof(结构名)获取结构字节大小
- 写入内存:e*命令
- 语法:ed(双字)/eb(字节) [地址] [值],ea(ASCII)/eu(Unicode)写字符串
- 示例:ed esp 41414141、ea esp "Hello"
- 搜索内存:s命令
- 语法:s -[类型] [起始地址] [长度] [模式]
- 类型:-d(双字)、-a(ASCII)、-u(Unicode)
- 示例:s -d 0 L?80000000 41414141(搜索整个用户态内存)
WinDbg寄存器操作
- 查看寄存器:r命令
- r:显示所有寄存器值 | r [寄存器名]:显示单个寄存器
- 修改寄存器:r命令
- 语法:r [寄存器名]=[值]
- 示例:r ecx=41414141
WinDbg程序执行控制
- 软件断点:bp命令
- 原理:将指令首字节替换为INT3,无数量限制
- 核心操作:bp [地址/函数](设置)| bl(列出)| bd/be(禁用/启用)| bc(清除)
- 示例:bp kernel32!WriteFile(断WriteFile API)
- 未解析函数断点:bu命令
- 作用:为未加载模块的函数设断点,模块加载后自动解析
- 示例:bu ole32!WriteStringStream(ole32.dll加载前设置)
- 断点触发动作
- 自动执行命令:bp [目标] "命令1;命令2;g"
- 格式化输出:.printf支持%p等格式符,示例:bp kernel32!WriteFile ".printf "字节数:%p",poi(esp+0x0C);g"
- 条件断点:结合.if/.else,示例:bp kernel32!WriteFile ".if(poi(esp+0x0C)==4){.printf "4字节";}else{ge;}"
- 硬件断点:ba命令
- 原理:由CPU调试寄存器控制,仅支持4个
- 语法:ba [访问类型] [字节数] [地址]
- 访问类型:e(执行)、r(读取)、w(写入)
- 示例:ba w 2 03b2c768(对指定地址写2字节触发)
- 单步执行
- p:步过,跳过函数调用 | t:步入,进入函数调用
- pt:步至下一个ret指令(函数结束)| ph:步至下一个分支指令
- 继续执行:g命令(解除进程暂停)
WinDbg高级功能
- 模块与符号查看
- lm:列出所有加载模块,lm m [通配符]过滤(如lm m kernel*)
- x:查看符号,x [模块!符号通配符](如x kernelbase!CreateProc*)
- 计算器功能:?命令
- 支持算术/位运算:+-*/、>>/<<等
- 默认十六进制,0n(十进制)/0y(二进制)前缀转换输入
- 数据格式转换
- .formats [值]:一次性转换为十六/十/八/二进制+ASCII
- 示例:.formats 41414141(显示AAAA及各进制值)
- 伪寄存器
- 定义:WinDbg自定义变量,非CPU寄存器,前缀@
- 系统伪寄存器:@$teb(指向TEB结构)等
- 用户伪寄存器:@$t0-@$t19,用于存储计算值
- 示例:r @$t0=(41414141-414141)*0n10
核心调试技巧与工具
- 常用辅助命令
- .hh:打开WinDbg内置手册 | g:继续执行 | .reload /f:重新加载符号
- 调试思路
- 附加进程→配置符号→设置断点→单步调试→查看/修改内存/寄存器
- 硬件断点适合跟踪内存读写,软件断点适合跟踪函数执行
- 课程要求
- 掌握所有基础命令与实操练习
- 熟练自定义工作区,利用脚本/条件断点自动化调试