Yahoo Messenger 是一个很不错的IM软件。但是它是用了一个非常陈旧的Windows Hook功能,因此制造了一个idle.dll 用来来检测用户的发呆时间。这个IDLE.DLL 文件看起来并不大,只有6k,其实它是一个用VC7.1编译产生的动态链接库并且动态链接到MSVCR71.DLL。 由于HOOK函数需要把 IDLE.DLL 注入到所有的用户程序中,MSVCR71.DLL 也会被注入到所有的用户程序中。 而且这个IDLE.DLL 会进入所有用户程序的消息循环。在所有的程序中都有这个 idle.dll 实在是让人不爽。 ;)
Let's check the IDLE.DLL
下面就让我们看看这 IDLE.DLL
C:\Program Files\Yahoo!\Messenger>dumpbin /exports idle.dll
Microsoft (R) COFF/PE Dumper Version 8.00.50727.42
Copyright (C) Microsoft Corporation. All rights reserved.
Dump of file idle.dll
File Type: DLL
Section contains the following exports for idle.dll
00000000 characteristics
450867C8 time date stamp Thu Sep 14 04:19:20 2006
0.00 version
1 ordinal base
3 number of functions
3 number of names
ordinal hint RVA name
1 0 00001016 ?IdleUIGetLastInputTime@@YAKXZ
2 1 000010C3 ?IdleUIInit@@YAHXZ
3 2 0000111C ?IdleUITerm@@YAXXZ
Summary
1000 .data
1000 .rdata
1000 .reloc
1000 .rsrc
1000 .text
1000 Y_IDLE
It has 3 C++ functions defined, and a customized data section "Y_IDLE", I think it is the shared data section which used to store the latest user active time stamp. While what's the function protocol for these 3 function? I found a very good documentation for the C++ name mangling of different compilers at URL http://www.agner.org/optimize/ Calling conventions for different C++ compilers and operating systems
它定义了三个输出函数,同时自定义了一个程序段 Y_IDLE 相比这应该是一个数据段,用来记录从各个应用程序收集到的最新的用户消息发出的时间。 而这三个函数应该是用C++的命名规则输出的,但是这三个函数的原型是什么呢?幸好发现了一个非常好的文档,详细地描述了各种编译器的 C++ name mangling 也就是符号标的转换规则。参见 http://www.agner.org/optimize/ Calling conventions for different C++ compilers and operating systems
In fact, from the Windows 2000, WIN_VER>=0x500 there is a new function GetLastInputInfo in user32.dll, it will provide the Last user input time stamp quickly.
其实从Window2000开始,微软在 User32.dll 就提供了一个新的函数 GetLastInputInfo 它就可以用来返回用户的最后输入的时间。
/**
* This is used to hack the Yahoo Messenger.
* compiled with VC7.1 as:
* cl -W3 -O1sy -LD -MD -D_WIN32_WINNT=0x0500 idle.cpp -Feidle.dll User32.lib
*/
#include
#pragma section("Y_IDLE",read,write)
__declspec(allocate("Y_IDLE"))
int Y_IDLE = 0;
#define DllExport __declspec( dllexport )
DllExport DWORD IdleUIGetLastInputTime()
{
LASTINPUTINFO lii;
lii.cbSize = sizeof(lii);
GetLastInputInfo(&lii);
return lii.dwTime;
}
DllExport INT IdleUIInit()
{
return TRUE;
}
DllExport VOID IdleUITerm()
{
return;
}
This will be able to create a new IDLE.DLL
这样就可以知道一个新的 idle.dll , 而且它也再也不会被注入到其他的程序中了。
替换原来的 IDLE.DLL 还真不错~~~~ 工作正常。
写在后面
在找到 IDLE.DLL 输出函数的原型还真花了些时间。后来才发现其实微软已经给我们提供了一个很方便的工具,那就是随Platform SDK 分发的 Dependency Walker (depends.exe) 里面有一个 Undecorate C++ functions 的功能,我们只需要用Dependency Walker 打开 IDLE.DLL 就可以看到输出函数的原型了。
其实
没有评论:
发表评论