2012-08-23 76 views
3

我有一個C#DLL與成員類似以下內容:如何用Mono.Cecil重新拋出一個ILAsm拋出?

public void DoStuff(int i) { 
    try { 
     something.InnerDoStuff(i); 
    } 
    catch (Exception ex) { 
     throw ex; 
    } 
} 

我想出如何讓throw opcode:用rethrow opcode

Add-Type -Path 'c:\Program Files\ILSpy2\Mono.Cecil.dll' 
Add-Type -Path 'c:\Program Files\ILSpy2\Mono.Cecil.pdb.dll' 

$dll = 'c:\Program Files\ZippySoft\Something\foo.dll' 
$assemblyDefinition = [Mono.Cecil.AssemblyDefinition]::ReadAssembly($dll); 

$doThingsIlAsm = (
    (
     $assemblyDefinition.MainModule.Types ` 
      | where { $_.Name -eq 'DoerOfThings' } ` 
      | select -first 1 * 
    ).Methods | where { $_.Name -eq 'DoStuff' } 
).Body.Instructions 

$throwOp = ($doThingsIlAsm | where { 
    $_.OpCode.Name -eq 'throw' 
}) 

我的問題是如何更換拋操作碼?

+0

您的標題問如何「替換」的操作碼,但你問只是如何「搞定」了。你對哪些感興趣? – latkin

回答

3

我相信你可以得到一個ILProcessor爲你的方法,Create一個rethrow操作碼,然後用處理器的Replace方法來交換throwrethrow

而不是立即得到您的方法身體的指示,得到一個方法體的參考,並使用它來得到myMethod.Body.GetIlProcessor以及myMethod.Body.Instructions。然後,您可以像現在一樣查找throw指令,並使用Replace方法將其交換出去。

這是非常未經測試,但我認爲它的要點是:

$throw = # your existing stuff 
$il = myMethod.Body.GetIlProcessor() 
$rethrow = $il.Create(OpCodes.Rethrow) # not sure about the powershell syntax for enums 
$il.Replace($throw, $rethrow) 
+0

看起來不錯。現在我需要弄清楚如何保存它。 –

+1

@JustinDearing只需在你的assemblyDefinition中調用Write方法即可。 –