2016-06-26 8 views
1

2つのアセンブリがあります。 「patchsrc.exe」と「アセンブリ-CSharp.dll」
私はAssembly-CSharp.dll::Class::Method()アセンブリを保存中のMono.CecilのArgumentException

からpatchsrc.exe::TXDLLLoader.Program::Main()
からすべてのIL-命令と、すべてのIL-手順を取得、私は最初のコードからオペコードを「RET」を除去し、その後にそれらをマージ1つの機能。

私はそれを保存しようとすると、私はこの取得:

型 'System.ArgumentExceptionの' の未処理の例外はMono.Cecil.dll

で発生しました追加情報:メンバー「するSystem.Reflectionを.Assembly System.Reflection.Assembly :: LoadFileが(可能System.String「)別のモジュールで宣言され、私はこのコードを使用してい

をインポートする必要がある。

var assembly = AssemblyDefinition.ReadAssembly("./game_Data/Managed/Assembly-CSharp.dll"); 
var assembly_patchsrc = AssemblyDefinition.ReadAssembly("./patchsrc.exe"); 


Console.WriteLine("searching.."); 

Collection<Instruction> instrForPatch = new Collection<Instruction>(); 

foreach (var methodDefinition in from type in assembly_patchsrc.MainModule.Types from methodDefinition in type.GetMethods() where methodDefinition.FullName.Contains("TXDLLLoader.Program::Main()") select methodDefinition) 
{ 
    Console.WriteLine("Found some patch instructions!"); 

    var instr_patchsrc = methodDefinition.Body.Instructions; 

    instr_patchsrc.Remove(instr_patchsrc.Last()); 

    for (var i = 0; i <= instr_patchsrc.Count - 1; i++) 
    { 
     instrForPatch.Add(instr_patchsrc[i]); 
    } 
} 

Console.ReadLine(); 

foreach (var instr in from typeDef in assembly.MainModule.Types 
      from method in typeDef.Methods 
      where typeDef.Name.Equals("Class") && method.Name.Equals("Method") 
      select method.Body.Instructions) 
{ 
    Collection<Instruction> oldList = new Collection<Instruction>(); 

    for (var i = 0; i<=instr.Count-1; i++) 
    { 
     oldList.Add(instr[i]); 
    } 

    instr.Clear(); 

    Console.WriteLine($"Begin injecting patch instructions.. [{instrForPatch.Count}]"); 

    foreach (var instruction in instrForPatch) 
    { 
     Console.WriteLine($"Adding instruction: [{instruction}]"); 
     instr.Add(instruction); 
    } 

    Console.WriteLine($"Begin injecting old instructions.. [{oldList.Count}]"); 

    foreach (var instruction in oldList) 
    { 
     Console.WriteLine($"Adding instruction: [{instruction}]"); 
     instr.Add(instruction); 
    } 

    Console.WriteLine("patched!"); 
} 

Console.WriteLine("saving asssembly.."); 
assembly.Write("./game_Data/Managed/Assembly-CSharp_patched.dll"); 

どうすれば解決できますか?

+1

Mono.Cecilはオープンソースです。 GitHub上でそのコードを見つけ出し、それをデバッグして、例外につながるものを見つけてください。 –

+0

@LexLiどのように関連性があるのか​​よく分かりませんが、例外メッセージはすでに何が例外につながっているかを示しています。 – svick

答えて

2

Cecil documentation on importingで説明されているように、使用しているone to LoadFile()のようなメンバー参照は、モジュールに適用されます。別のモジュールで参照を使用する場合は、まずそれをインポートする必要があります。 patchsrcでどんな命令が出るか分からないので、命令のオペランドをインポートできる必要があります。

static Instruction ImportInstruction(Instruction instruction, ModuleDefinition module) 
{ 
    object operand = instruction.Operand; 

    var fieldOperand = operand as FieldReference; 
    if (fieldOperand != null) 
     return Instruction.Create(instruction.OpCode, module.Import(fieldOperand)); 

    var methodOperand = operand as MethodReference; 
    if (methodOperand != null) 
     return Instruction.Create(instruction.OpCode, module.Import(methodOperand)); 

    var typeOperand = operand as TypeReference; 
    if (typeOperand != null) 
     return Instruction.Create(instruction.OpCode, module.Import(typeOperand)); 

    return instruction; 
} 

をそしてpatchsrc命令を追加するとき、それを使用します:それを行うには、ヘルパーメソッドを書くことができます

foreach (var instruction in instrForPatch) 
{ 
    Console.WriteLine($"Adding instruction: [{instruction}]"); 
    instr.Add(ImportInstruction(instruction, assembly.MainModule)); 
} 
+0

ありがとうございました! – NulledCoder

関連する問題