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");
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)
{
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;
}
}
}
}
}
What I have tried:
please check code. i think there are something wrong. please help me.