You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用dnlib与IL代码创建Dictionary时遇问题求助

Fixing Dictionary Creation via dnlib IL Injection

Let's break down the issues in your code and fix them step by step—these mistakes are generating invalid IL that crashes dnSpy:


Key Problems in Your Current Code

  • Broken Field Type Definition: You didn't specify generic type parameters for the Dictionary field, and there's a syntax error in GetCorLibTypeSig.
  • Invalid newobj Target: You're passing the Dictionary type itself to newobj, but this opcode requires a reference to a constructor method, not the raw type definition.
  • Missing Generic Instantiation: Dictionary is a generic type (Dictionary<TKey, TValue>), so you need to create an instantiated version of it before using it for fields or constructors.

Corrected Code Example

Assuming you want a Dictionary<int, object> (adjust the generic types to match your use case):

MethodDef cctor = Module.GlobalType.FindOrCreateStaticConstructor();
IList<Instruction> inst = cctor.Body.Instructions;

// 1. Get the generic Dictionary`2 type from mscorlib
TypeDefOrRef dictGenericType = Module.CorLibTypes.GetTypeRef("System.Collections.Generic", "Dictionary`2");

// 2. Instantiate the generic type with your desired key/value types (int as key, object as value here)
TypeSig dictType = new GenericInstSig(dictGenericType, 
    Module.CorLibTypes.Int32.TypeSig, 
    Module.CorLibTypes.Object.TypeSig);

// 3. Create the static field with the correctly typed Dictionary
var Global_Array = new FieldDefUser(
    "field_obfuscator_array", 
    dictType, 
    FieldAttributes.Public | FieldAttributes.Static);
Module.GlobalType.Fields.Add(Global_Array);

// 4. Get the Dictionary constructor that accepts an int capacity parameter
MethodSig dictCtorSig = MethodSig.CreateInstance(Module.CorLibTypes.Void, Module.CorLibTypes.Int32.TypeSig);
MemberRef dictCtor = new MemberRefUser(Module, ".ctor", dictCtorSig, dictGenericType);

// 5. Build a valid IL sequence for the static constructor
inst.Clear(); // Start fresh to avoid conflicts with existing Ret instructions
inst.Add(new Instruction(OpCodes.Ldc_I4, 100000)); // Push the initial capacity value
inst.Add(new Instruction(OpCodes.Newobj, dictCtor)); // Create the Dictionary instance
inst.Add(new Instruction(OpCodes.Stsfld, Global_Array)); // Store the instance in the static field
inst.Add(new Instruction(OpCodes.Ret)); // Return from the static constructor

What Changed & Why

  1. Proper Generic Type Handling: We first fetch the raw generic Dictionary type, then create an instantiated version with your target key/value types (swap Int32 and Object if you need a different Dictionary variant).
  2. Valid Constructor Reference: The newobj opcode now points to the correct constructor (the one that takes an integer for initial capacity) instead of the type itself—this is required for valid IL.
  3. Clean IL Flow: We clear existing instructions to avoid conflicts with the default Ret instruction, then build a logical sequence: push capacity → create instance → store in field → return.
  4. Fixed Field Definition: The field now uses the properly instantiated generic Dictionary type, so dnlib and dnSpy recognize it as a valid type.

内容的提问来源于stack exchange,提问作者Waze Android

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.15 04:31:54