Skip to content

RUNUO服务器分析心得 第三章——进入Main函数

RUNUO服务器分析心得 第三章——进入Main函数 published on RUNUO服务器分析心得 第三章——进入Main函数有91条评论

        好了,接上篇。进入到Main后,我们来看看里面到底在作写什么?首先提醒一下各位朋友,如果不是很懂IL呢,还是最好找些资料来看看了,我呢是边看边分析边写,如果大家有时间可以系统的学学IL,只有好处没坏处的。

        上章中带领大家一起进入了Runuo.il的调试工作,众所周知,控制台程序有有一个Main函数,通过IL代码搜索,我们发现Main函数是在Server命名空间Core类里面,至于什么是命名空间和类的概念我就不多解释了。

 

.method public hidebysig static void
Main(string[] args) cil managed
{
.entrypoint // 这里看到没有,这代表是入口点的意思啦,证明我们没有找错喔。
.custom instance void [mscorlib]System.STAThreadAttribute::.ctor() = ( 01 00 00 00 )

        好了,不废话了,顺着这个函数往下看,看到这里IL_019d,我发现了一个关键字,这个是我最关心的东西了:

      IL_019c:  ldloc.0
      IL_019d:  call       bool Server.ScriptCompiler::Compile(bool) //这里,有个Script
      IL_01a2:  brfalse.s  IL_016c

        灵感告诉我,这里面一定有我关心的问题。看代码来看,这里调用了ScriptCompiler的一个成员函数,看到前面哪个Server.了么?也是Server命名空间里的啊。解下来我们找ScriptCompiler类的带参数的Compile方法

     .method public hidebysig static bool
            Compile(bool debug) cil managed //就是它拉
    {
      // 代码大小       564 (0x234)
      .maxstack  4
      .locals (class [System]System.CodeDom.Compiler.CompilerResults V_0,
               class [System]System.CodeDom.Compiler.CompilerResults V_1,
               int32 V_2,
               class [mscorlib]System.Collections.ArrayList V_3,
               class [mscorlib]System.Type[] V_4,
               int32 V_5,
               class [mscorlib]System.Reflection.MethodInfo V_6,
               int32 V_7,
               class [mscorlib]System.Type[] V_8,
               int32 V_9,
               class [mscorlib]System.Reflection.MethodInfo V_10,
               int32 V_11)

        找到后,看下面的代码,很多,不过别着急慢慢来,直到看到这里:

      IL_004d:  ldarg.0
      IL_004e:  call       class [System]System.CodeDom.Compiler.CompilerResults Server.ScriptCompiler::CompileCSScripts(bool)
      IL_0053:  stloc.0

        看这个函数名字大家都知道它在做什么了吧,编译.cs文件啊,还带了个参数,不管它老办法,搜索这个函数:

      method private hidebysig static class [System]System.CodeDom.Compiler.CompilerResults
            CompileCSScripts(bool debug) cil managed
    {
      // 代码大小       447 (0x1bf)
      .maxstack  5
      .locals (class [System]Microsoft.CSharp.CSharpCodeProvider V_0,
               class [System]System.CodeDom.Compiler.ICodeCompiler V_1,
               string[] V_2,
               string V_3,
               class [System]System.CodeDom.Compiler.CompilerResults V_4,
               int32 V_5,
               int32 V_6,
               class [System]System.CodeDom.Compiler.CompilerError V_7,
               class [System]System.CodeDom.Compiler.CompilerError V_8,
               class [mscorlib]System.Collections.IEnumerator V_9,
               class [mscorlib]System.IDisposable V_10,
               object[] V_11)

        好啦,主角上场,这个函数里有我们最关心的东西……

原创文章,转载请注明: 转载自游戏无界·达秀的黑暗空间

本文链接地址: RUNUO服务器分析心得 第三章——进入Main函数

本站作品除特殊申明外均为原创,采用知识共享署名-非商业性使用-禁止演绎 3.0 Unported许可协议进行许可。如果需转载请保持文章完整性和标明原文出处,禁止商业用途。

RUNUO服务器分析心得 第二章——基于IL代码的调试

RUNUO服务器分析心得 第二章——基于IL代码的调试 published on RUNUO服务器分析心得 第二章——基于IL代码的调试有79条评论

        首先用上次反编译的代码生成需要调试的EXE文件,当然因为要做调试,所以必须要用DEBUG模式来生成EXE,DEBUG模式生成的EXE文件要比原来的大一些,而且同时还会生成一个.pdb文件。还是在.NET命令环境下键入如下命令:ilasm runuo.il /resource:runuo.res /debug OK,看看目录下是不是多了一个runuo.pdb文件?而且runuo.exe的大小变成了436 KB (446,464 字节)。

好了,下面准备好CLR调试器,CLR调试器的位置在.NET Framework SDK目录下\v1.1\GuiDebug\目录里,名字叫DbgCLR.exe,它是一个图形界面的帮助开发者调试的程序。现在打开它,然后载入,我们最早反编译出的runuo.il文件,如下图:

o_clrdebug

        然后选择 调试->要调试的程序 弹出一个对话框,在里面填好类容,如下图:

o_debug dlg

        确定后,你会发现在CLR调试器里的那个代表调试开始的那个深蓝色三角形箭头可以用了。

        接下来,在il代码里,找到Main函数位置,在里面代码开始处打上断点,然后运行调试,看是断点是否命中,如果成功回出现下面的界面:

o_main stop

        注意,断点一定要打在IL_XXXX的地方,其他地方有可能不能命中喔。如果不能命中,请检查一下前几步是不是出了什么问题。好了,将在下章进入MAIN函数分析IL代码。

本站作品除特殊申明外均为原创,采用知识共享署名-非商业性使用-禁止演绎 3.0 Unported许可协议进行许可。如果需转载请保持文章完整性和标明原文出处,禁止商业用途。

RUNUO服务器分析心得 第一章——RUNUO的反编译

RUNUO服务器分析心得 第一章——RUNUO的反编译 published on RUNUO服务器分析心得 第一章——RUNUO的反编译有102条评论

        因为在分析RUNUO程序之前,因为没有源代码,所以首先要对RUNUO.EXE进行反编译。.NET程序反编译出来的结果并非反汇编代码,而是MSIL代码,即微软中间语言代码。虽然看起来很头疼,总比看反汇编要强得多了,而且根据中间代码可以手动翻译成和源代码类似的代码。这就需要时间了。

        反编译.NET程序其实不需要外部工具,.NET Framework 的SDK里提供了一个工具,名字叫ildasm.exe具体位置在.NET SDK目录\.NET版本目录\BIN\ 下。运行它,然后选择菜单 文件->打开 出现下面这个界面:

 o_ildasm_runuo

        通过它你可以将所有的IL代码导出到一个文件里,现在选择 文件->转储 就会弹出一个对话框,见下图:

 o_ildasm_save

        更改完设置后,点确定就会让你选择保存路径,建议大家保存成.il的格式。

        保存完后,看看保存的目录下一个有两个文件,一个叫RunUO.il 另一个叫RunUO.res。

        如果你不是很相信ILDASM的能力,那么下面我们把中间码编译还原到EXE看看有没有字节损失。现在进入.NET的命令行模式,就是类似cmd的窗口,不过它里面有.NET的工作路径,很多命令可以直接调用。通过cd命令进入到刚才反编译的文件目录,然后输入如下命令:ilasm runuo.il 回车。屏幕停止滚动后如果发下如下字样就说明成功了:Writing PE file  Operation completed successfully。进入目录发现多了一个RunUO.exe文件,看看大小,428 KB (438,272 字节) 好像不对啊,原文件大小是432 KB (442,368 字节)啊,怎么回事???喔,不要着急,想想刚才反编译出来的文件不是还有一个.res的资源文件么,没有用上啊。好,再来一次输入命令:ilasm runuo.il /resource=runuo.res 回车。一看啊,果然,这次没错了。成功还原,而起runuo.exe的图标也对了。那么准备开始进一步工作吧……

原创文章,转载请注明: 转载自游戏无界·达秀的黑暗空间

本文链接地址: RUNUO服务器分析心得 第一章——RUNUO的反编译

本站作品除特殊申明外均为原创,采用知识共享署名-非商业性使用-禁止演绎 3.0 Unported许可协议进行许可。如果需转载请保持文章完整性和标明原文出处,禁止商业用途。

RUNUO服务器分析心得 第零章——序章

RUNUO服务器分析心得 第零章——序章 published on RUNUO服务器分析心得 第零章——序章有79条评论

UO-SA_ankh_standard        已经很久没上ICQ了,今天忽然兴起,挂上ICQ(免费那种)。觉得不过瘾,索性QQ,MSN Messager能开的都开了。刚开完MSN Messager,一则消息从ICQ上传来:

        James:Hello,我是James,最近过的好么?很久没看见你了。
(本来是E文的为了大家看着方便,写着也方便就干脆用中文直接写出来了,一直有个感觉,老外问候不太像我们。我们一般是HI过来,然后HI回去,他们一般不,也许关系还没到位吧。一番问候之后,开始入正题了。)

        James:Richard,你最近忙什么,还在碰UO么?我最近在玩RUNUO,挺不错的,你没有么?
(其实不是玩的意思,应该是研究的意思)

        我想:UO?晕哦,大概3、4年没碰了。亏你精神那么好~~~,老外给我一个感觉就是执着。做什么事都不轻易就放弃。     
   
        我:很长时间没有了。怎么样,UO服务端技术还是那样么?

        James:不是了,以前UOX占主导地位,现在基本都少了,很多都在玩RUNUO了。
(以前国内用TUS系列后来叫SPHERE比较多,国外不一样,因为国外都是自己弄来研究,不是用来开站,所以多数在研究开源的UOX)

        我:是吗?那RUNUO怎么样?开源么?性能怎么样?

        James:不,不开源。性能不错,超过UOX系列。
(在国外因为UOX开源,所以除了很多私人版本,而且UOX的性能确实低,下一个源码下来看看就知道了,用ROSE反向工程后,看那乱七八糟的类关系、重定义类型就头大)。 

        我:没源码不太好研究啊,什么写的呢?脚本引擎是自己做的么?还是和UOX一样?
(UOX的脚本引擎是用的JavaScript的,TUS和SPHERE的是自主开发的)

        James:不开源,但是它的脚本很有特色,用的.NET Framework,其实可以说没有用脚本引擎。脚本大多数是C#写的,估计执行程序也是C#开发的。

        我:什么意思?没有引擎,那怎么扩展呢?

        James:说不清楚,你知道.NET吗?

        我想:不至于这么看不起我吧~~~~

        我:知道,以前出来的时候玩过一段时间。是一个平台。开发语言很多,它采用的技术是类似JAVA的中间语言,是语言无关性的,对吧?

        James:你还知道挺多的啊。

        我想:靠~~~分明是洗我嘛。

        James:那你应该知到C#本来就是一种解释性的语言吧。

        我:其实不全是,可以说类似,但运行时它是经过JIT编译的,不能和解释性语言比,它效率要比那种解释性语言高得多。

        James:对,我的意思是类似解释性语言。所以,RUNUO就借助了这个特点,它的脚本也就是C#或VB.NET这种高级语言编写的,所以在运行前就编译过,运行起来效率就以前那些要好了。

        我:哦,这样啊,这到蛮有意思的,可以学习学习。

        James:是啊,我最近在玩,你不妨也去弄个来玩吧。它的接口设计挺好的,以后说不定还可以参考。

        我:嗯,好的。谢谢你告诉我,我去下个试试。那下次再聊,Bye-Bye。

        20分钟后,终于下下来了。安装后,看了一下,真的不的了。这种方法就和我当年想的一样。当年是用C++做的服务端,然后里面留出接口。需要扩展的时候,以插件的形式添加,即可以提高效率又可以防止被盗窃源码。以插件方式添加我觉得有两个好处:

       1、是编译过的,要反编译到原样是不可能的,因为以前在国内开文艺复兴站的时候,因为服务器安全问题,代码被偷过很多次。
       2、既然是编译过的,那就是二进制的,比解释的来得块得多。如果有什么问题,直接替换就可以了,不需要服务器重新加载一次。

        RUNUO居然把我当年想过未曾实现的和未曾想过的都实现了,刚开始我还是不太懂,它是如何在运行前把这一系列的.CS文件编译成Assembly的。我以为因为每台运行RUNUO的机器上都必须装.NET的运行环境,那么就一定有CSC这种东西,莫非从外部调用的???嗯,一定是,我心理这么想。(其实后来我才知道我错了,它用了一种比这个高级得多得方式,在后面的章节我们通过它的IL代码也就是反编译出来的中间代码来分析讨论这个问题

        这时jwh51上来了。

         
我:HI,51大哥。

         jwh51:好啊,最近好么。

         我:还行,很久没看到您啦。最近还在搞破解么?

         jwh51:没有了,没有时间。

         我:哦,最近我准备搞一个网络游戏,到时候客户端和协议加密部分需要您得帮助啊。

         jwh51:没问题,我一直在帮朋友做加密方面得工作。

         我:那先谢谢您了。我还有点事先下了。886

         jwh51:88

        接着我开始考虑刚才的问题,RUNUO怎么实现的利用C#做它的脚本语言的技术。通过反编译,然后又用IL码编译还原,看看中途有没有什么字节损失。还好,完全一模一样,可以开工了…………

原创文章,转载请注明: 转载自游戏无界·达秀的黑暗空间

本文链接地址: RUNUO服务器分析心得 第零章——序章

本站作品除特殊申明外均为原创,采用知识共享署名-非商业性使用-禁止演绎 3.0 Unported许可协议进行许可。如果需转载请保持文章完整性和标明原文出处,禁止商业用途。