0x6.U3D游戏修改分析实战

本文介绍IL反编译工具Ildasm.exe的基本使用方法及其在.NET程序中的应用,通过具体案例剖析IL代码指令,并展示了如何利用Ildasm.exe与ilasm工具对Unity3D游戏进行脚本反编译、修改与回编译。

注:

Ildasm.exe:用来将dll,exe编译为IL文件

ilasm.exe:用来将IL文件编译回来dll或exe

转:https://www.cnblogs.com/yangmingming/archive/2010/02/03/1662307.html

初识Ildasm.exe——IL反编译的实用工具

Ildasm.exe 概要:


一.前言:

     微软的IL反编译实用程序——Ildasm.exe,可以对可执行文件(ex,经典的控制台Hello World 的 exe 可执行文件)抽取出 IL 代码,并且给出命名空间以及类的视图。在讲述如何反编译之前,有必要从虚拟CPU的角度来看CLR,这样有助于先从正面了解代码执行过程。

虚拟CPU: 

    .NET 程序,其核心皆为 CLR ,而同时CLR的功能却与CPU非常相近,其中CLR执行IL代码(或叫做,IL指令)、操作数据,只不过操作的代码不同:CPU操作机器语言,而CLR操作IL代码。

由上,上述讲解的是从IL--机器语言的过程,而Ildasm则可以实现将可执行程序(机器语言)--IL代码,这就是Ildasm的主要功能。 

    在Anytao的《你必须知道的.NET》中对IL代码专门做了说明,虽然暂时悟不透其"深远意义",但我还是愿意去开始我的IL之旅的,呵呵~。 在此我们先看,Anytao对于掌握(或者了解) IL代码的重要性:

1.通用的语言基础是.NET运行的基础,当我们对运行结果有异议的时候,如何透过表面看本质,IL是必须的基础; 

2. IL也是更好理解、认识CLR的基础

3.大量的实例分析是以IL为基础的,所以了解IL,是读懂他人代码的必备基础,同时自己也可以获得潜移默化的提高; 

    有上述3条影响,足以让任何一个有追求的人都鼓足劲,去开始IL之旅了(自然包括我,呵呵~)。

 

二 .Ildasm.exe 的使用方法:

在应用Ildasm.exe具体反编译代码之前,先附上MSDN对于用Ildasm.exe反编译的经典帮助示例: 

 

然后我们用Ildasm.exe具体反编译经典的"Hello World"控制台程序的可执行文件,展现出来的视图为:

 


分析具体IL代码:

1.MANIFEST清单:

     MANIFEST是一个附加信息列表,主要包含程序集的一些属性,如程序集名称、版本号、哈希算法等;

2.ConsoleApplication1.Program类:

    这才是我们介绍的主角。 

首先是Program类: 代码为

.class private auto ansi beforefieldinit ConsoleApplication1.Program
       extends [mscorlib]System.Object
{
// end of class ConsoleApplication1.Program

1).class,表示Program是一个类。并且它继承自程序集—mscorlib的System.Object类;

2)private,表示访问权限;

3)auto,表示程序的内存加载全部由CLR来控制;

4)ansi,是为了在没有托管代码与托管代码之间实现无缝转换。这里主要指C、C++代码等;

5)beforefieldinit,是用来标记运行库(CLR)可以在静态字段方法生成后的任意时刻,来加载构造器(构造函数);

 

其次是 .otor方法,代码为:

复制代码
.method public hidebysig specialname rtspecialname 
        instance 
void  .ctor() cil managed
{
  
// Code size       7 (0x7)
  .maxstack  8
  IL_0000:  ldarg.
0
  IL_0001:  call       instance 
void [mscorlib]System.Object::.ctor()
  IL_0006:  ret
// end of method Program::.ctor
复制代码


1)cil managed:表示其中为IL代码,指示编译器编译为托管代码;

2).maxstack:表示调用构造函数.otor期间的评估堆栈(Evaluation Stack) ;

3)IL_0000:标记代码行开头;

4)ldarg.0:表示转载第一个成员参数,在实例方法中指的是当前实例的引用;

5)call:call一般用于调用静态方法,因为静态方法是在编译期就确定的。而这里的构造函数.otor()也是在编译期就制定的。而另一指令callvirt则表示调用实例方法, 它是在运行时确定的,因为如前述,当调用方法的继承关系时,就要比较基类与派生类的同名函数的实现方法(virtual和new),以确定调用的函数所属的Method Table;

6)ret:表示执行完毕,返回;

 

最后是Main()方法,代码为:

复制代码
.method private hidebysig static void  Main() cil managed
{
  .entrypoint
  
// Code size       13 (0xd)
  .maxstack  8
  IL_0000:  nop
  IL_0001:  ldstr      
"Hello world"
  IL_0006:  call       
void [mscorlib]System.Console::WriteLine(string)
  IL_000b:  nop
  IL_000c:  ret
// end of method Program::Main
复制代码


1) .entrypoint指令表示CLR加载程序时,是首先从.entrypoint开始的,即从Main方法作为程序的入口函数;

2)ldstr:表示将字符串压栈,在这里就是将"Hello World." 压栈;

3)hidebysig:表示当把此类作为基类,存在派生类时,此方法不被继承,同上构造函数;

 

   至此,我们对IL代码的一些指令有了了解,也纵观了IL世界里的概况,呵呵~

 

常用IL指令扩展: 


一:创建对象实例的IL指令

关于创建对象的在内存分配的机制,在《内存探寻1之——值类型和引用类型的内存分配机制》 里有了详细的介绍。而常用的创建对象的IL指令使我们更好理解对象的步骤。其主要有4种:

1.newobj: 用于创建引用类型的对象;

2:ldstr:用于创建String对象变量;

3.newarr:用于创建数组型对象;

4:box:在值类型转换为引用类型的对象时,将值类型拷贝纸托管堆上分配内存; 

 

二:通过IL代码,更好地理解属性 

我们在C++中,在典型的类中,都会定义用于控制有效性输入的Set()函数,以及用于不同方式显示的Get()函数。然而在C#中,它将Get()函数和Set()结合在一起,刚开始难免会为之混淆。然而若通过 Ildasm.exe对程序反编译后观察属性的本质,即可看到其执行机制,如下图示(注:选自互联网):

 

 

由我们前面的分析IL代码的方法,以及上图的展示,我们可以看到属性被重新分为Get()函数和Set()函数。ex,属性Name,被分解为get_Name()函数和set_Name(String s)函数。这样我们对其本质就一目了然了!至于其属性的特殊表示形式,只看做是Set()函数和Get()函数的完美结合体就可以了,这也是C#语言的优美体现啊,呵呵~

 

综述之,我们对反编译工具Ildasm.exe有了一定认识,最主要的,我们通过它反编译的IL代码,对基本的IL指令有了一定的了解,也对以后的在把IL代码作为有力工具 使用的过程中,更向前了一步!然而,这些都还只是IL的基础,需要继续深入,呵呵~


转:https://www.kanxue.com/book-24-102.htm

0x6.U3D游戏修改分析实战


本文介绍mono框架安卓Unity3D游戏的简单修改,提纲如下:



这次我们采用的样本是在第三节【逆向初体验】中的样本, 网盘链接 https://pan.baidu.com/s/1dvM7O6  密码: rpgt
-->文中的apk修改仅用于研究学习,如涉及权益侵犯请随时联系处理。 <-- 

第三节中已经讲过反编译与回编译,所以本节不再赘述这两部分内容。下面分确认脚本、反编译/回编译脚本、修改脚本三部分进行讲解。

0x1.确认脚本
mono架构的Unity3D游戏的主要脚本主要存放在Assembly-CSharp.dll或者Assembly-CSharp-firstpass.dll中。路径为:



一般情况下,两个文件中较大的为我们要找的主要脚本,部分apk中只有 Assembly-CSharp.dll。

0x2.反编译/回编译脚本
.NET架构dll的反编译回编译工具有很多,本文使用的是最原始的工具 ildasm及ilasm【已上传至附件】。
(需要安装.NET Framework,请根据个人电脑配置情况安装,如果缺少某dll请自行下载补全)

2.1 ildasm反编译工具
用ildasm打开该apk的脚本文件 Assembly-CSharp.dll,打开后进行dump,File --> Dump --> OK,命名为conglin后等待dump完成。
这时我们的到了一个il文件和一个res文件,这个就是反编译后的il中间语言文件。

2.2ilasm回编译工具
完成修改后,需要使用ilasm进行回编译,重新打包生成dll文件。命令如下:
ilasm /dll /resource=conglin.res conglin.il
命令如果无效请使用标准命令
ilasm conglin.il /dll /output:conglin.dll
编译完成后,将dll重命名为原本名字 Assembly-CSharp.dll放回到Managed文件夹,编译apk运行即可。

0x3.修改脚本
本apk本身对于金条数量已经有修改,数量为100100,我们现在着手查找一下这个修改的位置。

                           

此修改位置的查找我们需要在conglin.il中进行,搜索100100,如果没有结果,我们则搜索其16进制数0x18704,结果如下:



我们将其修改为999999的十六进制,即0xf423f,保存,然后使用ilasm进行回编译。
之后重命名放到Managed文件夹打包运行即可,此处不再演示,请大家自己尝试。

上传的附件:

timing is 86083 ns, write address [0x88015c18] [0x05706]= 0x0000aaaa ... simulation is on, at time 86200 ns... timing is 86203 ns, read address [0x88015c18] [0x05706] = 0x0000aaaa ... timing is 86343 ns, write address [0x88015c1c] [0x05707]= 0x00005555 ... simulation is on, at time 86400 ns... timing is 86463 ns, read address [0x88015c1c] [0x05707] = 0x00005555 ... simulation is on, at time 86600 ns... timing is 86603 ns, write address [0x88015d00] [0x05740]= 0x000000aa ... timing is 86723 ns, read address [0x88015d00] [0x05740] = 0x000000aa ... simulation is on, at time 86800 ns... timing is 86863 ns, write address [0x88015d04] [0x05741]= 0x00000055 ... timing is 86983 ns, read address [0x88015d04] [0x05741] = 0x00000055 ... simulation is on, at time 87000 ns... timing is 87123 ns, write address [0x88015d08] [0x05742]= 0x000000aa ... simulation is on, at time 87200 ns... timing is 87243 ns, read address [0x88015d08] [0x05742] = 0x000000aa ... timing is 87383 ns, write address [0x88015d0c] [0x05743]= 0x00000055 ... simulation is on, at time 87400 ns... timing is 87503 ns, read address [0x88015d0c] [0x05743] = 0x00000055 ... simulation is on, at time 87600 ns... timing is 87643 ns, write address [0x88015d10] [0x05744]= 0x000000aa ... timing is 87763 ns, read address [0x88015d10] [0x05744] = 0x000000aa ... simulation is on, at time 87800 ns... timing is 87903 ns, write address [0x88015d14] [0x05745]= 0x00000055 ... simulation is on, at time 88000 ns... timing is 88023 ns, read address [0x88015d14] [0x05745] = 0x00000055 ... timing is 88163 ns, write address [0x88015d18] [0x05746]= 0x000000aa ... simulation is on, at time 88200 ns... timing is 88283 ns, read address [0x88015d18] [0x05746] = 0x000000aa ... simulation is on, at time 88400 ns... timing is 88423 ns, write address [0x88015d1c] [0x05747]= 0x00000055 ... timing is 88543 ns, read address [0x88015d1c] [0x05747] = 0x00000055 ... simulation is on, at time 88600 ns... timing is 88683 ns, write address [0x88015d80] [0x05760]= 0x000000aa ... simulation is on, at time 88800 ns... timing is 88803 ns, read address [0x88015d80] [0x05760] = 0x000000aa ... timing is 88943 ns, write address [0x88015d84] [0x05761]= 0x00000055 ... simulation is on, at time 89000 ns... timing is 89063 ns, read address [0x88015d84] [0x05761] = 0x00000055 ... simulation is on, at time 89200 ns... timing is 89203 ns, write address [0x88015d88] [0x05762]= 0x000000aa ... timing is 89323 ns, read address [0x88015d88] [0x05762] = 0x000000aa ... simulation is on, at time 89400 ns... timing is 89463 ns, write address [0x88015d8c] [0x05763]= 0x00000055 ... timing is 89583 ns, read address [0x88015d8c] [0x05763] = 0x00000055 ... simulation is on, at time 89600 ns... timing is 89723 ns, write address [0x88015d90] [0x05764]= 0x000000aa ... simulation is on, at time 89800 ns... timing is 89843 ns, read address [0x88015d90] [0x05764] = 0x000000aa ... timing is 89983 ns, write address [0x88015d94] [0x05765]= 0x00000055 ... simulation is on, at time 90000 ns... timing is 90103 ns, read address [0x88015d94] [0x05765] = 0x00000055 ... simulation is on, at time 90200 ns... timing is 90243 ns, write address [0x88015d98] [0x05766]= 0x000000aa ... timing is 90363 ns, read address [0x88015d98] [0x05766] = 0x000000aa ... simulation is on, at time 90400 ns... timing is 90503 ns, write address [0x88015d9c] [0x05767]= 0x00000055 ... simulation is on, at time 90600 ns... timing is 90623 ns, read address [0x88015d9c] [0x05767] = 0x00000055 ... timing is 90763 ns, write address [0x88016800] [0x05a00]= 0x00003333 ... simulation is on, at time 90800 ns... timing is 90883 ns, read address [0x88016800] [0x05a00] = 0x00003333 ... simulation is on, at time 91000 ns... timing is 91023 ns, write address [0x88016804] [0x05a01]= 0x00002222 ... timing is 91143 ns, read address [0x88016804] [0x05a01] = 0x00002222 ... simulation is on, at time 91200 ns... timing is 91283 ns, write address [0x88016808] [0x05a02]= 0x00003333 ... simulation is on, at time 91400 ns... timing is 91403 ns, read address [0x88016808] [0x05a02] = 0x00003333 ... timing is 91543 ns, write address [0x8801680c] [0x05a03]= 0x00002222 ... simulation is on, at time 91600 ns... timing is 91663 ns, read address [0x8801680c] [0x05a03] = 0x00002222 ... simulation is on, at time 91800 ns... timing is 91803 ns, write address [0x88016810] [0x05a04]= 0x00003333 ... timing is 91923 ns, read address [0x88016810] [0x05a04] = 0x00003333 ... simulation is on, at time 92000 ns... timing is 92063 ns, write address [0x88016814] [0x05a05]= 0x00002222 ... timing is 92183 ns, read address [0x88016814] [0x05a05] = 0x00002222 ... simulation is on, at time 92200 ns... timing is 92323 ns, write address [0x88016818] [0x05a06]= 0x00003333 ... simulation is on, at time 92400 ns... timing is 92443 ns, read address [0x88016818] [0x05a06] = 0x00003333 ... timing is 92583 ns, write address [0x8801681c] [0x05a07]= 0x00002222 ... simulation is on, at time 92600 ns... timing is 92703 ns, read address [0x8801681c] [0x05a07] = 0x00002222 ... simulation is on, at time 92800 ns... timing is 92843 ns, write address [0x88016840] [0x05a10]= 0x00003333 ... timing is 92963 ns, read address [0x88016840] [0x05a10] = 0x00000033 ... simulation is on, at time 93000 ns... timing is 93103 ns, write address [0x88016844] [0x05a11]= 0x00002222 ... simulation is on, at time 93200 ns... timing is 93223 ns, read address [0x88016844] [0x05a11] = 0x00000022 ... timing is 93363 ns, write address [0x88016848] [0x05a12]= 0x00003333 ... simulation is on, at time 93400 ns... timing is 93483 ns, read address [0x88016848] [0x05a12] = 0x00000033 ... simulation is on, at time 93600 ns... timing is 93623 ns, write address [0x8801684c] [0x05a13]= 0x00002222 ... timing is 93743 ns, read address [0x8801684c] [0x05a13] = 0x00000022 ... simulation is on, at time 93800 ns... timing is 93883 ns, write address [0x88016850] [0x05a14]= 0x00003333 ... simulation is on, at time 94000 ns... timing is 94003 ns, read address [0x88016850] [0x05a14] = 0x00000033 ... timing is 94143 ns, write address [0x88016854] [0x05a15]= 0x00002222 ... simulation is on, at time 94200 ns... timing is 94263 ns, read address [0x88016854] [0x05a15] = 0x00000022 ... simulation is on, at time 94400 ns... timing is 94403 ns, write address [0x88016858] [0x05a16]= 0x00003333 ... timing is 94523 ns, read address [0x88016858] [0x05a16] = 0x00000033 ... simulation is on, at time 94600 ns... timing is 94663 ns, write address [0x8801685c] [0x05a17]= 0x00002222 ... timing is 94783 ns, read address [0x8801685c] [0x05a17] = 0x00000022 ... simulation is on, at time 94800 ns... timing is 94923 ns, write address [0x88016880] [0x05a20]= 0x00003333 ... simulation is on, at time 95000 ns... timing is 95043 ns, read address [0x88016880] [0x05a20] = 0x00003333 ... timing is 95183 ns, write address [0x88016884] [0x05a21]= 0x00002222 ... simulation is on, at time 95200 ns... timing is 95303 ns, read address [0x88016884] [0x05a21] = 0x00002222 ... simulation is on, at time 95400 ns... timing is 95443 ns, write address [0x88016888] [0x05a22]= 0x00003333 ... timing is 95563 ns, read address [0x88016888] [0x05a22] = 0x00003333 ... simulation is on, at time 95600 ns... timing is 95703 ns, write address [0x8801688c] [0x05a23]= 0x00002222 ... simulation is on, at time 95800 ns... timing is 95823 ns, read address [0x8801688c] [0x05a23] = 0x00002222 ... timing is 95963 ns, write address [0x88016890] [0x05a24]= 0x00003333 ... simulation is on, at time 96000 ns... timing is 96083 ns, read address [0x88016890] [0x05a24] = 0x00003333 ... simulation is on, at time 96200 ns... timing is 96223 ns, write address [0x88016894] [0x05a25]= 0x00002222 ... timing is 96343 ns, read address [0x88016894] [0x05a25] = 0x00002222 ... simulation is on, at time 96400 ns... timing is 96483 ns, write address [0x88016898] [0x05a26]= 0x00003333 ... simulation is on, at time 96600 ns... timing is 96603 ns, read address [0x88016898] [0x05a26] = 0x00003333 ... timing is 96743 ns, write address [0x8801689c] [0x05a27]= 0x00002222 ... simulation is on, at time 96800 ns... timing is 96863 ns, read address [0x8801689c] [0x05a27] = 0x00002222 ... simulation is on, at time 97000 ns... timing is 97003 ns, write address [0x880168c0] [0x05a30]= 0x00003333 ... timing is 97123 ns, read address [0x880168c0] [0x05a30] = 0x00000001 ... simulation is on, at time 97200 ns... timing is 97263 ns, write address [0x880168c4] [0x05a31]= 0x00002222 ... timing is 97383 ns, read address [0x880168c4] [0x05a31] = 0x00000000 ... simulation is on, at time 97400 ns... timing is 97523 ns, write address [0x880168c8] [0x05a32]= 0x00003333 ... simulation is on, at time 97600 ns... timing is 97643 ns, read address [0x880168c8] [0x05a32] = 0x00000001 ... timing is 97783 ns, write address [0x880168cc] [0x05a33]= 0x00002222 ... simulation is on, at time 97800 ns... timing is 97903 ns, read address [0x880168cc] [0x05a33] = 0x00000000 ... simulation is on, at time 98000 ns... timing is 98043 ns, write address [0x880168d0] [0x05a34]= 0x00003333 ... timing is 98163 ns, read address [0x880168d0] [0x05a34] = 0x00000001 ... simulation is on, at time 98200 ns... timing is 98303 ns, write address [0x880168d4] [0x05a35]= 0x00002222 ... simulation is on, at time 98400 ns... timing is 98423 ns, read address [0x880168d4] [0x05a35] = 0x00000000 ... timing is 98563 ns, write address [0x880168d8] [0x05a36]= 0x00003333 ... simulation is on, at time 98600 ns... timing is 98683 ns, read address [0x880168d8] [0x05a36] = 0x00000001 ... simulation is on, at time 98800 ns... timing is 98823 ns, write address [0x880168dc] [0x05a37]= 0x00002222 ... timing is 98943 ns, read address [0x880168dc] [0x05a37] = 0x00000000 ... simulation is on, at time 99000 ns... timing is 99083 ns, write address [0x88016c00] [0x05b00]= 0x77777777 ... simulation is on, at time 99200 ns... timing is 99203 ns, read address [0x88016c00] [0x05b00] = 0x77777777 ... timing is 99343 ns, write address [0x88016c04] [0x05b01]= 0x88888888 ... simulation is on, at time 99400 ns... timing is 99463 ns, read address [0x88016c04] [0x05b01] = 0x88888888 ... simulation is on, at time 99600 ns... timing is 99603 ns, write address [0x88016c08] [0x05b02]= 0x77777777 ... timing is 99723 ns, read address [0x88016c08] [0x05b02] = 0x77777777 ... simulation is on, at time 99800 ns... timing is 99863 ns, write address [0x88016c0c] [0x05b03]= 0x88888888 ... timing is 99983 ns, read address [0x88016c0c] [0x05b03] = 0x88888888 ... simulation is on, at time 100000 ns... timing is 100123 ns, write address [0x88016c10] [0x05b04]= 0x77777777 ... simulation is on, at time 100200 ns... timing is 100243 ns, read address [0x88016c10] [0x05b04] = 0x77777777 ... timing is 100383 ns, write address [0x88016c14] [0x05b05]= 0x88888888 ... simulation is on, at time 100400 ns... timing is 100503 ns, read address [0x88016c14] [0x05b05] = 0x88888888 ... simulation is on, at time 100600 ns... timing is 100643 ns, write address [0x88016c18] [0x05b06]= 0x77777777 ... timing is 100763 ns, read address [0x88016c18] [0x05b06] = 0x77777777 ... simulation is on, at time 100800 ns... timing is 100903 ns, write address [0x88016c1c] [0x05b07]= 0x88888888 ... simulation is on, at time 101000 ns... timing is 101023 ns, read address [0x88016c1c] [0x05b07] = 0x88888888 ... 检查下以上命令行,相同输入输出地址寄存器 读写数据不一样的有哪些
09-24
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值