使用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
Dictionaryfield, and there's a syntax error inGetCorLibTypeSig. - Invalid
newobjTarget: You're passing theDictionarytype itself tonewobj, but this opcode requires a reference to a constructor method, not the raw type definition. - Missing Generic Instantiation:
Dictionaryis 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
- Proper Generic Type Handling: We first fetch the raw generic
Dictionarytype, then create an instantiated version with your target key/value types (swapInt32andObjectif you need a different Dictionary variant). - Valid Constructor Reference: The
newobjopcode 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. - Clean IL Flow: We clear existing instructions to avoid conflicts with the default
Retinstruction, then build a logical sequence: push capacity → create instance → store in field → return. - Fixed Field Definition: The field now uses the properly instantiated generic
Dictionarytype, so dnlib and dnSpy recognize it as a valid type.
内容的提问来源于stack exchange,提问作者Waze Android
相关产品推荐
相关产品推荐

