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游戲的腳本開發(fā)語言為C#,dll腳本反編譯后的語言即為IL,也被稱為微軟中間語言MSIL。


0x2.常用指令

我將IL分析中常用的指令分為了五種,分別是用于加載的ld開頭指令、用于存儲的st開頭指令、用于跳轉的b開頭指令、用于調用的call開頭指令、運算指令。


2.1   用于加載的ld開頭指令

ld是load的意思,是將操作數(shù)推送/加載到堆棧中,等待下一個語句調用或者存儲。下面介紹幾種常見的指令:

2.1.1  ldc指令

ldc.i4 → 將所提供的int32類型的值推送到堆棧上,簡言之,就是在內存中加載一個整數(shù)。

        例如:ldc.i4     0x10      意思就是將十六進制數(shù)0x10加載到內存中,也有l(wèi)dc.i4.0~ldc.i4.8代表整數(shù)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的意思,是將操作數(shù)從堆棧中彈出,相當于將其賦值給某些變量的意思。

stfld →  用新值替換在對象引用或指針的字段中存儲的值。

        例如:stfld     string name    意思就是將堆棧中的字符串對象賦值給字符串變量name。


2.3   用于跳轉的b開頭指令

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

2.3.1  beq指令

beq → 如果兩個值相等,則將控制轉移到目標指令。這個與smali中的是類似的。

        例如:beq     IL_0020     意思就是如果前面提供的兩個值相等,就跳轉到IL_0020這一行執(zhí)行。

2.3.2  br指令

br → 無條件的將控制轉移到目標指令。

        例如:br     IL_0020     意思就是不進行任何判斷直接跳轉到IL_0020這一行執(zhí)行。


2.4   用于調用的call開頭指令

call是調用的意思,常見的兩種,帶返回值的和不帶返回值的。

2.4.1 call指令

call →  調用由傳遞的方法說明符指示的方法。

2.4.2 callvirt指令

callvirt →  對對象調用后期綁定方法,并且將返回值推送到計算堆棧上。


兩者有區(qū)別但是我們現(xiàn)在并不必深究,僅做了解知道是調用函數(shù)即可。

【    僅作了解:

1)call可以調用靜態(tài)方法,實例方法和虛方法

     callvirt只能調用實例方法和虛方法,不能調用靜態(tài)方法

2)call一般是以非虛的方式來調用函數(shù)的

     callvirt是以已多態(tài)的方式來調用函數(shù)的      】


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
上述代碼的意思是:
//將數(shù)值2加載到內存
//將其存儲整型變量value1
//將數(shù)值3加載到內存
//將value1的值加載到內存
//數(shù)值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
上述代碼的意思是:
//將浮點數(shù)0.5加載到內存中
//將0.5存儲到float32變量value1中
//將浮點數(shù)0.6加載到內存中
//將value1的值加載到內存中
//比較0.6和value1的值,如果相等就跳轉到IL_0020
//如果不相等就執(zhí)行call來調用函數(shù)function()
//直接跳轉到IL_0020

?