【解決方法】dnlib C# を使用してファイルされた複数のモジュールを処理する方法


1 - in api.dll i load class and create a FieldDefUser

2 - in test.exe i search method name Patched and trying to replace string value with api.dll OpCodes.Ldsfld.ToInstruction(ff). but i getting error
<pre>dnlib.DotNet.Writer.ModuleWriterException: Field 'System.String Api.Class1::MyField1' (0x04000000) is not defined in this module 'Test.exe'. A field was removed that is still referenced by this module. Error occurred after metadata event BeginWriteMethodBodies during writing method 'System.Void TEST._fTest::Patched()' (0x060000A8).
   at dnlib.DotNet.DummyLogger.Log(Object sender, LoggerEvent loggerEvent, String format, Object[] args)
   at dnlib.DotNet.Writer.ModuleWriterBase.dnlib.DotNet.ILogger.Log(Object sender, LoggerEvent loggerEvent, String format, Object[] args)
   at dnlib.DotNet.Writer.Metadata.Error(String message, Object[] args)
   at dnlib.DotNet.Writer.NormalMetadata.GetRid(FieldDef fd)
   at dnlib.DotNet.Writer.Metadata.AddMDTokenProvider(IMDTokenProvider tp)
   at dnlib.DotNet.Writer.Metadata.GetToken(Object o)
   at dnlib.DotNet.Writer.MethodBodyWriter.WriteInlineField(ArrayWriter& writer, Instruction instr)
   at dnlib.DotNet.Writer.MethodBodyWriterBase.WriteOperand(ArrayWriter& writer, Instruction instr)
   at dnlib.DotNet.Writer.MethodBodyWriterBase.WriteInstruction(ArrayWriter& writer, Instruction instr)
   at dnlib.DotNet.Writer.MethodBodyWriterBase.WriteInstructions(ArrayWriter& writer)
   at dnlib.DotNet.Writer.MethodBodyWriter.WriteTinyHeader()
   at dnlib.DotNet.Writer.MethodBodyWriter.Write()
   at dnlib.DotNet.Writer.Metadata.WriteMethodBodies()
   at dnlib.DotNet.Writer.Metadata.Create()
   at dnlib.DotNet.Writer.Metadata.CreateTables()
   at dnlib.DotNet.Writer.ModuleWriter.WriteImpl()
   at dnlib.DotNet.Writer.ModuleWriterBase.Write(Stream dest)
   at dnlib.DotNet.Writer.ModuleWriterBase.Write(String fileName)
   at dnlib.DotNet.ModuleDef.Write(String filename)  
<pre lang="C#"><pre>static void Main(string[] args)
 {
     Console.WriteLine(args[0]);
     string _sRoot = args[0];
     string _sRootApi = args[0].Replace("Test.exe", "Api.dll");
     //AssemblyDef assembly = AssemblyDef.Load(_sRoot);
     ModuleContext modCtx = ModuleDefMD.CreateModuleContext();
     ModuleDefMD module = ModuleDefMD.Load(_sRoot, modCtx);


     ModuleContext Api_modCtx = ModuleDefMD.CreateModuleContext();
     ModuleDefMD Api_module = ModuleDefMD.Load(_sRootApi, Api_modCtx);
     try
     {
         Load_DLL_ClassName(Api_module);
         Patched(module, Api_module);
     }
     catch (Exception ex)
     {
         MessageBox.Show(ex.ToString());
     }

     try
     {
         Api_module.Write(_sRootApi.Replace(".dll", "of.dll"));
         module.Write(args[0].Replace(".exe", "of.exe"));

     }
     catch (Exception ex)
     {
         File.WriteAllText(Application.StartupPath.ToString() + "\\Error.txt", ex.ToString());
         MessageBox.Show(ex.ToString());
     }
 }
 static TypeDef Class1;
 public static void Load_DLL_ClassName(ModuleDef module)
 {
     foreach (TypeDef type in module.Types)
     {
         if (type.Name.ToString() == "Class1")
         {
             Class1 = type;
             break;
         }
     }
 }
 static int _inum = 0;
 public static FieldDefUser CreateFiled(ModuleDef module, string Data)
 {
     // Create a public static System.Int32 field called MyField
     var field1 = new FieldDefUser("MyField" + _inum.ToString(),
                     new FieldSig(module.CorLibTypes.String),
                     FieldAttributes.Public | FieldAttributes.Static);
     Class1.Fields.Add(field1);
     return field1;
 }
 public static void Patched(ModuleDef module, ModuleDef Api_module)
 {
     foreach (TypeDef type in module.Types)
     {
         foreach (MethodDef method in type.Methods)
         {
             if (method.Name != "Patched")
             {
                 continue;
             }
             if (method.Body == null) continue;


             method.Body.SimplifyBranches();
             for (int i = 0; i < method.Body.Instructions.Count; i++)
             {
                 if (method.Body.Instructions[i].OpCode == OpCodes.Ldstr)
                 {
                     string _sValue = method.Body.Instructions[i].Operand.ToString();
                     FieldDefUser ff = CreateFiled(module, _sValue);
                     _inum++;
                     method.Body.Instructions[i].OpCode = OpCodes.Nop;
                     method.Body.Instructions.Insert(i + 1, OpCodes.Ldsfld.ToInstruction(ff));
                     i += 1;
                 }
             }
         }
     }
 }

私が試したこと:

please check code. i think there are something wrong. please help me.

解決策 1

このプロジェクトは Github プロジェクトです。 Github プロジェクトが膨大にあることを考えると、プロジェクトの作成者またはプロジェクトに精通している人がコード プロジェクト QA を参照していることは非常に幸運です。 あなたがすべきことは問題を提起することです ここ[^] これはこのライブラリに関する活発な議論のポイントになると思われるためです。

コメント

タイトルとURLをコピーしました