Windows调试——基本知识

基本寄存器和反汇编知识
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=????????

你可能感兴趣的:(软件调试,调试)