C# invalid IL after altering dll with reflector and reflexil plugin

0

I'm trying to learn how to hack a game, and i just wanted to start by adding some functionality. I found a likely function and wanted to add a bit of code before the main execution, but the game reports invalid IL when running. I don't understand what's wrong though.

The original decompiled code was like this:

public void InitializeAfterInventory()
{
    if ((this.thisCharacterInstance.spawn_type == SpawnType.SpawnType_Avatar) && (this.inventory.curDeck != null))
    {
        ItemDef def = this.inventory.curDeck.def;
        base.baseAttributes.armor = def.decking_hardening;
        base.baseAttributes.body = def.decking_body;
        base.baseSkills.dodge = def.decking_evasion;
        base.baseAttributes.ap = def.decking_max_ap;
        base.baseAttributes.hp = def.decking_max_ip;
        base.SetHP(this.inventory.curDeck.CurrentHealth);
        base.SetAP(base.baseAttributes.ap);
        base.SetRP(StatsUtil.GetMaxArmor(this));
        this.inventory.InitializeAvatarItems(def.decking_default_weapon);
    }
    if ((this.thisCharacterInstance.spawn_type == SpawnType.SpawnType_Avatar) && (this.inventory.curDeck == null))
    {
        Logger.LogError(LogChannel.PLYR, base.name + " is of type avatar, but has no deck.  Stats unchanged");
    }
}

with this IL:

Offset  OpCode  Operand
0   ldarg.0 
1   ldfld   isogame.CharacterInstance Player::thisCharacterInstance
6   callvirt    isogame.SpawnType isogame.CharacterInstance::get_spawn_type()
11  ldc.i4.2    
12  bne.un  -> (60) ldarg.0 
17  ldarg.0 
18  ldfld   PlayerInventory Player::inventory
23  ldfld   Item PlayerInventory::curDeck
28  brfalse -> (60) ldarg.0 
33  ldarg.0 
34  ldfld   PlayerInventory Player::inventory
39  ldfld   Item PlayerInventory::curDeck
44  ldfld   isogame.ItemDef Item::def
49  stloc.0 
50  ldarg.0 
51  ldfld   isogame.Attributes Actor::baseAttributes
56  ldloc.0 
57  callvirt    System.Int32 isogame.ItemDef::get_decking_hardening()
62  callvirt    System.Void isogame.Attributes::set_armor(System.Int32)
67  ldarg.0 
68  ldfld   isogame.Attributes Actor::baseAttributes
73  ldloc.0 
74  callvirt    System.Int32 isogame.ItemDef::get_decking_body()
79  callvirt    System.Void isogame.Attributes::set_body(System.Int32)
84  ldarg.0 
85  ldfld   isogame.Skills Actor::baseSkills
90  ldloc.0 
91  callvirt    System.Int32 isogame.ItemDef::get_decking_evasion()
96  callvirt    System.Void isogame.Skills::set_dodge(System.Int32)
101 ldarg.0 
102 ldfld   isogame.Attributes Actor::baseAttributes
107 ldloc.0 
108 callvirt    System.Int32 isogame.ItemDef::get_decking_max_ap()
113 callvirt    System.Void isogame.Attributes::set_ap(System.Int32)
118 ldarg.0 
119 ldfld   isogame.Attributes Actor::baseAttributes
124 ldloc.0 
125 callvirt    System.Int32 isogame.ItemDef::get_decking_max_ip()
130 callvirt    System.Void isogame.Attributes::set_hp(System.Int32)
135 ldarg.0 
136 ldarg.0 
137 ldfld   PlayerInventory Player::inventory
142 ldfld   Item PlayerInventory::curDeck
147 callvirt    System.Int32 Item::get_CurrentHealth()
152 call    System.Void Actor::SetHP(System.Int32)
157 ldarg.0 
158 ldarg.0 
159 ldfld   isogame.Attributes Actor::baseAttributes
164 callvirt    System.Int32 isogame.Attributes::get_ap()
169 call    System.Void Actor::SetAP(System.Int32)
174 ldarg.0 
175 ldarg.0 
176 call    System.Int32 StatsUtil::GetMaxArmor(Actor)
181 call    System.Void Actor::SetRP(System.Int32)
186 ldarg.0 
187 ldfld   PlayerInventory Player::inventory
192 ldloc.0 
193 callvirt    System.String isogame.ItemDef::get_decking_default_weapon()
198 callvirt    System.Boolean PlayerInventory::InitializeAvatarItems(System.String)
203 pop 
204 ldarg.0 
205 ldfld   isogame.CharacterInstance Player::thisCharacterInstance
210 callvirt    isogame.SpawnType isogame.CharacterInstance::get_spawn_type()
215 ldc.i4.2    
216 bne.un  -> (75) ret 
221 ldarg.0 
222 ldfld   PlayerInventory Player::inventory
227 ldfld   Item PlayerInventory::curDeck
232 brtrue  -> (75) ret 
237 ldsfld  LogChannel LogChannel::PLYR
242 ldarg.0 
243 call    System.String UnityEngine.Object::get_name()
248 ldstr    is of type avatar, but has no deck.  Stats unchanged
253 call    System.String System.String::Concat(System.String,System.String)
258 call    System.Void Logger::LogError(LogChannel,System.String)
263 ret 

while my edit is this:

public void InitializeAfterInventory()
{
    // This item is obfuscated and can not be translated.
    Item tempDataJack = PlayerInventory.GetTempDataJack(this);
    if (((this.inventory.curDeck == null) && (tempDataJack != null)) && (tempDataJack.def.decking_default_weapon != null))
    {
        this.inventory.curDeck = tempDataJack;
    }
    if ((this.thisCharacterInstance.spawn_type == SpawnType.SpawnType_Avatar) && (this.inventory.curDeck != null))
    {
        ItemDef def = this.inventory.curDeck.def;
        base.baseAttributes.armor = def.decking_hardening;
        base.baseAttributes.body = def.decking_body;
        base.baseSkills.dodge = def.decking_evasion;
        base.baseAttributes.ap = def.decking_max_ap;
        base.baseAttributes.hp = def.decking_max_ip;
        base.SetHP(this.inventory.curDeck.CurrentHealth);
        base.SetAP(base.baseAttributes.ap);
        base.SetRP(StatsUtil.GetMaxArmor(this));
        this.inventory.InitializeAvatarItems(def.decking_default_weapon);
    }
    if ((this.thisCharacterInstance.spawn_type == SpawnType.SpawnType_Avatar) && (this.inventory.curDeck == null))
    {
        Logger.LogError(LogChannel.PLYR, base.name + " is of type avatar, but has no deck.  Stats unchanged");
    }
}

(notice the auto-inserted comment)

with this IL:

Offset  OpCode  Operand
0   ldarg.0 
1   ldfld   PlayerInventory Player::inventory
6   ldarg.0 
7   callvirt    Item PlayerInventory::GetTempDataJack(Player)
12  stloc.0 
13  ldarg.0 
14  ldfld   PlayerInventory Player::inventory
19  ldfld   Item PlayerInventory::curDeck
24  brtrue  -> (19) ldarg.0 
29  ldloc.0 
30  brfalse -> (19) ldarg.0 
35  ldloc.0 
36  ldfld   isogame.ItemDef Item::def
41  callvirt    System.String isogame.ItemDef::get_decking_default_weapon()
46  brfalse -> (19) ldarg.0 
51  ldarg.0 
52  ldfld   PlayerInventory Player::inventory
57  ldloc.0 
58  stfld   Item PlayerInventory::curDeck
63  ldarg.0 
64  ldfld   isogame.CharacterInstance Player::thisCharacterInstance
69  callvirt    isogame.SpawnType isogame.CharacterInstance::get_spawn_type()
74  ldc.i4.2    
75  bne.un  -> (79) ldarg.0 
80  ldarg.0 
81  ldfld   PlayerInventory Player::inventory
86  ldfld   Item PlayerInventory::curDeck
91  brfalse -> (79) ldarg.0 
96  ldarg.0 
97  ldfld   PlayerInventory Player::inventory
102 ldfld   Item PlayerInventory::curDeck
107 ldfld   isogame.ItemDef Item::def
112 stloc.1 
113 ldarg.0 
114 ldfld   isogame.Attributes Actor::baseAttributes
119 ldloc.1 
120 callvirt    System.Int32 isogame.ItemDef::get_decking_hardening()
125 callvirt    System.Void isogame.Attributes::set_armor(System.Int32)
130 ldarg.0 
131 ldfld   isogame.Attributes Actor::baseAttributes
136 ldloc.1 
137 callvirt    System.Int32 isogame.ItemDef::get_decking_body()
142 callvirt    System.Void isogame.Attributes::set_body(System.Int32)
147 ldarg.0 
148 ldfld   isogame.Skills Actor::baseSkills
153 ldloc.1 
154 callvirt    System.Int32 isogame.ItemDef::get_decking_evasion()
159 callvirt    System.Void isogame.Skills::set_dodge(System.Int32)
164 ldarg.0 
165 ldfld   isogame.Attributes Actor::baseAttributes
170 ldloc.1 
171 callvirt    System.Int32 isogame.ItemDef::get_decking_max_ap()
176 callvirt    System.Void isogame.Attributes::set_ap(System.Int32)
181 ldarg.0 
182 ldfld   isogame.Attributes Actor::baseAttributes
187 ldloc.1 
188 callvirt    System.Int32 isogame.ItemDef::get_decking_max_ip()
193 callvirt    System.Void isogame.Attributes::set_hp(System.Int32)
198 ldarg.0 
199 ldarg.0 
200 ldfld   PlayerInventory Player::inventory
205 ldfld   Item PlayerInventory::curDeck
210 callvirt    System.Int32 Item::get_CurrentHealth()
215 call    System.Void Actor::SetHP(System.Int32)
220 ldarg.0 
221 ldarg.0 
222 ldfld   isogame.Attributes Actor::baseAttributes
227 callvirt    System.Int32 isogame.Attributes::get_ap()
232 call    System.Void Actor::SetAP(System.Int32)
237 ldarg.0 
238 ldarg.0 
239 call    System.Int32 StatsUtil::GetMaxArmor(Actor)
244 call    System.Void Actor::SetRP(System.Int32)
249 ldarg.0 
250 ldfld   PlayerInventory Player::inventory
255 ldloc.1 
256 callvirt    System.String isogame.ItemDef::get_decking_default_weapon()
261 callvirt    System.Boolean PlayerInventory::InitializeAvatarItems(System.String)
266 pop 
267 ldarg.0 
268 ldfld   isogame.CharacterInstance Player::thisCharacterInstance
273 callvirt    isogame.SpawnType isogame.CharacterInstance::get_spawn_type()
278 ldc.i4.2    
279 bne.un  -> (94) ret 
284 ldarg.0 
285 ldfld   PlayerInventory Player::inventory
290 ldfld   Item PlayerInventory::curDeck
295 brtrue  -> (94) ret 
300 ldsfld  LogChannel LogChannel::PLYR
305 ldarg.0 
306 call    System.String UnityEngine.Object::get_name()
311 ldstr    is of type avatar, but has no deck.  Stats unchanged
316 call    System.String System.String::Concat(System.String,System.String)
321 call    System.Void Logger::LogError(LogChannel,System.String)
326 ret 

I also added a variable of type 'Item' at index 0 on the 'Variables' tab of the Reflexil menu for the method (to join the other of type ItemDef'), that was the only way that it wouldn't crash right away when trying to display the code. I don't understand what's wrong, the game always shows:

[...]
ERROR -1    *      PlayerInventory.EquipAvailableFromBackpack ()
ERROR -1 EXCEPTION: InvalidProgramException: Invalid IL code in Player:InitializeAfterInventory (): IL_0146: ret    

in the log

edit: requested output of linux mono version peverify errors, original:

Shadowrun Dragonfall/Shadowrun Dragonfall/Dragonfall_Data/Managed$ peverify Assembly-CSharp\ \(ORIGINAL\).dll 
Missing method .ctor in assembly /home/i30817/Desktop/Shadowrun Dragonfall/Shadowrun Dragonfall/Dragonfall_Data/Managed/Assembly-CSharp (ORIGINAL).dll, type System.Runtime.CompilerServices.ExtensionAttribute
Error: Invalid CustomAttribute content row 1 Value field 0x00003c18
Error: CustomAttribute: Invalid constructor
Error count: 2

(original works fine in game) edited:

Shadowrun Dragonfall/Dragonfall_Data/Managed$ peverify Assembly-CSharp.dll 
Missing method .ctor in assembly /home/i30817/Desktop/Shadowrun Dragonfall/Shadowrun Dragonfall/Dragonfall_Data/Managed/Assembly-CSharp.dll, type System.Runtime.CompilerServices.ExtensionAttribute
Error: Invalid CustomAttribute content row 1 Value field 0x00000048
Error: CustomAttribute: Invalid constructor
Error count: 2

edit 2: this is the CIL of the method output from monodis (slightly different because i redid the edit, but the same error and structure):

// method line 5554
.method public hidebysig 
       instance default void InitializeAfterInventory ()  cil managed 
{
    // Method begins at RVA 0xa4de0
// Code size 312 (0x138)
.maxstack 4
.locals init (
    class [ShadowrunDTO]isogame.ItemDef V_0,
    class Item  V_1)
IL_0000:  ldarg.0 
IL_0001:  ldfld class PlayerInventory Player::inventory
IL_0006:  ldarg.0 
IL_0007:  callvirt class Item class PlayerInventory::GetTempDataJack(class Player)
IL_000c:  stloc.1 
IL_000d:  ldarg.0 
IL_000e:  ldfld class PlayerInventory Player::inventory
IL_0013:  ldfld class Item PlayerInventory::curDeck
IL_0018:  brtrue.s IL_0036

IL_001a:  ldloc.1 
IL_001b:  brfalse.s IL_0036

IL_001d:  ldloc.1 
IL_001e:  ldfld class [ShadowrunDTO]isogame.ItemDef Item::def
IL_0023:  callvirt instance string class [ShadowrunDTO]isogame.ItemDef::get_decking_default_weapon()
IL_0028:  brfalse.s IL_0036

IL_002a:  ldarg.0 
IL_002b:  ldfld class PlayerInventory Player::inventory
IL_0030:  ldloc.1 
IL_0031:  stfld class Item PlayerInventory::curDeck
IL_0036:  ldarg.0 
IL_0037:  ldfld class [ShadowrunDTO]isogame.CharacterInstance Player::thisCharacterInstance
IL_003c:  callvirt instance valuetype [ShadowrunDTO]isogame.SpawnType class [ShadowrunDTO]isogame.CharacterInstance::get_spawn_type()
IL_0041:  ldc.i4.2 
IL_0042:  bne.un IL_0102

IL_0047:  ldarg.0 
IL_0048:  ldfld class PlayerInventory Player::inventory
IL_004d:  ldfld class Item PlayerInventory::curDeck
IL_0052:  brfalse IL_0102

IL_0057:  ldarg.0 
IL_0058:  ldfld class PlayerInventory Player::inventory
IL_005d:  ldfld class Item PlayerInventory::curDeck
IL_0062:  ldfld class [ShadowrunDTO]isogame.ItemDef Item::def
IL_0067:  stloc.0 
IL_0068:  ldarg.0 
IL_0069:  ldfld class [ShadowrunDTO]isogame.Attributes Actor::baseAttributes
IL_006e:  ldloc.0 
IL_006f:  callvirt instance int32 class [ShadowrunDTO]isogame.ItemDef::get_decking_hardening()
IL_0074:  callvirt instance void class [ShadowrunDTO]isogame.Attributes::set_armor(int32)
IL_0079:  ldarg.0 
IL_007a:  ldfld class [ShadowrunDTO]isogame.Attributes Actor::baseAttributes
IL_007f:  ldloc.0 
IL_0080:  callvirt instance int32 class [ShadowrunDTO]isogame.ItemDef::get_decking_body()
IL_0085:  callvirt instance void class [ShadowrunDTO]isogame.Attributes::set_body(int32)
IL_008a:  ldarg.0 
IL_008b:  ldfld class [ShadowrunDTO]isogame.Skills Actor::baseSkills
IL_0090:  ldloc.0 
IL_0091:  callvirt instance int32 class [ShadowrunDTO]isogame.ItemDef::get_decking_evasion()
IL_0096:  callvirt instance void class [ShadowrunDTO]isogame.Skills::set_dodge(int32)
IL_009b:  ldarg.0 
IL_009c:  ldfld class [ShadowrunDTO]isogame.Attributes Actor::baseAttributes
IL_00a1:  ldloc.0 
IL_00a2:  callvirt instance int32 class [ShadowrunDTO]isogame.ItemDef::get_decking_max_ap()
IL_00a7:  callvirt instance void class [ShadowrunDTO]isogame.Attributes::set_ap(int32)
IL_00ac:  ldarg.0 
IL_00ad:  ldfld class [ShadowrunDTO]isogame.Attributes Actor::baseAttributes
IL_00b2:  ldloc.0 
IL_00b3:  callvirt instance int32 class [ShadowrunDTO]isogame.ItemDef::get_decking_max_ip()
IL_00b8:  callvirt instance void class [ShadowrunDTO]isogame.Attributes::set_hp(int32)
IL_00bd:  ldarg.0 
IL_00be:  ldarg.0 
IL_00bf:  ldfld class PlayerInventory Player::inventory
IL_00c4:  ldfld class Item PlayerInventory::curDeck
IL_00c9:  callvirt instance int32 class Item::get_CurrentHealth()
IL_00ce:  call instance void class Actor::SetHP(int32)
IL_00d3:  ldarg.0 
IL_00d4:  ldarg.0 
IL_00d5:  ldfld class [ShadowrunDTO]isogame.Attributes Actor::baseAttributes
IL_00da:  callvirt instance int32 class [ShadowrunDTO]isogame.Attributes::get_ap()
IL_00df:  call instance void class Actor::SetAP(int32)
IL_00e4:  ldarg.0 
IL_00e5:  ldarg.0 
IL_00e6:  call int32 class StatsUtil::GetMaxArmor(class Actor)
IL_00eb:  call instance void class Actor::SetRP(int32)
IL_00f0:  ldarg.0 
IL_00f1:  ldfld class PlayerInventory Player::inventory
IL_00f6:  ldloc.0 
IL_00f7:  callvirt instance string class [ShadowrunDTO]isogame.ItemDef::get_decking_default_weapon()
IL_00fc:  callvirt instance bool class PlayerInventory::InitializeAvatarItems(string)
IL_0101:  pop 
IL_0102:  ldarg.0 
IL_0103:  ldfld class [ShadowrunDTO]isogame.CharacterInstance Player::thisCharacterInstance
IL_0108:  callvirt instance valuetype [ShadowrunDTO]isogame.SpawnType class [ShadowrunDTO]isogame.CharacterInstance::get_spawn_type()
IL_010d:  ldc.i4.2 
IL_010e:  bne.un.s IL_0137

IL_0110:  ldarg.0 
IL_0111:  ldfld class PlayerInventory Player::inventory
IL_0116:  ldfld class Item PlayerInventory::curDeck
IL_011b:  brtrue.s IL_0137

IL_011d:  ldsfld class LogChannel LogChannel::PLYR
IL_0122:  ldarg.0 
IL_0123:  call instance string class [UnityEngine]UnityEngine.Object::get_name()
IL_0128:  ldstr " is of type avatar, but has no deck.  Stats unchanged"
IL_012d:  call string string::Concat(string, string)
IL_0132:  call void class Logger::LogError(class LogChannel, string)
IL_0137:  ret 
} // end of method Player::InitializeAfterInventory
c#
edit
cil
decompiler
asked on Stack Overflow Mar 5, 2015 by i30817 • edited Mar 5, 2015 by i30817

1 Answer

0

I needed a pop after calling the first static method (which returned a object). I thought that just assigning it with stloc would pop but no such thing, i needed to add a pop after the assignement.

answered on Stack Overflow Mar 5, 2015 by i30817

User contributions licensed under CC BY-SA 3.0