Chinaunix首页 | 论坛 | 博客
  • 博客访问: 71266
  • 博文数量: 41
  • 博客积分: 1475
  • 博客等级: 上尉
  • 技术积分: 440
  • 用 户 组: 普通用户
  • 注册时间: 2009-03-27 22:49
文章分类
文章存档

2012年(8)

2011年(1)

2009年(32)

我的朋友
最近访客

分类: WINDOWS

2009-03-28 11:28:42

操作系统版本

Windows Server 2008 (Japanese Edition)

测试程序

有两个测试程序,A和B,其中进程A调用进程B。具体如下:

  程序B
  功能:建立一个线程来显示一个MessageBox,
       并且通过主线程的结束来关闭
       MessageBox。
------------------------------------------
主线程                   MsgBox显示线程
------------------------------------------
CreateThread();   -->    MessageBox(...);
Sleep(5000);             return 0;
return -1;
------------------------------------------

  程序A
  功能:每隔2秒启动一个B进程。
------------------------------------------
主线程
------------------------------------------
int main(int argc, char **argv)
{
    while (1) {
        CreateProcess(NULL, "B.exe", ...);
        Sleep(2000);
    }
    return 0;
}
------------------------------------------

问题出现

在运行程序A几小时后,将程序A结束。之后,令人惊奇的是,有几个程序B的进程并没有结束,反而占用了很高的CPU。

查找问题原因

【第一步:采dump并查看调用栈】
为了保存现场,赶快采了一个出现问题的B.exe进程的内存dump。然后利用Windbg进行dump的分析。
dump显示,问题B.exe的调用栈如下:
0:000> kb
ChildEBP RetAddr  Args to Child
0012fd10 77c3c350 00000000 0012fd54 1b7ca8e6 ntdll!NtDelayExecution
0012fd78 77bf1c7a 00000000 00000000 0012fda0 kernel32!SleepEx+0x62
0012fd88 74915648 00000000 00000001 00000000 kernel32!Sleep+0xf
0012fda0 748a592b 002e7440 748a5984 0012fe10 imjp10k!
CIImeGrammar::Terminate+0x1d
0012fda8 748a5984 0012fe10 748d73ab 74890000 imjp10k!TerminateGrammar
+0xf
0012fdb0 748d73ab 74890000 00000000 00000001 imjp10k!DllMain+0x36
0012fe10 77d0e1c4 74890000 00000000 00000001 imjp10k!_CRT_INIT+0x281
0012fe30 77cfa8dd 748d7524 74890000 00000000 ntdll!LdrpCallInitRoutine
+0x14
0012fed0 77cfa85f 0012feec 77c13b69 00000000 ntdll!LdrShutdownProcess
+0x1a9
0012fed8 77c13b68 00000000 77e8f3b0 ffffffff ntdll!RtlExitUserProcess
+0x64
*** WARNING: Unable to verify checksum for B.EXE
*** ERROR: Module load completed but symbols could not be loaded for
AVXMSGBOX.EXE
0012feec 004019c2 00000000 00000000 0040190a kernel32!ExitProcess+0x12
WARNING: Stack unwind information not available. Following frames may
be wrong.
0012fef8 0040190a 00000000 00000000 00000000 B+0x19c2
00000000 00000000 00000000 00000000 00000000 B+0x190a
结合B.exe的代码,可以看出该进程运行在main函数退出后的ExitProcess系统API中。我们知道,当一个进程结束时,它所使用的所有DLL都会被detach掉。估计B.exe在调用imjp10k.dll的DllMain函数时出现了问题。

【第二步:反汇编内核代码,并分析内存】
反汇编 imjp10k!CIImeGrammar::Terminate+0x1d 处的代码如下:
0:000> u 74915630 74915655
imjp10k!CIImeGrammar::Terminate+0x5:
74915630 53              push    ebx
74915631 56              push    esi
74915632 8b358c118974    mov     esi,dword ptr [imjp10k!
_imp__InterlockedExchange (7489118c)]
74915638 57              push    edi
74915639 bffc719374      mov     edi,offset imjp10k!g_pvIImeGram
(749371fc)
7491563e eb08            jmp     imjp10k!CIImeGrammar::Terminate+0x1d
(74915648)
74915640 6a00            push    0
74915642 ff15f0108974    call    dword ptr [imjp10k!_imp__Sleep
(748910f0)]
74915648 6aff            push    0FFFFFFFFh
7491564a 57              push    edi
7491564b ffd6            call    esi
7491564d 8bd8            mov     ebx,eax
7491564f 83fbff          cmp     ebx,0FFFFFFFFh
74915652 74ec            je      imjp10k!CIImeGrammar::Terminate+0x15
(74915640)
74915654 8b4d08          mov     ecx,dword ptr [ebp+8]
下面来分析一下上面的汇编代码:
74915632: 将InterlockedExchange函数地址放入esi寄存器中。
74915638: 保存edi
7491563e: 将g_pvIImeGram全局变量g_pvIImeGram(位于749371fc)放入edi中
7491563e: 转到74915648开始执行
74915640 to 74915642: 调用_imp__Sleep(0);
74915648 to 7491564b: 调用InterlockedExchange(g_pvIImeGram, -1);
7491564d to 74915652: 判断InterlockedExchange函数的返回值是不是-1,如果是-1就转到74915640开始执行。
查看g_pvIImeGram变量的值:
 0:000> dd 749371fc
749371fc ffffffff 00000000 00000000 00000000
7493720c 00000000 00000000 00000000 00000000
7493721c 00000000 00000000 00000000 00000000
7493722c 00000000 00000000 00000000 00000000

God! g_pvIImeGram变量的值是-1,因此,如果g_pvIImeGram的值一直没有变的话,从74915640到74915652将会有一个死循环。

结论

imjp10k.dll是微软日文输入法中的一个dll。在系统默认输入法是日文输入法的前提下,一个进程如果调用MessageBox函数,那么该dll就自动load到进程空间中。根据前面的调查情况来看,估计是imjp10k.dll的DllMain函数存在问题,也许是微软的一个bug。
阅读(606) | 评论(0) | 转发(0) |
0

上一篇:没有了

下一篇:ACM UVA (10007)

给主人留下些什么吧!~~