修改过程 我修改的过程比较繁琐,所以在这里剔除复杂的部分,简单的说。 首先,使用 W32dasm 反汇编汉化后的 CTris2000.exe ,存盘,打开 CTris2000.alf 文件,查找 CreateFont ,发现只有 CreateFontIndirectA ,而没有 CreateFontA ,这真是一个烦人的开始。继续查找,发现 CreateFontIndirectA 被三个地方调用,地址分别是 4124EC 、420460 和 42A7F3 。 运行 Trw2000 ,调入 CTris2000.exe ,然后键入“bpx 4124EC”、“bpx 420460” 和 “bpx 42A7F3”设置断点,按“F5”运行,中断时键入“dd *esp”查看堆栈的栈顶指针所指的地址的内容,发现大多数情况此地址的开头都是“FFFFFFF4”,也就是“-12”,是正常的,不过有一次,它是“FFFFFFF5”,也就是“-11”,在它下面一点,我们见到了这种字体的名称“MS Sans Serif”。 用 ResHacker 检查 CTris2000.exe ,发现并不是所有的“MS Sans Serif,8”都被改成了“宋体,9”,所以首先把这些没有改成“宋体,9”的项都改成“宋体,9”,存盘。 用 UEdit 打开 CTris2000.exe ,查找“MS Sans Serif”,只有一个,在 0x5b0b8 处,为了验证,把这个“MS Sans Serif”改成“System”,运行程序,发现那个输入窗体的字体确实如我们所想的变成“宋体,12”了。 0x5b0b8 在数据段,所以,数据基偏移 = 基地址 + 数据RVA - 数据Offset = 400000h + 5c000h - 5ae00 = 401200h ,所以,0x5b0b8 的在代码中为 401200h + 5b0b8 = 45C2B8h 。在 CTris2000.alf 查找“0045C2B8”,没找到,那么,查找“0045C2B”吧,找到几处,如“0045C2B7”、“0045C2B6”和“0045C2B0”,很是奇怪。 运行 Trw2000 ,调入 CTris2000.exe ,像上面一样设断点,运行到有问题的 CreateFontA 的时候,键入“dd 0045C2B0”,看看是什么?原来是“FFFFFFF5”!好吧,把“0045C2B0”当作突破口。 打开 CTris2000.alf ,查找“0045C2B0”,发现两个地方,代码如下: * Referenced by a CALL at Address:|:0041979B |:00419604 53 push ebx:00419605 56 push esi:00419606 57 push edi:00419607 6A48 push 00000048:00419609 A1D0E54500 mov eax, dword ptr [0045E5D0]:0041960E 50 push eax:0041960F 6A08 push 00000008* Reference To: kernel32.MulDiv, Ord:0000h |:00419611 E836BEFEFF Call 0040544C:00419616 F7D8 neg eax:00419618 A3B0C24500 mov dword ptr [0045C2B0], eax:0041961D A13CD64500 mov eax, dword ptr [0045D63C]:00419622 80780800 cmp byte ptr [eax+08], 00:00419626 743A je 00419662:00419628 E893FFFFFF call 004195C0:0041962D 8BD8 mov ebx, eax:0041962F 8BC3 mov eax, ebx:00419631 2C80 sub al, 80:00419633 752D jne 00419662:00419635 BE68964100 mov esi, 00419668:0041963A BFB7C24500 mov edi, 0045C2B7:0041963F B904000000 mov ecx, 00000004:00419644 F3 repz:00419645 A5 movsd:00419646 6A48 push 00000048:00419648 A1D0E54500 mov eax, dword ptr [0045E5D0]:0041964D 50 push eax:0041964E 6A09 push 00000009* Reference To: kernel32.MulDiv, Ord:0000h |:00419650 E8F7BDFEFF Call 0040544C:00419655 F7D8 neg eax:00419657 A3B0C24500 mov dword ptr [0045C2B0], eax:0041965C 881DB6C24500 mov byte ptr [0045C2B6], bl* Referenced by a (U)nconditional or (C)onditional Jump at Addresses:|:00419626(C), :00419633(C)|:00419662 5F pop edi:00419663 5E pop esi:00419664 5B pop ebx:00419665 C3 ret
不知道大家是否能大概看懂上面的代码,不过它和我在《C 程序字号的修改》里摘抄的 MSDN 里建议的设置字号的方式是基本一样的: nHeight = -MulDiv(PointSize, GetDeviceCaps(hDC, LOGPIXELSY), 72);
我们可以看到,“0041960F”处的“6A08”压入的就是磅值,我们需要的是 9 磅的字体,所以把“6A08”改成“6A09”就可以了。代码基偏移 = 基地址 + 代码RVA - 代码Offset = 400000h + 1000h - 400h = 400c00h ,41960fh - 400c00h = 18a0fh ,也就是说“6a08”在 0x18a0f 处。 所以,最后的修改是这样的:把 0x5b0b8 处的 "MS Sans Serif" 改成 "宋体";把 0x18a0f 处的 6a08 改成 6a09 。 虽然我已经简化了过程,不过好像还是很麻烦,那么有没有什么简单的方法呢?有的。 一、如果实在不会这样的修改方法,也不要留着,把“MS Sans Serif”改成“System”是一种简单有效的方法,遗憾的是字体显得比较大。 二、先把“MS Sans Serif”改成“宋体”,然后用 W32dasm 反编译汉化后的程序并存盘后,用 EmEditor 打开 *.alf 文件,按“Ctrl+F”,出现查找对话框,选择“使用表达式”,在要查找的文本中输入“push 00000008* Reference To: kernel32.MulDiv,”,找到的不会很多,把“08”修改成“09”试一试,直到得到正确的结果。 需要注意,第二种方法只适用于 Delphi 程序的 InputBox 的字体修改,而第一种方法适用于所有程序。另外,我因为没有见到其它类似的 Delphi 程序,也不能肯定第二种方法就是对的,如果各位有见到,不妨一试。
|