0x3.U3D游戏逆向修改深化-1

U3D游戏逆向修改深化-1 : IL指令介绍


本文主要介绍常用的IL指令,主要分一下几个类型来进行介绍。



常用IL指令文档 链接: https://pan.baidu.com/s/1dp507PpZfhofud9LDAp8lQ 密码: arhh

官方介绍地址:https://msdn.microsoft.com/zh-cn/library/system.reflection.emit.opcodes(v=vs.110).aspx

接下来我们分类进行介绍。


0x1.IL是什么

U3D游戏的脚本开发语言为C#,dll脚本反编译后的语言即为IL,也被称为微软中间语言MSIL。


0x2.常用指令

我将IL分析中常用的指令分为了五种,分别是用于加载的ld开头指令、用于存储的st开头指令、用于跳转的b开头指令、用于调用的call开头指令、运算指令


2.1   用于加载的ld开头指令

ld是load的意思,是将操作数推送/加载到堆栈中,等待下一个语句调用或者存储。下面介绍几种常见的指令:

2.1.1  ldc指令

ldc.i4 → 将所提供的int32类型的值推送到堆栈上,简言之,就是在内存中加载一个整数。

        例如:ldc.i4     0x10      意思就是将十六进制数0x10加载到内存中,也有ldc.i4.0~ldc.i4.8代表整数1到8加载到内存中。

2.1.2  ldstr指令

ldstr → 将字符串对象推送到堆栈中,简言之,就是在内存中加载一个字符串对象。

        例如:ldstr     “hello world”     意思就是将字符串“hello world”加载到内存中。

2.1.2  ldfld指令

ldfld →  查找对象中其引用的当前位于计算堆栈的字段的值。

        例如:ldfld     string name     意思就是将字符串变量name中的值查找出来待用。


2.2   用于存储的st开头指令

st是store的意思,是将操作数从堆栈中弹出,相当于将其赋值给某些变量的意思。

stfld →  用新值替换在对象引用或指针的字段中存储的值。

        例如:stfld     string name    意思就是将堆栈中的字符串对象赋值给字符串变量name。


2.3   用于跳转的b开头指令

b是branch的意思,可以理解为分支或者跳转。

2.3.1  beq指令

beq → 如果两个值相等,则将控制转移到目标指令。这个与smali中的是类似的。

        例如:beq     IL_0020     意思就是如果前面提供的两个值相等,就跳转到IL_0020这一行执行。

2.3.2  br指令

br → 无条件的将控制转移到目标指令。

        例如:br     IL_0020     意思就是不进行任何判断直接跳转到IL_0020这一行执行。


2.4   用于调用的call开头指令

call是调用的意思,常见的两种,带返回值的和不带返回值的。

2.4.1 call指令

call →  调用由传递的方法说明符指示的方法。

2.4.2 callvirt指令

callvirt →  对对象调用后期绑定方法,并且将返回值推送到计算堆栈上。


两者有区别但是我们现在并不必深究,仅做了解知道是调用函数即可。

【    仅作了解:

1)call可以调用静态方法,实例方法和虚方法

     callvirt只能调用实例方法和虚方法,不能调用静态方法

2)call一般是以非虚的方式来调用函数的

     callvirt是以已多态的方式来调用函数的      】


2.5   运算指令

运算分为两类,算术运算和逻辑运算。

2.5.1  算术运算

算术运算主要是加减乘除,分别为 add、sub、mul、div。

2.5.2  逻辑运算

逻辑运算主要是与或非,分别为 and、or、not;异或也常用到,为xor。


0x3.举例分析

例子1:

ldc.i4     0x2
stfld     int32 value1
ldc.i4     0x3
ldfld     int32 value1
mul
stfld     int32 value2
上述代码的意思是:
//将数值2加载到内存
//将其存储整型变量value1
//将数值3加载到内存
//将value1的值加载到内存
//数值3和value1的值进行乘法运算
//运算结果存储到value2中
例子2:
ldc.r4     0.5
stfld     float32 value1
ldc.r4     0.6
ldfld     float32 value1
beq     IL_0020
call    void function()
br     IL_0020
上述代码的意思是:
//将浮点数0.5加载到内存中
//将0.5存储到float32变量value1中
//将浮点数0.6加载到内存中
//将value1的值加载到内存中
//比较0.6和value1的值,如果相等就跳转到IL_0020
//如果不相等就执行call来调用函数function()
//直接跳转到IL_0020