• 基本调试命令


    原:http://www.cnblogs.com/developersupport/p/windbgcommand-u.html


    在调试过程中难免会遇到须要反编译代码来分析逻辑的时候。在windbg中,须要反编译代码就要用到u/ub/uf这三个命令。本文这里分别介绍这三个命令各自的用途。

    下面是一个quick sort的实例代码,将其编译成可运行文件,然后通过windbg运行。

    复制代码
    #include <stdio.h>
    #include <string.h>
    
    #define MAXLINES 5000
    #define MAXLEN 1000
    #define ALLOCSIZE 10000
    
    static char allocbuf[ALLOCSIZE];
    static char *allocp = allocbuf;
    char *lineptr[MAXLINES];
    
    int readlines(char *lineptr[], int nlines);
    void writelines(char *lineptr[], int nlines);
    
    void qsort(void *lineptr[], int left, int right, int(*comp)(void *, void *));
    int numcmp(char *, char *);
    
    main(int argc, int *argv[])
    {
        int nlines;
        int numeric = 0;
    
        if((argc > 1) && strcmp(argv[1], "-n")==0)
            numeric = 1;
        if((nlines = readlines(lineptr, MAXLINES)) >= 0){
            qsort((void **) lineptr, 0, nlines-1, 
                    (int (*)(void*, void*))(numeric ? numcmp : strcmp));
            writelines(lineptr, nlines);
            return 0;
        } else {
            printf("input too big to sort
    ");
            return 1;
        }
    }
    
    void qsort(void *v[], int left, int right,
            int (*comp)(void *, void *))
    {
        int i, last;
        void swap(void *v[], int, int);
    
        if(left >= right)
            return;
        swap(v, left, (left+right)/2);
        last = left;
        for( i = left+1; i <= right; i++)
            if((*comp)(v[i], v[left]) < 0)
                swap(v, ++last, i);
        swap(v, left, last);
        qsort(v, left, last-1, comp);
        qsort(v, last+1, right, comp);
    }
    
    char *alloc(int n)
    {
        if(allocbuf + ALLOCSIZE - allocp >= n){
            allocp += n;
            return allocp - n;
        } else
            return 0;
    }
    
    int getline(char s[], int lim)
    {
        int c, i;
        i = 0;
        while(--lim > 0 && (c=getchar()) != EOF && c != '
    ')
            s[i++] = c;
        if(c == '
    ')
            s[i++] = c;
        s[i] = '';
        return i;
    }
    
    int readlines(char *lineptr[], int maxlines)
    {
        int len, nlines;
        char *p, line[MAXLEN];
        nlines = 0;
        while((len = getline(line, MAXLEN)) > 0)
            if((nlines >= maxlines  || (p = alloc(len)) == NULL))
                return -1;
            else{
                line[len-1] = '';
                strcpy(p, line);
                lineptr[nlines++] = p;
            }
        return nlines;
    }
    
    void writelines(char *lineptr[], int nlines)
    {
        int i;
    
        for(i = 0; i < nlines; i++)
            printf("%s
    ", lineptr[i]);
    }
    
    int numcmp(char *s1, char *s2)
    {
        double v1, v2;
    
        v1 = atof(s1);
        v2 = atof(s2);
        if(v1 < v2)
            return -1;
        else if(v1 > v2)
            return 1;
        else
            return 0;
    }
    
    void swap(void *v[], int i, int j)
    {
        void *temp;
    
        temp = v[i];
        v[i] = v[j];
        v[j] = temp;
    }
    复制代码

     

    u命令

    u命令的作用就是反编译指定地址參数之后的代码,假设不指定地址參数,即仅仅输入u命令运行,那么默认就是反编译当前线程的当前指令

    我们来做个实验。在运行起实例代码之后,在main函数上设断点,然后通过u命令来反编译eip(instruction pointer)中的地址指向的方法地址。即当前函数的运行地址。能够查看接下来当前线程要运行的汇编代码。

    关于x86各个寄存器的含义能够參考x86 Architecture

    复制代码

    0:000> x qsort!main
    000c12e0 qsort!main (int, int **)
    0:000> bp 000c12e0 
    0:000> g
    Breakpoint 0 hit
    eax=004e8228 ebx=00000000 ecx=00000001 edx=00000000 esi=00000000 edi=00000000
    eip=000c12e0 esp=0027f7d4 ebp=0027f818 iopl=0 nv up ei pl zr na pe nc
    cs=0023 ss=002b ds=002b es=002b fs=0053 gs=002b efl=00000246
    qsort!main:
    000c12e0 55 push ebp
    0:000> u @eip
    qsort!main [c:qsort.c @ 19]:
    000c12e0 55 push ebp
    000c12e1 8bec mov ebp,esp
    000c12e3 83ec0c sub esp,0Ch
    000c12e6 c745f800000000 mov dword ptr [ebp-8],0
    000c12ed 837d0801 cmp dword ptr [ebp+8],1
    000c12f1 7e27 jle qsort!main+0x3a (000c131a)
    000c12f3 6804b00e00 push offset qsort!allocp+0x4 (000eb004)
    000c12f8 b804000000 mov eax,4

    复制代码

    uf命令

    uf命令是用来反编译整个函数的汇编代码,

    比方我希望反编译整个main函数,能够通过uf函数。

    复制代码

    0:000> uf @eip
    qsort!main [c:qsort.c @ 19]:
    19 000c12e0 55 push ebp
    19 000c12e1 8bec mov ebp,esp
    19 000c12e3 83ec0c sub esp,0Ch
    21 000c12e6 c745f800000000 mov dword ptr [ebp-8],0
    23 000c12ed 837d0801 cmp dword ptr [ebp+8],1
    23 000c12f1 7e27 jle qsort!main+0x3a (000c131a)

    qsort!main+0x13 [c:qsort.c @ 23]:
    23 000c12f3 6804b00e00 push offset qsort!allocp+0x4 (000eb004)
    23 000c12f8 b804000000 mov eax,4
    23 000c12fd c1e000 shl eax,0
    23 000c1300 8b4d0c mov ecx,dword ptr [ebp+0Ch]
    23 000c1303 8b1401 mov edx,dword ptr [ecx+eax]
    23 000c1306 52 push edx
    23 000c1307 e854080000 call qsort!strcmp (000c1b60)
    23 000c130c 83c408 add esp,8
    23 000c130f 85c0 test eax,eax
    23 000c1311 7507 jne qsort!main+0x3a (000c131a)

    qsort!main+0x33 [c:qsort.c @ 24]:
    24 000c1313 c745f801000000 mov dword ptr [ebp-8],1

    qsort!main+0x3a [c:qsort.c @ 25]:
    25 000c131a 6888130000 push 1388h
    25 000c131f 68e0020f00 push offset qsort!lineptr (000f02e0)
    25 000c1324 e8f5fcffff call qsort!ILT+25(_readlines) (000c101e)
    25 000c1329 83c408 add esp,8
    25 000c132c 8945fc mov dword ptr [ebp-4],eax
    25 000c132f 837dfc00 cmp dword ptr [ebp-4],0
    25 000c1333 7c47 jl qsort!main+0x9c (000c137c)

    qsort!main+0x55 [c:qsort.c @ 27]:
    27 000c1335 837df800 cmp dword ptr [ebp-8],0
    27 000c1339 7409 je qsort!main+0x64 (000c1344)

    qsort!main+0x5b [c:qsort.c @ 27]:
    27 000c133b c745f414100c00 mov dword ptr [ebp-0Ch],offset qsort!ILT+15(_numcmp) (000c1014)
    27 000c1342 eb07 jmp qsort!main+0x6b (000c134b)

    qsort!main+0x64 [c:qsort.c @ 27]:
    27 000c1344 c745f4601b0c00 mov dword ptr [ebp-0Ch],offset qsort!strcmp (000c1b60)

    qsort!main+0x6b [c:qsort.c @ 27]:
    27 000c134b 8b45f4 mov eax,dword ptr [ebp-0Ch]
    27 000c134e 50 push eax
    27 000c134f 8b4dfc mov ecx,dword ptr [ebp-4]
    27 000c1352 83e901 sub ecx,1
    27 000c1355 51 push ecx
    27 000c1356 6a00 push 0
    27 000c1358 68e0020f00 push offset qsort!lineptr (000f02e0)
    27 000c135d e8adfcffff call qsort!ILT+10(_qsort) (000c100f)
    27 000c1362 83c410 add esp,10h
    28 000c1365 8b55fc mov edx,dword ptr [ebp-4]
    28 000c1368 52 push edx
    28 000c1369 68e0020f00 push offset qsort!lineptr (000f02e0)
    28 000c136e e8bafcffff call qsort!ILT+40(_writelines) (000c102d)
    28 000c1373 83c408 add esp,8
    29 000c1376 33c0 xor eax,eax
    29 000c1378 eb14 jmp qsort!main+0xae (000c138e)

    qsort!main+0x9c [c:qsort.c @ 31]:
    31 000c137c 6808b00e00 push offset qsort!allocp+0x8 (000eb008)
    31 000c1381 e80c060000 call qsort!printf (000c1992)
    31 000c1386 83c404 add esp,4
    32 000c1389 b801000000 mov eax,1

    qsort!main+0xae [c:qsort.c @ 34]:
    34 000c138e 8be5 mov esp,ebp
    34 000c1390 5d pop ebp
    34 000c1391 c3 ret

    复制代码

    另外uf另一个比較经常使用的參数项/c,通过/c能够查看这个函数中的函数调用(call)都有哪些,当一个函数反编译代码过长的时候,我们能够通过这个參数来过滤全部的方法调用,方便查找。

    复制代码

    0:000> uf /c @eip
    qsort!main (000c12e0) [c:qsort.c @ 19]
    qsort!main+0x27 (000c1307) [c:qsort.c @ 23]:
    call to qsort!strcmp (000c1b60) [f:ddvctoolscrt_bldSELF_X86crtsrcINTELstrcmp.asm @ 65]
    qsort!main+0x44 (000c1324) [c:qsort.c @ 25]:
    call to qsort!ILT+25(_readlines) (000c101e)
    qsort!main+0x7d (000c135d) [c:qsort.c @ 27]:
    call to qsort!ILT+10(_qsort) (000c100f)
    qsort!main+0x8e (000c136e) [c:qsort.c @ 28]:
    call to qsort!ILT+40(_writelines) (000c102d)
    qsort!main+0xa1 (000c1381) [c:qsort.c @ 31]:
    call to qsort!printf (000c1992) [f:ddvctoolscrt_bldself_x86crtsrcprintf.c @ 49] 

    复制代码

    ub命令

    ub命令与u的不同之处在于它是用来查看线程当前指令之前的汇编代码。b这里就是代表向后查看(backward)的意思。

    在调用qsort!qsort方法之前设置断点,运行到这个断点的时候。假设希望看到前面运行的代码是什么样的。这时能够通过ub函数查看,通过对照就能够发现ub列出的汇编代码恰好是调用qsort!qsort方法之前的指令。

    复制代码

    0:000> bp 000c135d 
    0:000> g
    Breakpoint 1 hit
    eax=000c1b60 ebx=00000000 ecx=00000002 edx=00000000 esi=00000000 edi=00000000
    eip=000c135d esp=0027f7b4 ebp=0027f7d0 iopl=0 nv up ei pl nz na po nc
    cs=0023 ss=002b ds=002b es=002b fs=0053 gs=002b efl=00000202
    qsort!main+0x7d:
    000c135d e8adfcffff call qsort!ILT+10(_qsort) (000c100f)
    0:000> ub 000c135d 
    qsort!main+0x64 [c:qsort.c @ 27]:
    000c1344 c745f4601b0c00 mov dword ptr [ebp-0Ch],offset qsort!strcmp (000c1b60)
    000c134b 8b45f4 mov eax,dword ptr [ebp-0Ch]
    000c134e 50 push eax
    000c134f 8b4dfc mov ecx,dword ptr [ebp-4]
    000c1352 83e901 sub ecx,1
    000c1355 51 push ecx
    000c1356 6a00 push 0
    000c1358 68e0020f00 push offset qsort!lineptr (000f02e0)

    复制代码

     

    我希望对你有所帮助上述内容

    Aaron Zhang


  • 相关阅读:
    discuz方法赏析
    rpm安装软件(需管理员权限)
    php.ini修改php上传文件大小限制
    grep 基于关键字搜索
    网络排查的原则
    Sublime Text快捷键
    表格无边框,有内框,在table嵌套时,防止出现重复边线
    文件(图片)强制下载
    网络相关配置文件的位置
    ip,子网掩码,网关,DNS
  • 原文地址:https://www.cnblogs.com/blfshiye/p/4561657.html
Copyright © 2020-2023  润新知