·汉化新世纪 ·汉化新世纪论坛 ·百家争鸣 ·论坛集萃 ·汉化问答 ·软件介绍
文章首页 >> 汉化教学 >> 特殊汉化 >> .net汉化系列之一——.net程序汉化初探    Creative Commons License,创作共用协议(中文版)  署名 非商业性使用 禁止演绎

.net汉化系列之一——.net程序汉化初探

作者: 雅枫 来源:汉化教学 时间:2004-09-29 点击:9723

      MS的.NET兴奋了程序员可苦恼了汉化界。虽然以前也想跟它过过招,但由于偶的硬盘小,总也舍不得装VS.NET,最近买了个大硬盘彻底解决了空间问题,以前一直不敢装的VS.NET也躺到了偶的硬盘中。于是乎拿着我的刀子杈子对着M$的得意之作一阵狂扁,虽然没有解决所有的问题,但也解决了部分问题,积累了一些经验,写出来跟大家分享一下。
说起这个.NET可真厉害,以前偶是钻研用MFC与SDK写程序的,偶尔也用用VB。这几天小试一下.NET不打紧,震撼之余还是震撼——这小伙做起界面来简直太简单了。比起delphi,bcb也有过之而无不及。佩服M$的天才之余也暗暗为Borland、java担心。废话休提,言归正传,先说第一个不是不算是发现的发现:这种程序中是有所谓的“字串池”的,也就是说所有的字串资源都是放在差不多同一个位置的,并且几乎所有的字串都是Unicode码的,虽然这个处理起来不如ASCII直观(直接支持U码的十六进制编辑器不多,并且大都十分难用)但至少不如Ascii字串那样容易超长,并且,由于字串连续存放,用CXA等抓取的字串也十分容易编辑,比较容易判断哪些是需要翻译的字串(注意:点晴字串替换器抓不出这类程序中的U码)我先说说.NET程序中U码字串的存放规则:
      如上图中的E&xit这个字串,本来是10个字节(U码一个字母占两个字节)第一个字节存放的长度标志是0B也就是十进制的11,所以在这类程序中字串的长度是包括长度标志在内的(这也可能是点晴抓不出字串的原因)。两个字串以一个00隔开(图中用红框框起来的那个00)令人兴奋的是,字串池是不包含任何可执行代码的,也就是说,只要汉化后的字串总长度不大于英文长度,理论上是可以通过用其他字串的多余字符来补足不够长的字串的(类似于汉化VB窗体,但又不像VB窗体那样是一个结构)并且据我猜测肯定是像VB中的U字串那样是通过地址指针来调用的,我试着做了一下,把前一字串的几个字节“借给”了后边的字串,发现后边字串显不出来了,肯定是调用地址出了问题!!!但这种程序的调用地址是如何计算的呢?还是以前的“乾坤挪移”中的算法?答案是否定的,因为按这种算法根本算不出正确的调用码,由于我对.NET的PE结构不熟悉,并且在家里没法上网,找不到相关资料,只能在硬盘上挖宝了,先试了微软自己的反汇编工具ildasm这个东东,发现是可以找出相关字串的调用码的,不过代码有点乱,也比较麻烦,其实如果你的硬盘上有Lord PE这个东东,你也就拥有了比较好用的分析工具:就是Misc目录下的MetaPuck.exe这个小工具,并且这是个绿色程序,即拷即用:)界面如下:
      其中User Strings这一项包含了所有的字串池中的字串,并且前边的那个0x700000001之类的字串就是相应的调用地址(具体如何算出有待研究,不过谁也可以看出来是70000000再加上字串第一个字节相对于首字串的偏移量,是不是70000000加上这个偏移量也有待考证,不过就我写的这几个小不点程序,全是70000000开始的)可以做如下试验:在我提供的例子程序中,用十六进制编辑器查找0D000070改成19000070在菜单中将出现两个New菜单项。
经过试验,我也成功的把&Exit,&Ok通过借字的方法成功汉化了,效果如下:
     以&Ok为例,先记下&Ok的调用码70000437,由于汉化后比原来要长4个字节,就向前边的"you click the redo"借用4个字节,同时修改两个字串的长度标志,然后用十六进制编辑器查找37 04 00 70,替换为33 04 00 70,保存,汉化成功,很可惜的是,无论是微软的ildasm还是MetaPuck,我机器上的版本都暂时还无法支持中文,我也懒得去diy它,谁有心去给作者们去封信,让他们自己搞定吧:)
      关于字体字号,我也说说一个不成熟的改法,字体名怎么改不用我说,直接翻译即可(最好是补00然后改长度)然后查找字体名调用码的逆序,找到后往后数4个字节就是字号的大小8号是04 41 。9号则是10 41,这个是怎么算的呢?实际上就是8.25跟9的浮点值,前者是41040000,后者是41100000,浮点转换偶不会,哪个高手写个转换器?,代码页(语系)则是再往后几个字节,但是,改语系除了用ildasm像以前的反汇编改法那样进行修改外,我觉得不会有更简单的修改方法,并且并不是所有的语系都能改,因为中文语系字体比西文语系压入语系一般要多用几个字节,所以,需要调整别处代码,省出一些空间,如果省不出就没法改,比较郁闷。变通的方法是把代码页0(ANSI_CHARSET)改成代码页1(DEFAULT_CHARSET),因为在字节码中,压入0跟压入1都是一个字节,压入86则需要5个字节,最少也要2个字节。另一个可能可行的方法是用不带语系参数的构造函数,可能就会使用默认语系吧,因为语系问题只在9x下才会出现,我没有98没法测试改法的正确性(btw:9x用户越来越少了,如果考虑放弃9x用户,则字体字号完全不必考虑)。至于控件的大小的调整。也是暂时除了反汇编外没有比较好的方法,因为.net程序似乎不是用一些结构来储存这些数据,而是根据设置的属性来生成代码,然后生成字节码,好在微软的ildasm还不是太难用。下边是OK按钮生成的代码的反汇编内容,有点乱,不过还是不难看出1F 60 1F 18这几个字节是设置按钮大小的。期待更好用的IL反汇编工具!最好直接能修改二进制文件^_^,至于反汇编代码,跟以前的代码不太一样,具体的语法及其2进制表示在Opcode类中,大家可以装个msdn2003参考一下,也可能不用装这个,只装.NET Framework SDK就有了。
IL_0057:  /* 72   | (70)000099       */ ldstr      "button1" /* 70000099 */
IL_005c:  /* 6F   | (0A)000023       */ callvirt   instance void [System.Windows.Forms/* 23000001 */]System.Windows.Forms.Control/* 0100001A */::set_Name(string) /* 0A000023 */
IL_0061:  /* 02   |                  */ ldarg.0
IL_0062:  /* 7B   | (04)00001B       */ ldfld      class [System.Windows.Forms/* 23000001 */]System.Windows.Forms.Button/* 01000009 */ hanzime.Form2/* 02000003 */::button1 /* 0400001B */
IL_0067:  /* 1F   | 60               */ ldc.i4.s   96
IL_0069:  /* 1F   | 18               */ ldc.i4.s   24
  IL_006b:  /* 73   | (0A)000024       */ newobj     instance void [System.Drawing/* 23000004 */]System.Drawing.Size/* 01000020 */::.ctor(int32,
                                                                                                                                          int32) /* 0A000024 */
 
     忘了说,反汇编后窗体控件初始化是在InitializeComponent这一项中。
     这是我短短几天之内搞出来的,难免挂一漏万,有些观点也许是错误的,高手们可以讨论一下,我也算为了引玉先抛块砖吧。这篇文章写的比较简略,原因一是偶打字太慢,二是父母为了保护俺那双半瞎的眼不让俺在计算机面前呆太长时间。如果有看不明白的地方可以到QQ群里问,也可以央高手们写篇详细一些的。附上我写的一个.NET程序,大家欺负着玩玩,用的是vs2003中的C#写的(不过就.net程序来说,什么语言写都一样只要不是用的VC7的MFC就可以),用户需要安装.NET Framework,应该在1.0与1.1两个版本下都能运行。最好装V1.1。
 

汉化新世纪 责任编辑: 乾 .:|:. 标签(Tag): NET 汉化 字串

·上一篇: 用pediy实现为程序添加对话框和网址的功能 ·下一篇: 快速简体化繁体VB程序心得

· 版权申明: 本文引自《汉化教学》,如有版权疑问请及时联系本站,以便本站处理。

· 转载申明: 本文引自《汉化教学》[ 作者: 雅枫],如需转载请直接联系原始作者,并请注明原始出处。

相关文章                                                                                发表评论 打印此文 关闭窗口

| 设为首页 | 加入收藏 | 联系我们 | 友情链接
Creative Commons License,创作共用协议(中文版)  署名 非商业性使用 禁止演绎
本站内容,除转载或版权特别申明的内容外,皆遵守 创造共用协议中文版之“署名-非商业性使用-禁止演绎 2.5 中国大陆”条款
This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 2.5 China License.
本网站内容源自汉化新世纪论坛的摘录和汉化新世纪成员的原创文章。
凡汉化新世纪论坛的文字皆默认为汉化新世纪与原作者共同拥有并授权发布。
如对本站发布文章有所异议请来信告知,我们将及时删除。
凡商业摘录本站文字请先与我们联系,本站将保留非授权商业发布的追究权利。
凡非商业摘录本站文字请明显注明出处和原作者,并不得改动,凡改动必先征求原作者同意。
苏ICP备05002283号