菜鸟DIY---为计算器增加退出动画效果
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
【文章标题】: 菜鸟DIY---为计算器增加退出动画效果
【文章作者】: stalker
【作者邮箱】: zhangke_1989 at hotmail dot com
【软件名称】: calc.exe
【下载地址】: 系统目录
【操作平台】: Windows XP SP2
【作者声明】: 只是感兴趣,没有其他目的。
失误之处敬请诸位大侠赐教!
--------------------------------------------------------------------------------
【详细过程】
学校的校园网慢得可以。
以前我一直天真地认为,无法打开网页只有在掉线时才会发生,现在我终于醒悟了。
在电脑面前呆得实在是无聊,再次拿计算器来开刀,这次的目的是让它在退出的时候有点动画效果。
首先介绍一个Windows API,名为AnimateWindow,熟悉的可以跳过了。
它的原型如下:
BOOL AnimateWindow(HWND hwnd,DWORD dwTime,DWORD dwFlags);
MSDN对这个函数做了如此阐述:The AnimateWindow function enables you to produce special effects when showing
or hiding windows. There are four types of animation: roll, slide, collapse or expand, and
alpha-blended fade.
简单的说就是该函数可以让你在显示或隐藏窗体的时候产生特别的效果,共有四种类型的动画。
参数hwnd是需要产生特效的窗口句柄,dwTime为动画持续时间,dwFlags代表使用何种动画。
主角介绍完了,下面正式开始------------------------------------>
大家都知道,要进行DIY,首先得找对地方,我们要在计算器退出的时候产生一个动画效果,肯定得找到处理WM_CLOSE
消息的地方。
OD载入calc.exe,右键->查找->所有分支,然后在任意一分支上点右键->列出switch的case 列不了几次,我们就会找到,如图一所示
19941
双击WM_C LOSE,就会来到相应的代码处
可能聪明的你会发现,在另一个case中也出现了WM_C LOSE,如图二
19942
哪一个才是我们想找的呢?下个断点试试吧,分别双击来到各自代码处,然后下断,运行程序,再点X关闭程序,断在哪个点哪个点就是了(^_^)
实验证明,图一那个case是目标,点击它,来到这里
0100623F |> \A1 744D0101 mov eax, dword ptr [1014D74] ; Case 10 (WM_C LOSE) of switch 01006124
01006244 |. 33DB xor ebx, ebx
01006246 |. 3BC3 cmp eax, ebx
01006248 . /74 11 je short 0100625B
0100624A . |53 push ebx ; /lParam => 0
0100624B . |53 push ebx ; |wParam => 0
0100624C . |6A 10 push 10 ; |Message = WM_CLOSE
0100624E . |50 push eax ; |hWnd
0100624F . |FF15 3C110001 call dword ptr [<&USER32.SendMessageW>; \SendMessageW 01006255 . |891D 744D0101 mov dword ptr [1014D74], ebx
0100625B > \FF35 6C4D0101 push dword ptr [1014D6C] ; /hWnd = NULL
01006261 . FF15 78110001 call dword ptr [<&USER32.DestroyWindo>; \DestroyWindow
哈哈,我们只要把0100623F处的代码改为一个跳转,跳到我们自己的地方,然后再跳回来就可以了
现在就开始写我们自己的代码了吗?请别着急,还有一个问题,Anima teWindow函数的第一个参数是窗口句柄,我们如何
得到计算器的主窗口句柄呢?在上一次DIY的时候我使用的方法是GetForegroundWindow来获得的,因为我实在没有想出更好的
方法,该方法不能够保证万无一失。
这次我们有很好的条件(^_^),请注意观察上面代码中0100625B处的代码
0100625B > \FF35 6C4D0101 push dword ptr [1014D6C]
压入的是DestroyWindow函数的参数,而该参数就应当是计算器的主窗口句柄
稍微有经验的人都应该知道[1014D6C]相当于一个全局变量吧
由于我们要在0100623F处就让程序跳走,因此先在0100623F处下一个断点,运行程序,用Spy++获得主窗口句柄,
点X关闭程序,断下来之后,在命令行输入D 1014D6C,观察存储的值是否与Spy++获得的窗口句柄一致。
事实证明,果然是
一致的(^_^)
下面开始找地方写代码了,我找了010002ED这个地方,由于计算器并没有导入AnimateWindow这个华丽的函数,因此需要用工具
或者手动增加导入函数。
而我选择的是在代码中使用LoadLibrary&GetProcAddress这一黄金搭档来动态获得该函数的地址,
具体代码如下
010002ED 60 pushad ;保存寄存器
010002EE 68 6C6C0000 push 6C6C
010002F3 68 33322E64 push 642E3233
010002F8 68 75736572 push 72657375
010002FD 8BC4 mov eax, esp
010002FF 50 push eax
01000300 FF15 24100001 call dword ptr [<&KERNEL32.LoadLibrar>; kernel32.LoadLibraryA 01000306 6A 77 push 77
01000308 68 696E646F push 6F646E69
0100030D 68 61746557 push 57657461
01000312 68 416E696D push 6D696E41
01000317 8BDC mov ebx, esp
01000319 53 push ebx
0100031A 50 push eax
0100031B FF15 28100001 call dword ptr [<&KER NEL32.GetProcAdd>; kernel32.GetProcAddress 01000321 68 08000100 push 10008 ; 动画效果为从下往上收拢
01000326 68 B80B0000 push 0BB8 ; 动画时间为3000ms
0100032B FF35 6C4D0101 push dword ptr [1014D6C]
01000331 FFD0 call eax
01000333 83C4 1C add esp, 1C ;平衡堆栈
01000336 61 popad ;恢复寄存器
01000337 A1 744D0101 mov eax, dword ptr [1014D74] ;原来的这行代码被修改为跳转了
0100033C - E9 035F0000 jmp 01006244 ;跳回原来的位置继续执行
最后再把
0100623F |> \A1 744D0101 mov eax, dword ptr [1014D74]
修改为
0100623F >-\E9 A9A0FFFF jmp 010002ED
就大功告成了,最后保存到可执行文件试试吧
附上一个正在收拢的计算器
19943
附件中包含我修改好的计算器
19944
--------------------------------------------------------------------------------
【经验总结】
本来想在启动的时候也弄一个效果,无奈太菜,没有弄出来,改天再想想。
如果哪位朋友弄出来了,一定分享下(^_^)
1点早已过去,终于能够打开网页了,心情无比舒畅,可惜身体无比疲劳......
--------------------------------------------------------------------------------
【版权声明】: 本文原创于看雪技术论坛, 转载请注明作者并保持文章的完整, 谢谢!
2008年11月01日1:41:22。