The problem ended up being two methods with the same name but different signatures. This was straightforward enough to solve once I knew what the problem was. I was 99% sure I wasn't dealing with any methods that shared names, but there was that pesky 1%...
Thanks, Paul Buonopane On Thu, May 26, 2011 at 11:23 AM, Gábor Kozár <[email protected]> wrote: > You could try cleaning up your code a bit (e.g. introduce a local variable > for m.Body.Instruction[i], use the 'as' keyword instead of 'is' + casting, > etc.). > Also note that your code will produce invalid IL if any of the code you > change uses generics. Resolve() will drop all your generic arguments. This > issue has been discussed before a number of times, see this and this > discussion (note that in both it is assumed that you're using the latest > version of Cecil). > Apart from that, I can only give the same two hints I've already given: > - Use the latest version of Cecil from GitHub > - Use PEVerify to find out exactly what's wrong with your assembly. > 2011/5/26 Paul <[email protected]> >> >> Okay, now the program decompiles properly (the IL changes the way I >> want it to), but it still doesn't run correctly. I'm receiving an >> InvalidProgramException at runtime as soon as the JIT compiler hits >> one of the modified instructions. "JIT Compiler encountered an >> internal limitation." Could this have more to do with how I'm >> importing the type? Here's my method for that: >> >> private static void SwapTypes(string type) >> { >> string search = "Namespace." + type; >> TypeReference replace = >> Module.Import(Type.GetType(search + "New")); >> Console.WriteLine("Swapping {0} out for {1}", >> search, replace.Name); >> SwapTypes(search, replace); >> } >> >> Thanks, >> Paul Buonopane >> >> >> >> On Thu, May 26, 2011 at 9:38 AM, Paul <[email protected]> wrote: >> > A tad messy, but I think I finally have it working: >> > private static void SwapTypes(string search, >> > TypeReference replace) >> > { >> > foreach (TypeDefinition t in Module.Types) >> > { >> > foreach (FieldDefinition f in t.Fields) >> > { >> > if (f.FieldType.FullName == >> > search) >> > { >> > f.FieldType = replace; >> > } >> > } >> > foreach (MethodDefinition m in t.Methods) >> > { >> > if >> > (m.ReturnType.ReturnType.FullName == search) >> > { >> > m.ReturnType.ReturnType = >> > replace; >> > } >> > foreach (ParameterDefinition p in >> > m.Parameters) >> > { >> > if >> > (p.ParameterType.FullName == search) >> > { >> > p.ParameterType = >> > replace; >> > } >> > } >> > if (m.HasBody) >> > { >> > foreach >> > (VariableDefinition v in m.Body.Variables) >> > { >> > if >> > (v.VariableType.FullName == search) >> > { >> > >> > v.VariableType = replace; >> > } >> > } >> > for (int i = 0; i < >> > m.Body.Instructions.Count; i++) >> > { >> > if >> > (m.Body.Instructions[i].Operand is TypeReference && >> > ((TypeReference)m.Body.Instructions[i].Operand).FullName == search) >> > { >> > >> > m.Body.CilWorker.Replace(m.Body.Instructions[i], >> > m.Body.CilWorker.Create(m.Body.Instructions[i].OpCode, replace)); >> > } >> > else if >> > (m.Body.Instructions[i].Operand is MethodReference && >> > ((MethodReference)m.Body.Instructions[i].Operand).DeclaringType.FullName >> > == search) >> > { >> > >> > m.Body.CilWorker.Replace(m.Body.Instructions[i], >> > m.Body.CilWorker.Create(m.Body.Instructions[i].OpCode, >> > Module.Import(GetMethod(replace.Resolve(), >> > ((MethodReference)m.Body.Instructions[i].Operand).Name)))); >> > } >> > else if >> > (m.Body.Instructions[i].Operand is FieldReference && >> > ((FieldReference)m.Body.Instructions[i].Operand).DeclaringType.FullName >> > == search) >> > { >> > >> > m.Body.CilWorker.Replace(m.Body.Instructions[i], >> > m.Body.CilWorker.Create(m.Body.Instructions[i].OpCode, >> > Module.Import(GetField(replace.Resolve(), >> > ((FieldReference)m.Body.Instructions[i].Operand).Name)))); >> > } >> > } >> > } >> > } >> > } >> > } >> > Thanks, >> > Paul Buonopane >> > >> > >> > >> > On Thu, May 26, 2011 at 8:50 AM, Gábor Kozár <[email protected]> >> > wrote: >> >> No wonder, you have ignored references to the members of your types. >> >> Also, use peverify (it's in Microsoft SDKs - the full path on my >> >> machine: >> >> C:\Program Files (x86)\Microsoft SDKs\Windows\v7.0A\Bin) to find out >> >> exactly >> >> what's wrong with your application. >> >> 2011/5/26 Paul <[email protected]> >> >>> >> >>> Here's what I came up with, but it results in an invalid program: >> >>> >> >>> private static void SwapTypes(TypeReference search, >> >>> TypeReference replace) >> >>> { >> >>> foreach (TypeDefinition t in Module.Types) >> >>> { >> >>> foreach (FieldDefinition f in t.Fields) >> >>> { >> >>> if (f.FieldType == search) >> >>> { >> >>> f.FieldType = replace; >> >>> } >> >>> } >> >>> foreach (MethodDefinition m in >> >>> t.Methods) >> >>> { >> >>> if (m.ReturnType.ReturnType == >> >>> search) >> >>> { >> >>> m.ReturnType.ReturnType >> >>> = >> >>> replace; >> >>> } >> >>> foreach (ParameterDefinition p >> >>> in >> >>> m.Parameters) >> >>> { >> >>> if (p.ParameterType == >> >>> search) >> >>> { >> >>> p.ParameterType >> >>> = >> >>> replace; >> >>> } >> >>> } >> >>> if (m.HasBody) >> >>> { >> >>> foreach >> >>> (VariableDefinition >> >>> v in m.Body.Variables) >> >>> { >> >>> if >> >>> (v.VariableType >> >>> == search) >> >>> { >> >>> >> >>> v.VariableType = replace; >> >>> } >> >>> } >> >>> foreach (Instruction i >> >>> in >> >>> m.Body.Instructions) >> >>> { >> >>> if (i.Operand >> >>> is >> >>> TypeReference && (TypeReference)i.Operand == search) >> >>> { >> >>> >> >>> i.Operand = >> >>> replace; >> >>> } >> >>> } >> >>> } >> >>> } >> >>> } >> >>> } >> >>> >> >>> >> >>> Thanks, >> >>> Paul Buonopane >> >>> >> >>> >> >>> >> >>> On Thu, May 26, 2011 at 5:21 AM, Gábor Kozár <[email protected]> >> >>> wrote: >> >>> > It most certainly is possible, but it'll be not too easy to code. >> >>> > Basically >> >>> > what you need to do is find all references to Lightning1 or its >> >>> > members >> >>> > in >> >>> > the assembly you're processing, and replace them with the >> >>> > appropriate >> >>> > reference to Lightning2, or its members. >> >>> > Go through all types in the assembly, and check their base type, and >> >>> > the >> >>> > generic arguments of the base type. Then go through all the methods >> >>> > in >> >>> > the >> >>> > type (including the property get_* and set_* methods - maybe even >> >>> > the >> >>> > event >> >>> > add_* and remove_* methods), fix their parameter and local variable >> >>> > types, >> >>> > then iterate through the instructions to find all references to >> >>> > Lightning1 >> >>> > or its member. >> >>> > I believe the easiest way to achieve this would be to check the >> >>> > Operand >> >>> > of >> >>> > each instruction, and see if it's a TypeReference. If it is, check >> >>> > if it >> >>> > is >> >>> > Lightning1, and also check its generic arguments. If it's not a >> >>> > TypeReference, see if it's a MemberReference whose DeclaringType is >> >>> > Lightning1, or has Lightning1 as a generic argument. >> >>> > If Lightning1 is an attribute type, make sure to also check the >> >>> > CustomAttributes of all eligible members. I think that'll cover >> >>> > everything. >> >>> > I'm afraid I don't know any easier way to achieve this. Good luck! >> >>> > 2011/5/26 Paul Buonopane <[email protected]> >> >>> >> >> >>> >> Is it possible to inject a type in another's place? For example, >> >>> >> if I >> >>> >> have Lighting1 and Lighting2, the two being almost identical, could >> >>> >> I >> >>> >> inject >> >>> >> Lighting2 in place of Lighting1? If so, what would it entail? -- >> >>> >> -- >> >>> >> mono-cecil >> >>> > >> >>> > -- >> >>> > -- >> >>> > mono-cecil >> >>> >> >>> -- >> >>> -- >> >>> mono-cecil >> >> >> >> -- >> >> -- >> >> mono-cecil >> > >> >> -- >> -- >> mono-cecil > > -- > -- > mono-cecil -- -- mono-cecil
