VOS1.0p字体补丁制作手记[noword]

VOS1.0p字体补丁制作手记

先说说我走的弯路,一开始我认为VOS是在韩文状态下编译的,所以他的进程(thread )的Local也是韩文的,那我只要把进程的Local改成中文的就可以了。在MSDN中查找,发现 有一个API正合我意:SetThreadLocale。但是VOS没用到SetThreadLocale,于是我修改 import表,插入了SetThreadLocale,再在代码段中插入代码去调用SetThreadLocale,都改好后,双击VOS运行……熟悉的韩文出现在我面前,当场晕倒。

说出我走过的艰辛的弯路,是为了告诉大家,一开始找对方向有多么重要。下面的正路要比弯路简单多了。

进入正题,我用的工具:W32Dasm用来静态反汇编,SoftIce用来动态跟踪,UltraEdit 用来编辑。

首先,当然是用W32Dasm反汇编VOS.exe,还好HanseulSoft没进行什么恶心的压缩加壳 ,轻松得到Vos的反汇编代码。我们是要做的是VOS字体补丁,字体的英文叫Font,搜索Font ,果然VOS用到CreateFontA这个函数,而且跟Font有关的就是只有这个函数。继续搜索 CreateFontA,发现VOS共用了两次CreateFontA,一次在0043DD0B,还有一次在0043DE17。

先看后面的那次调用:

:0043DDEF 50
push eax
//lpszFace
:0043DDF0 0FBF942490000000movsx edx, word ptr [esp+00000090] 
:0043DDF8 6A02push 00000002//fdwPitchAndFamily
:0043DDFA 6A00push 00000000//fdwQuality
:0043DDFC 0FBF84249C000000movsx eax, word ptr [esp+0000009C] 
:0043DE04 6A00push 00000000//fdwClipPrecision
:0043DE06 6A00push 00000000 //fdwOutputPrecision
:0043DE08 6A01push 00000001//fdwCharSet DEFAULT_CHARSET
:0043DE0A 6A00push 00000000 //fdwStrikeOut
:0043DE0C 6A00push 00000000//fdwUnderline
:0043DE0E 6A00push 00000000 //fdwItalic
:0043DE10 51push ecx //fnWeight
:0043DE11 6A00push 00000000//nOrientation
:0043DE13 6A00push 00000000//nEscapement
:0043DE15 52push edx//nWidth
:0043DE16 50push eax //nHeight
* Reference To: GDI32.CreateFontA, Ord:0036h  
|  
:0043DE17 FF1578104400 Call dword ptr [00441078] 

 

 

 

 

 













VC中函数的参数是倒着压入堆栈中的,所以看的时候要倒过来看,熟悉一下CreateFont这个 函数:

HFONT CreateFont(
int nHeight, // logical height of font
int nWidth, // logical average character width
int nEscapement, // angle of escapement
int nOrientation, // base-line orientation angle
int fnWeight, // font weight
DWORD fdwItalic, // italic attribute flag
DWORD fdwUnderline, // underline attribute flag
DWORD fdwStrikeOut, // strikeout attribute flag
DWORD fdwCharSet, // character set identifier
DWORD fdwOutputPrecision, // output precision
DWORD fdwClipPrecision, // clipping precision
DWORD fdwQuality, // output quality
DWORD fdwPitchAndFamily, // pitch and family
LPCTSTR lpszFace // pointer to typeface name string
);


跟国家有关系的是fdwCharSet这个参数,显然VOS把这个参数设成了HANGUL_CHARSET,所以在装了 韩文字体的Windows下,VOS会显示出韩文字。在VC的include目录中,搜索HANGUL_CHARSET ,在wingdi.h中有:
#define HANGUL_CHARSET 129

129的十六进制是81,而0043DE17的那次CreateFont的CharSet是1,1是DEFAULT_CHARSET,所以不是我们的目标。
再看第一调用:

 

:0043DCD2 50push eax//lpszFace
:0043DCD3 6A02push 00000002//fdwPitchAndFamily
:0043DCD5 83E180and ecx, FFFFFF80 
:0043DCD8 6A00push 00000000 //fdwQuality
:0043DCDA 6A00push 00000000//fdwClipPrecision
:0043DCDC 81C181000000 add ecx, 00000081// <---源头在这里
:0043DCE2 6A00push 00000000//fdwOutputPrecision
:0043DCE4 51push ecx//fdwCharSet <--- 犯人就是它!!!
:0043DCE5 6A00 push 00000000//fdwStrikeOut
:0043DCE7 6A00push 00000000//fdwUnderline
:0043DCE9 6A00push 00000000 //fdwItalic
:0043DCEB 52push edx//fnWeight
:0043DCEC 6A00push 00000000 //nOrientation
:0043DCEE 6A00push 00000000 //nEscapement
:0043DCF0 6A00push 00000000//nWidth
:0043DCF2 6A48push 00000048//nHeight
:0043DCF4 6A5Apush 0000005A 
:0043DCF6 57push edi 
* Reference To: GDI32.GetDeviceCaps, Ord:0125h  
|  
:0043DCF7 FF1534104400 Call dword ptr [00441034] 
:……  
:* Reference To: GDI32.CreateFontA, Ord:0036h  
:0043DD0B FF1578104400Call dword ptr [00441078] 
   


 

 

 

 

 

 

 

 

 

 









这次调用被VC优化过,参数都在前面设好了,GetDeviceCaps用到两个参数,倒推上去,可以看到CharSet是通过寄存器CX设置的,所以只要在前面

:0043DCDC 81C181000000 add ecx, 00000081

改成

mov ecx, 1

nop

就可以了。

当我第一次在SoftIce里改好后进入VOS,看到熟悉的中文,兴奋之情难于言表。

2003-08-30  

by noword (欢迎转载传阅)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值