完成后按确定保存我们所做的工作,运行一下修改后的程序,呵呵,终于把字体改过来了:
如果你运行出错也没关系,用 OllyDBG 调试一下你修改后的程序,看看错在什
么地方。这一般都是输入补丁代码时造成的,你只要看一下你补丁代码运行的情况就可以了。到这里我们的任务似乎也完成了,但细心的朋友可能会发现补丁代码1和补丁代码2前面的代码基本上是相同的。一个两个这样的补丁还好,如果要是多的话,这样重复就要浪费不少空间了,况且工作量也相应加大了。既然前面有很多代码都是重复的,为什么我们不把这些重复的代码做成一个子程序呢?这样调用起来要方便的多。下面我们把前面的补丁代码修改一下,我们先把补丁代码1的代码改成这样:
0040A43E 60 PUSHAD ; 保护现场
0040A43F A3 6EC54000 MOV DWORD PTR DS:[40C56E],EAX ; 保存窗口句柄
0040A444 68 15A44000 PUSH myuninst.0040A415 ; 我们建的LOGFONT对应指针
0040A449 FF15 44B04000 CALL DWORD PTR DS:[<&GDI32.CreateFontIndirectA>] ; GDI32.CreateFontIndirectA 0040A44F 6A 00 PUSH 0 ; lParam 参数留空 0040A451 50 PUSH EAX ; 字体句柄
0040A452 6A 30 PUSH 30 ; WM_SETFONT
0040A454 8B0D 6EC54000 MOV ECX,DWORD PTR DS:[40C56E] ; 窗口句柄 0040A45A 51 PUSH ECX ; 窗口句柄压栈 0040A45B FF15 3CB24000 CALL DWORD PTR DS:[<&USER32.SendMessageA>] ; USER32.SendMessageA 0040A461 61 POPAD ; 恢复现场 0040A462 C3 RETN ; 返回
这样我们的子程序代码就写好了。现在我们再在子程序代码后面写上两个补丁代码,当然不要忘了改前面原程序中的跳转:
修改后的补丁代码1:
0040A467 E8 D2FFFFFF CALL myuninst.0040A43E ; 调用子程序 0040A46C 6A 00 PUSH 0 ; 恢复前面修改过的代码
0040A46E 8945 F4 MOV DWORD PTR SS:[EBP-C],EAX
0040A471 ^ E9 F3EAFFFF JMP myuninst.00408F69 ; 返回继续执行
修改后的补丁代码2:
0040A47A E8 BFFFFFFF CALL myuninst.0040A43E
0040A47F 8945 F0 MOV DWORD PTR SS:[EBP-10],EAX 0040A482 8B45 F8 MOV EAX,DWORD PTR SS:[EBP-8] 0040A485 ^ E9 13EBFFFF JMP myuninst.00408F9D
我在每个补丁代码片断间留了4个字节来分隔。同样,我们还要修改一下我们前面的跳转: