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