Windows调试——基本知识
来源:互联网 发布:计算卡路里的软件 编辑:程序博客网 时间:2024/06/05 18:34
基本寄存器和反汇编知识
EBP: 扩展基址指针寄存器(extended base pointer) 其内存放一个指针,该指针指向系统栈最上面一个栈帧的底部。
ESP: 栈顶指针,用于指向栈的栈顶(下一个压入栈的活动记录的顶部),而EBP为帧指针,指向当前活动记录的底部。
EIP: 指令寄存器,存放当前指令的下一条指令的地址。CPU该执行哪条指令就是通过IP来指示的。
具体代码:
反汇编代码:
#include "stdafx.h"int sum(int x, int y){01271000 push ebp 01271001 mov ebp,esp 01271003 push ecx //__asm mov ebp, 0 int* p= NULL;01271004 mov dword ptr [p],0 x = *p;0127100B mov eax,dword ptr [p] 0127100E mov ecx,dword ptr [eax] 01271010 mov dword ptr [x],ecx return (x + y); 01271013 mov eax,dword ptr [x] 01271016 add eax,dword ptr [y] }01271019 mov esp,ebp 0127101B pop ebp 0127101C ret --- 无源文件-----------------------------------------------------------------------0127101D int 3 0127101E int 3 0127101F int 3 --- c:\users\lifangzheng\documents\visual studio 2008\projects\crashtest\crashtest\crashtest.cpp int sumstub(int x, int y){01271020 push ebp 01271021 mov ebp,esp 01271023 push ecx int tmp = 0;01271024 mov dword ptr [tmp],0 printf("enter fun() ...\n");0127102B push offset ___xi_z+34h (12720F4h) 01271030 call dword ptr [__imp__printf (12720A0h)] 01271036 add esp,4 tmp = sum(x, y);01271039 mov eax,dword ptr [y] 0127103C push eax 0127103D mov ecx,dword ptr [x] 01271040 push ecx 01271041 call sum (1271000h) 01271046 add esp,8 01271049 mov dword ptr [tmp],eax printf("leave fun() ...\n");0127104C push offset ___xi_z+48h (1272108h) 01271051 call dword ptr [__imp__printf (12720A0h)] 01271057 add esp,4 return tmp;0127105A mov eax,dword ptr [tmp] }0127105D mov esp,ebp 0127105F pop ebp 01271060 ret--- 无源文件-----------------------------------------------------------------------……--- c:\users\lifangzheng\documents\visual studio 2008\projects\crashtest\crashtest\crashtest.cpp int _tmain(int argc, _TCHAR* argv[]){01271070 push ebp 01271071 mov ebp,esp printf("enter main() ...\n");01271073 push offset ___xi_z+5Ch (127211Ch) 01271078 call dword ptr [__imp__printf (12720A0h)] 0127107E add esp,4 printf("sum = %d\n", sumstub(0x1234, 0x5678));01271081 push 5678h 01271086 push 1234h 0127108B call sumstub (1271020h) 01271090 add esp,8 01271093 push eax 01271094 push offset ___xi_z+70h (1272130h) 01271099 call dword ptr [__imp__printf (12720A0h)] 0127109F add esp,8 printf("leave main() ...\n");012710A2 push offset ___xi_z+7Ch (127213Ch) 012710A7 call dword ptr [__imp__printf (12720A0h)] 012710AD add esp,4 return 0;012710B0 xor eax,eax }012710B2 pop ebp 012710B3 ret
Dump实例分析
1.通过编译器环境或者其他手段得到Dump日志。
2.输入 !analyze –v:自动分析命令
3.堆栈片段分析:
. 0(线程序号) Id: 1744(线程ID).fd4 Suspend: 0 Teb: 7ffdf000 Unfrozen
ChildEBP RetAddr Args to Child
002ef814 01271046 00001234 00005678 00000000 CrashTest!sum+0xe
002ef828 01271090 00001234 00005678 002ef87c CrashTest!sumstub+0x26
002ef838 0127121d 00000001 003f1ad8 003f1bb0 CrashTest!wmain+0x20
002ef87c 76caee1c 7ffd4000 002ef8c8 77c037eb CrashTest!__tmainCRTStartup+0x10f
WARNING: Stack unwind information not available. Following frames may be wrong.
002ef888 77c037eb 7ffd4000 72a4cec4 00000000 kernel32!BaseThreadInitThunk+0x12
002ef8c8 77c037be 01271365 7ffd4000 00000000 ntdll!RtlInitializeExceptionChain+0xef
002ef8e0 00000000 01271365 7ffd4000 00000000 ntdll!RtlInitializeExceptionChain+0xc2
几个名词:
ChildEBP: a pointer to a memory location which stores the address of the previous function on the stack (“stack frame”).(ebp的值:堆栈基地址)
RetAddr: The “return address” where processing will resume once this function returns (finishes what it had to do).(函数执行完以后返回的:计算机指令地址)
*当前寄存器状态:*
0:000> r
eax=00000000 ebx=00000000 ecx=00001234 edx=77be70f4 esi=00000001 edi=0127337c
eip=0127100e esp=002ef810 ebp=002ef814 iopl=0 nv up ei pl nz na pe nc
cs=001b ss=0023 ds=0023 es=0023 fs=003b gs=0000 efl=00010206
CrashTest!sum+0xe:
0127100e 8b08 mov ecx,dword ptr [eax] ds:0023:00000000=????????
崩溃原因:eax为0,所以读取空指针指向内存里的值出现崩溃。
0127100e 是计算机指令地址。
绝大多数dump都可以通过!analyze -v指令得到崩溃的最直接原因。
另外一种特殊情况
在做组件的过程中可能会遇到,上层应用调用组件功能,并且设置了完备的异常处理机制,比如SEH,但是不幸的是,组件此时发生崩溃,虽然由dump输出,!analyze确发现不了崩溃的原因。
这种情况下的堆栈常如下所示:
0:000> ~*kv //显示出所有线程,找到对应的函数标识
. 0 Id: 12a0.44c Suspend: 0 Teb: 7ffdf000 Unfrozen
ChildEBP RetAddr Args to Child
WARNING: Stack unwind information not available. Following frames may be wrong.
001df590 7762be2e 001df544 001df5b8 00000000 ntdll!KiFastSystemCallRet
001df5d8 7762be9c 00000002 7ffd5000 00000000 kernel32!WaitForMultipleObjectsEx+0x8e
001df5f4 776406b7 00000002 001df628 00000000 kernel32!WaitForMultipleObjects+0x18
001df660 77640952 001df740 00000001 00000001 kernel32!GetThreadSelectorEntry+0x1ee
001df674 77640900 001df740 00000001 001df710 kernel32!UnhandledExceptionFilter+0x249
001df684 7764087b 001df740 00000001 6c699e83 kernel32!UnhandledExceptionFilter+0x1f7
001df710 77da7f62 00000000 77d4e31c 00000000 kernel32!UnhandledExceptionFilter+0x172
001dffc0 77d937be 011d107d 7ffd5000 00000000 ntdll!EtwReplyNotification+0x366
001dffd8 00000000 011d107d 7ffd5000 00000000 ntdll!RtlInitializeExceptionChain+0xc2
1) Kernel32! UnhandledExceptionFilter第一个参数为 EXCEPTION_POINTERS结构
2)再根据 KiUserExceptionDispatcher函数的原型得到本次异常发生时保存的 CONTEXT 结构信息。(windows 系统底层具体处理异常的函数)
VOID KiUserExceptionDispatcher (
IN PEXCEPTION_RECORD ExceptionRecord,
IN PCONTEXT ContextRecord
)
3)通过命令/显示EXCEPTION_POINTERS数据结构里各个变量值
0:000> dd 001df740 L2
001df740 001df840 001df85c
4)调用cxr命令解析崩溃瞬间的堆栈
0:000> .cxr 001df85c
eax=00000000 ebx=7ffd5000 ecx=00000000 edx=0fb91408 esi=001dfd68 edi=001dfd58
eip=011d13e8 esp=001dfc80 ebp=001dfd58 iopl=0 nv up ei pl nz ac po nc
cs=001b ss=0023 ds=0023 es=0023 fs=003b gs=0000 efl=00010212
CrashTest!sum+0x28:
011d13e8 8b08 mov ecx,dword ptr [eax] ds:0023:00000000=????????
- Windows调试——基本知识
- Application——基本知识
- CSS —表格基本知识
- Windows调试工具入门1—Windows调试工具介绍
- Windows调试工具入门1—Windows调试工具介绍
- 调试代码的基本知识
- 嵌入式学习——LINUX的基本知识 的基本知识【2】
- 基本知识——2014.6.3
- Qt 基本知识 ——路径
- Java内存——基本知识
- 黑马程序员—网络基本知识
- 反射(1)—基本知识
- Windows调试工具入门2—基本调试器设置
- Windows调试工具入门3—基本调试操作
- Android ADB调试基本知识汇总
- mipi 基本知识和调试经验
- Windows调试——死锁的查找
- Windows调试——死锁的查找
- css-元素水平、竖直居中
- Android 项目开发实战:答题系统
- iOS图标工场
- iOS 是否包含某个字符串 判断整形 浮点型
- RxJava操作符
- Windows调试——基本知识
- Java 数组构建二叉树
- 错误:The request sent by the client was syntactically incorrect的解决
- Android下拉刷新完全解析,教你如何一分钟实现下拉刷新功能
- 结构体指针和结构体嵌套
- Android学习历程14-Android ListView优化
- Java 二叉树广度优先遍历
- Implement Queue using Stacks
- 安卓Xutils3网络工具,注解工具,图片工具和日志工具的使用,以及对网络工具的封装