ioncodes / dnpatch

.NET Patcher library using dnlib
MIT License
313 stars 48 forks source link

Exception when saving #48

Closed fl380 closed 6 years ago

fl380 commented 6 years ago

Hello,

Thank you for providing a very useful library.

I'm unfortunately having a problem with a simple example:

Exception:

dnlib.DotNet.Writer.ModuleWriterException
  HResult=0x80131500
  Message=Found some other method's instruction or a removed instruction. You probably removed an instruction that is the target of a branch instruction or an instruction that's the first/last instruction in an exception handler.
  Source=dnlib
  StackTrace:
   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.dnlib.DotNet.Writer.IWriterError.Error(String message)
   at dnlib.DotNet.Writer.MethodBodyWriter.ErrorImpl(String message)
   at dnlib.DotNet.Writer.MethodBodyWriterBase.GetOffset(Instruction instr)
   at dnlib.DotNet.Writer.MethodBodyWriterBase.WriteShortInlineBrTarget(BinaryWriter writer, Instruction instr)
   at dnlib.DotNet.Writer.MethodBodyWriterBase.WriteOperand(BinaryWriter writer, Instruction instr)
   at dnlib.DotNet.Writer.MethodBodyWriterBase.WriteInstruction(BinaryWriter writer, Instruction instr)
   at dnlib.DotNet.Writer.MethodBodyWriterBase.WriteInstructions(BinaryWriter writer)
   at dnlib.DotNet.Writer.MethodBodyWriter.WriteFatHeader()
   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)
   at dnpatch.PatchHelper.Save(String name)
   at dnpatch.Patcher.Save(String name)
   at My_Patcher.Program.Main(String[] args) in E:\Documents\Visual Studio 2017\My_Patcher\My_Patcher\Program.cs:line 25

and this is the code

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using dnlib.DotNet;
using dnlib.DotNet.Emit;
using dnpatch;

namespace My_Patcher
{
    class Program
    {
        static void Main(string[] args)
        {
            Patcher p = new Patcher("Test.1.Server.exe");
            Target target = new Target()
            {
                Namespace = "ns0",
                Class = "GClass2",
                Method = "method_30",
                Indices = new[] { 26, 27 }
            };
            p.RemoveInstruction(target);
            p.Save("Test.1.Server_patched.exe");
        }
    }
}

I've downloaded and referenced dnpatch.dll and dnlib.dll from the releases zip and don't have any errors or warnings when compiling.

I'll be very grateful for your assistance please.

thanks

ioncodes commented 6 years ago

Does it work if you do Patcher("Server.exe", true)?

fl380 commented 6 years ago

no, unfortunately not, same exception message

ioncodes commented 6 years ago

Can you please send me a screenshot of that method? I recommend using dnSpy for this. Please make a screenshot of the C# and IL version of the method.

fl380 commented 6 years ago
0   0000    ldc.i4  0x11E90000
1   0005    stloc   V_0 (0)
2   0009    ldc.i4  0x75234B61
3   000E    stloc   V_0 (0)
4   0012    ldloca  V_0 (0)
5   0016    ldind.i2
6   0017    conv.i2
7   0018    ldc.i4  0x68FE4B61
8   001D    stloc   V_0 (0)
9   0021    ldloca  V_0 (0)
10  0025    ldind.i2
11  0026    conv.i2
12  0027    ceq
13  0029    switch  [14 (003A), 14 (003A), 14 (003A)]
14  003A    ldc.i4  0x19200001
15  003F    stloc   V_0 (0)
16  0043    ldloca  V_0 (0)
17  0047    ldind.i2
18  0048    conv.i2
19  0049    brtrue.s    20 (004B) ldc.i4 0x6D9C0000
20  004B    ldc.i4  0x6D9C0000
21  0050    stloc   V_0 (0)
22  0054    ldloca  V_0 (0)
23  0058    ldind.i2
24  0059    conv.i2
25  005A    brtrue.s    26 (005C) ldarg.0 
26  005C    ldarg.0
27  005D    call    instance void ns0.GClass2::method_29()
28  0062    ret
namespace ns0
{
    // Token: 0x0200000C RID: 12
    public partial class GClass2 : GInterface3
    {
        // Token: 0x0600006D RID: 109 RVA: 0x000094B4 File Offset: 0x000076B4
        [CompilerGenerated]
        private void method_30(object sender, EventArgs e)
        {
            short num = (short)300482560;
            num = (short)1965247329;
            short num2 = num;
            num = (short)1761495905;
            switch (num2 == num)
            {
            default:
                num = (short)421527553;
                if (num == 0)
                {
                }
                num = (short)1838940160;
                if (num == 0)
                {
                }
                this.method_29();
                return;
            }
        }
    }
}

I'm attempting to remove this call

26  005C    ldarg.0
27  005D    call    instance void ns0.GClass2::method_29()
ioncodes commented 6 years ago

I see, what happens if you just empty the entire body?

fl380 commented 6 years ago

That seems to work, thank you.

I hope that you plan to continue developing this library, it's very useful!

ioncodes commented 6 years ago

I am actually going to work on it again now since I need it personally for a few projects. I will only work on the v1 branch tho!

fl380 commented 6 years ago

Excellent!