private static void Retarget(TypeDefinition type, DllImportMap map, DllImports imports) { foreach (var nested in type.NestedTypes) { Retarget(nested, map, imports); } foreach (MethodDefinition md in type.Methods) { if (!md.HasBody) { continue; } for (int i = 0; i < md.Body.Instructions.Count; i++) { Instruction ins = md.Body.Instructions[i]; if (ins.OpCode == OpCodes.Call) { MethodDefinition method_operand = ins.Operand as MethodDefinition; if (method_operand == null) { continue; } PInvokeInfo pinfo = method_operand.PInvokeInfo; if (pinfo == null) { continue; } ImportKey key = new ImportKey(pinfo.Module.Name, pinfo.EntryPoint); if (imports.ContainsKey(key)) { //Console.WriteLine ("{0} is a pinvoke, {1}/{2}", method_operand, pinfo.EntryPoint, pinfo.Module.Name); if (map.ContainsKey(key)) { Console.WriteLine("retargeting reference to method method {0}/{1}", key.module_name, key.entry_point); var il = md.Body.GetILProcessor(); MethodDefinition mapped_method = map[key]; MethodReference mapped_ref; mapped_ref = type.Module.Import(mapped_method); Instruction callMethod = il.Create(OpCodes.Call, mapped_ref); il.Replace(ins, callMethod); } else { Console.WriteLine("WARNING: no map entry for method {0}/{1}", key.module_name, key.entry_point); } } } } } }
public override bool Equals(object o) { ImportKey key = o as ImportKey; if (key == null) { return(false); } return(key.module_name == module_name && key.entry_point == entry_point); }
private static DllImports CollectDllImports(AssemblyDefinition assembly) { DllImports imports = new DllImports(); foreach (TypeDefinition t in assembly.MainModule.GetAllTypes()) { if (t.Name == "<Module>") { continue; } if (t.IsSpecialName || t.IsRuntimeSpecialName) { continue; } foreach (MethodDefinition md in t.Methods) { if (md.IsSpecialName) { continue; } if (IsFinalizer(md)) { continue; } PInvokeInfo pinfo = md.PInvokeInfo; if (pinfo == null) { continue; } // Console.WriteLine ("{0} is a pinvoke, hashcode = {1}", md, md.GetHashCode()); ImportKey key = new ImportKey(pinfo.Module.Name, pinfo.EntryPoint); if (imports.ContainsKey(key)) { Console.WriteLine("WARNING: pinvoke {0}/{1} shows up more than once in input assembly", key.module_name, key.entry_point); } else { imports.Add(key, md); } } } return(imports); }
private static DllImportMap BuildMap(string map_assembly) { DllImportMap map = new DllImportMap(); var assembly = AssemblyDefinition.ReadAssembly(map_assembly); foreach (TypeDefinition t in assembly.MainModule.GetAllTypes()) { if (t.Name == "<Module>") { continue; } if (t.IsSpecialName || t.IsRuntimeSpecialName) { continue; } foreach (MethodDefinition md in t.Methods) { if (md.IsSpecialName) { continue; } if (IsFinalizer(md)) { continue; } CustomAttribute attr = GetMapDllImportAttribute(md); if (attr == null) { continue; } ImportKey key = new ImportKey(attr.ConstructorArguments [0].Value.ToString(), md.Name); map.Add(key, md); } } return(map); }