背景:
一同事提到某客户要求修改产品程序中的一段文字,正常情况下这是很简单的事情,不需要我这业余人员参与,但问题在于该客户使用的是旧版本产品,而旧版本产品的代码已遗失,这种情况下修改文字就成了一个棘手的工作。几经辗转这个事情就找到了我这里,受不了同事再三托付,我答应其试试。
该程序使用.net 2.0开发。
目的:
需要修改的为一C/S客户端界面,在界面中某个label处(假设原文字为“服务器123!”)增加一段文字描述(假设为“新增服务器”),使程序可正常运行,兼顾美观性。
工具手段:
google、UE、.Net Reflector8.1、ildasm、.net framework2.0、自编汉字转码工具(javascript)
准备工作:
利用google下载上面提到的几个工具,并掌握各个工具的使用方法,我这里大概说说各个工具的用途:
.Net Reflector8.1很有用的工具,可以查看.net编译程序的源码格式,用于了解程序的编制思路及寻找修改方式;
ildasm.exe可以将.net编译的可执行程序(dll、exe)反汇编为il中间格式,该格式可使用ue进行编辑修改;
UE我喜爱的工具,全称ultraedit,超好用的文本编辑工具,支持hex格式编辑;
.net framework2.0我们修改后的il文件需要依托.net framework2.0进行再次编译,才能形成可执行文件,其实主要使用ilasm.exe;
自编汉字转码工具,这个是我为了方便自己写的转换工具,做得事情不复杂,主要是将字符尤其是中文转换为unicode编码,再将unicode编码转换为il文件中的中文编码(去掉\u、将双字节的高低位互换);大家也可以手工转,在网上搜索unicode在线编码转换将字符转换unicode编码,手工去掉\u,再将双字节高低位互换。(我会单独写文章把这个工具与大家共享的)。
因为不确定客户使用的哪个小版本产品,所以我让同事从客户处把程序直接拷贝给我了。
修改步骤
相关准备工作做完后就要开战了。
1、首先出场的当然是.Net Reflector8.1了
将需要修改的程序文件(如果有多个文件不确定是哪个的话就需要都托付给reflector反编译先),通过Reflector查找文字“服务器123!”,这样可快速定位这个界面的源码位置,通过读源码我们知道了这个界面上有哪些控件,哪些控件与我们待修改的内容有关。
2、轮到二号人物出场了ildasm.exe
打开ildasm.exe,将待修改的程序文件拖放到该程序,选择转存为123.il文件,转存时注意选择utf-8编码,关键人物的出场都是短暂的,短暂但确很重要。
3、三号人物UE出场
使用UE打开123.il,这个地方我走了我弯路,在UE中直接找中文“服务器123!”,找了N遍都没有,后来google了很久,找到有专家说要转成unicode编码,到网上找工具将服务器123!转成了unicode编码,直接按照转换的16进制搜索,还是找不到,当时俺那个崩溃呀,心想难道不在123.il,后来又查找123.res(也是ildasm.exe的产物),但都是徒劳无货。后来在UE和reflector中反复走查代码,俺终于发现了规律。原来il文件中又对unicode编码进行了双字节高低位互换,这个折磨人的编码问题呀。还是给同学们展示个实例吧:
中文:服务器 unicode编码:\u670D\u52A1\u5668 il编码:0D 67 A1 52 68 56
4、编写汉字转换工具
我比较懒或者说不喜欢做重复工作,我一想到要一个一个汉字的转编码、调顺序,而且客户要加的文字还不少,那个头疼啊。一怒之下为配合三号人物完成工作俺连夜编写了一个html页面(使用javascrip脚本)用于转换汉字编码,好久不写代码了,N多生疏,心里默默感激google与大众的分享,让俺能完成这个小小工具。
5、UE继续出场
工具有了就好办多了,首先通过工具将原始文字“服务器123!”转换为il编码(暂且这么叫吧),在UE中查找,OK一查即中,鼠标停留在字符串结束位置,将待增加文字“新增服务器”转换为il编码,直接在UE中粘贴即可(服务器123!之后),这样文字修改就可以了。
6、.net framework2.0出场
第五步我们只是把程序中间格式文件修改好了,但还不是可执行程序,要编译出.net 2.0的程序当然还得使用它本身了,但il的编译需要使用的是ilasm.exe。
该命令需要在cmd窗口中执行,打开cmd,切换到il文件所在目录下,执行如下命令:c:\Windows\Microsoft.NET\Framework\v2.0.50727\ilasm.exe 123.il /output=123.exe /res:123.res /exe
其中c:\Windows\Microsoft.NET\Framework\v2.0.50727\ilasm.exe为ilasm.exe的路径;123.il为我们修改后的il文件;/output=123.exe指我们要输出的文件名称;/res:123.res表示要将对应的资源文件也编译到程序中;/exe为输出的文件格式为exe,如果原始文件dll的,则需要使用/dll
这一步俺也走了弯路,大家不要走呀,我第一次运行命令的时候,没有带/res参数,导致编译出来的exe文件没有应用程序图标.
编译成功后,目录下会生成123.exe文件
7、测试
对于编译的123.exe,打开运行观察是否是期望的结果。如果你幸运修改的文字较少不影响控件美观性,那么本次任务就圆满结束了。但我很不幸运,增加的文字较多,导致在lable中文字显示不全。所以俺还需要附带赠送如下步骤。
8、调整控件位置及大小
在reflector中找到对应控件,找到其location、size设置的大小,还发现该控件的autosize为true,这是不行的,需要修改为false,我们才能调整他的大小。
在UE中查找对应位置,可按照控件方法名定位,数字可能涉及16进制转换,在修改时要注意。
IL_025a: ldc.i4.1 //需要修改为ldc.i4.0,表示false
IL_025b: callvirt instance void [System.Windows.Forms]System.Windows.Forms.Control::set_AutoSize(bool) //设置autosize
修改控件size大小
IL_02be: ldc.i4 0xdb //长度 按照需要修改吧
IL_02c0: ldc.i4.s 30 //高度 按照需要修改吧
IL_02c2: newobj instance void [System.Drawing]System.Drawing.Size::.ctor(int32,
int32)
修改完成后,重复6、7步骤,直到控件位置调整正常。
9、完工
将程序发给客户验证,OK!
此次任务完工。