用Windbg和OllyICE调试Pidgin

由于机器上IM安装较多,就去http://www.pidgin.im/下了一个pidgin,连上了msngtalk还有QQ,比较爽,但是近来发现当打开对话窗口时,选中选择字体老是造成程序crash,无奈之下就不只好不改字体。等了3pidgin新版本,问题依旧。我天真的认为总会被官方fix的。

废话不说,上windbg,开启pidgin,用windbg attach上,一切安好。继续g,依次选中字体,结果问题出现了:

省略若干加载模块。。。。。。

(1ac4.2890): Access violation - code c0000005 (first chance)

First chance exceptions are reported before any exception handling.

This exception may be expected and handled.

eax=002283de ebx=002283f0 ecx=77639d78 edx=002283de esi=00000000 edi=0375d090

eip=68ddf5e8 esp=002282d0 ebp=00228318 iopl=0         nv up ei pl nz na po nc

cs=001b  ss=0023  ds=0023  es=0023  fs=003b  gs=0000             efl=00010202

*** ERROR: Symbol file could not be found.  Defaulted to export symbols for C:\Program Files\Common Files\GTK\2.0\bin\libcairo-2.dll -

libcairo_2!cairo_scaled_font_text_extents+0x18:

68ddf5e8 8b4604          mov     eax,dword ptr [esi+4] ds:0023:00000004=????????

 

出现了一个Access violation,出现在libcairo_2!cairo_scaled_font_text_extents里,打开register,发现ESI0,可不访问错误。

打开disassembly,汇编码如下:

 

 1 libcairo_2!cairo_scaled_font_text_extents:
 2 68ddf5d0 55              push    ebp
 3 68ddf5d1 89e5            mov     ebp,esp
 4 68ddf5d3 56              push    esi
 5 68ddf5d4 53              push    ebx
 6 68ddf5d5 83ec40          sub     esp,40h
 7 68ddf5d8 8b7508          mov     esi,dword ptr [ebp+8]
 8 68ddf5db c745f000000000  mov     dword ptr [ebp-10h],0
 9 68ddf5e2 8b550c          mov     edx,dword ptr [ebp+0Ch]
10 68ddf5e5 8b5d10          mov     ebx,dword ptr [ebp+10h]
11 68ddf5e8 8b4604          mov     eax,dword ptr [esi+4ds:0023:00000004=????????
12 68ddf5eb 85c0            test    eax,eax
13 68ddf5ed 0f858d000000    jne     libcairo_2!cairo_scaled_font_text_extents+0xb0 (68ddf680)//goto ZERO_EXTENTS
14 68ddf5f3 85d2            test    edx,edx
15 68ddf5f5 0f8485000000    je      libcairo_2!cairo_scaled_font_text_extents+0xb0 (68ddf680)// goto ZERO_EXTENTS
16 68ddf5fb 89542414        mov     dword ptr [esp+14h],edx
17 68ddf5ff 31c0            xor     eax,eax
18 68ddf601 d9ee            fldz
19 68ddf603 8944242c        mov     dword ptr [esp+2Ch],eax
20 68ddf607 31c0            xor     eax,eax
21 68ddf609 b9ffffffff      mov     ecx,0FFFFFFFFh
22 68ddf60e 89442428        mov     dword ptr [esp+28h],eax
23 68ddf612 31c0            xor     eax,eax
24 68ddf614 89442424        mov     dword ptr [esp+24h],eax
25 68ddf618 8d45f4          lea     eax,[ebp-0Ch]
26 68ddf61b 89442420        mov     dword ptr [esp+20h],eax
27 68ddf61f 8d45f0          lea     eax,[ebp-10h]
28 68ddf622 8944241c        mov     dword ptr [esp+1Ch],eax
29 68ddf626 894c2418        mov     dword ptr [esp+18h],ecx
30 68ddf62a dd54240c        fst     qword ptr [esp+0Ch]
31 68ddf62e dd5c2404        fstp    qword ptr [esp+4]
32 68ddf632 893424          mov     dword ptr [esp],esi
33 68ddf635 e866f8ffff      call    libcairo_2!cairo_scaled_font_text_to_glyphs (68ddeea0)
34 68ddf63a 85c0            test    eax,eax
35 68ddf63c 7532            jne     libcairo_2!cairo_scaled_font_text_extents+0xa0 (68ddf670)
36 68ddf63e 895c240c        mov     dword ptr [esp+0Ch],ebx
37 68ddf642 8b45f4          mov     eax,dword ptr [ebp-0Ch]
38 68ddf645 89442408        mov     dword ptr [esp+8],eax
39 68ddf649 8b45f0          mov     eax,dword ptr [ebp-10h]
40 68ddf64c 893424          mov     dword ptr [esp],esi
41 68ddf64f 89442404        mov     dword ptr [esp+4],eax
42 68ddf653 e8f8fcffff      call    libcairo_2!cairo_scaled_font_glyph_extents (68ddf350)
43 68ddf658 8b45f0          mov     eax,dword ptr [ebp-10h]
44 68ddf65b 890424          mov     dword ptr [esp],eax
45 68ddf65e e83dcd0600      call    libcairo_2!cairo_svg_surface_create_for_stream+0x3fc80 (68e4c3a0)
46 68ddf663 83c440          add     esp,40h
47 68ddf666 5b              pop     ebx
48 68ddf667 5e              pop     esi
49 68ddf668 5d              pop     ebp
50 68ddf669 c3              ret//return
51 68ddf66a 8db600000000    lea     esi,[esi]
52 68ddf670 89442404        mov     dword ptr [esp+4],eax
53 68ddf674 893424          mov     dword ptr [esp],esi
54 68ddf677 e864d4ffff      call    libcairo_2!cairo_pattern_get_radial_circles+0x1660 (68ddcae0)
55 68ddf67c 8d742600        lea     esi,[esi]
56 68ddf680 d9ee            fldz
57 68ddf682 dd13            fst     qword ptr [ebx]//最后六个赋值
58 68ddf684 dd5308          fst     qword ptr [ebx+8]
59 68ddf687 dd5310          fst     qword ptr [ebx+10h]
60 68ddf68a dd5318          fst     qword ptr [ebx+18h]
61 68ddf68d dd5320          fst     qword ptr [ebx+20h]
62 68ddf690 dd5b28          fstp    qword ptr [ebx+28h]
63 68ddf693 83c440          add     esp,40h
64 68ddf696 5b              pop     ebx
65 68ddf697 5e              pop     esi
66 68ddf698 5d              pop     ebp
67 68ddf699 c3              ret
68 

 

 

看不懂什么意思。我记得cairo好像是开源的图形包啊,去下一个来看看,下了一个最新版,打开了cairo-scaled-font.c,找到了cairo_scaled_font_text_extents函数:

 

 1 void cairo_scaled_font_text_extents (cairo_scaled_font_t   *scaled_font,
 2                 const char            *utf8,
 3                 cairo_text_extents_t  *extents)
 4 {
 5     cairo_status_t status;
 6     cairo_glyph_t *glyphs = NULL;
 7     int num_glyphs;
 8 
 9     if (scaled_font->status)// scaled_font是空,所以访问错误
10     goto ZERO_EXTENTS;
11 
12     if (utf8 == NULL)
13     goto ZERO_EXTENTS;
14 
15     status = cairo_scaled_font_text_to_glyphs (scaled_font, 0., 0.,
16                            utf8, -1,
17                            &glyphs, &num_glyphs,
18                            NULL, NULL,
19                            NULL);
20     if (status)
21     goto ZERO_EXTENTS;
22 
23     cairo_scaled_font_glyph_extents (scaled_font, glyphs, num_glyphs, extents);
24     free (glyphs);
25 
26     return;
27 
28 ZERO_EXTENTS:
29     extents->x_bearing = 0.0;
30     extents->y_bearing = 0.0;
31     extents->width  = 0.0;
32     extents->height = 0.0;
33     extents->x_advance = 0.0;
34     extents->y_advance = 0.0;
35 }
36 

 

对着源代码,比较容易读懂上面的汇编码,大家不要弄清楚每行指令的含义,只要能看懂基本的流程就行,我也做了简单的注释。错误是出现在

 

8b4604          mov     eax,dword ptr [esi+4ds:0023:00000004=????????

 

esi是在前面68ddf5d8 8b7508          mov     esi,dword ptr [ebp+8]给赋的值,再结合后面test指令和源代码,估计错误行对应的是

 

if (scaled_font->status)
    
goto ZERO_EXTENTS;

 

 

[esi+4]就是通过偏移来访问变量,而这个scaled_font指针恰好是个NULL,所以才造成了访问错误。

怎么解决呢?首先下了一个最新的Cairo包,替换,问题依旧。可以下个源码包,自己编译一个?那我得把整个gtk+给编译一遍,还不加那些可怕的dependency,还得装cygwin,不由得印堂发黑,估计没有个把小时是搞不定的。

这时候我想起了OllyICE,也是调试的利器,和windbg不同的是它可以改写汇编码,也就是说可以crack软件。打开,同样attachpidgin,同样crash在同样的错误行,把mov     eax,dword ptr [esi+4]改为jmp 68ddf680;对应的源码就是直接改为goto ZERO_EXTENTS或是直接NOP掉。保存libcairo-2.dll,收工,至此pidgin的字体窗口能顺利打开了,而且也能正确设置字体了,半个小时解决问题。这只是个临时的解决办法,最好的办法是报个bug给gtk+。

后记:我在linux上用pidgin是没有问题的,估计是gtk+win32上有bug

 

 

 

 

 

 

 

posted @ 2009-06-10 22:08  DiggingDeeply  阅读(2170)  评论(3编辑  收藏  举报