第七色在线视频,2021少妇久久久久久久久久,亚洲欧洲精品成人久久av18,亚洲国产精品特色大片观看完整版,孙宇晨将参加特朗普的晚宴

為了賬號(hào)安全,請(qǐng)及時(shí)綁定郵箱和手機(jī)立即綁定
已解決430363個(gè)問(wèn)題,去搜搜看,總會(huì)有你想問(wèn)的

反編譯.NET Core中的匿名方法IL

反編譯.NET Core中的匿名方法IL

C#
GCT1015 2023-07-22 16:24:18
我有這個(gè)方法public void Add(Action<Cursor> action){    // Decompile `action` to C#}在方法內(nèi)部,我想將內(nèi)部的匿名方法反編譯action 為 C# 代碼,或 C# 代碼的 AST 表示形式。我嘗試使用Mono.Ceciland ICSharpCode.Decompiler(來(lái)自ILSpy存儲(chǔ)庫(kù)),但我找不到反編譯匿名方法的方法,因?yàn)檫@兩個(gè)庫(kù)都要求您從物理位置加載程序集并通過(guò)類(lèi)型圖搜索方法,這看起來(lái)非常復(fù)雜,尤其是在尋找匿名方法時(shí)。有沒(méi)有辦法使用該方法的 IL Byte 數(shù)組,并將其反編譯為 C#?public void Add(Action<Cursor> action){    var il = action.Method.GetMethodBody().GetILAsByteArray();    var ast = decompiler.DecompileIL(il); // Does such decompiler exist?}
查看完整描述

1 回答

?
天涯盡頭無(wú)女友

TA貢獻(xiàn)1831條經(jīng)驗(yàn) 獲得超9個(gè)贊

使用該ICSharpCode.Decompiler庫(kù)(來(lái)自ILSpy存儲(chǔ)庫(kù)),我能夠反編譯 lambda 方法。

像這樣

public void Add(Action<Cursor> action)

{

? ? // Get the assembly in which the lambda resides

? ? var asm = Assembly.GetCallingAssembly();

? ? var file = asm.Location;


? ? // Create a resolver (a callback for resolving referenced assemblies during decompilation)

? ? var resolver = new CustomAssemblyResolver(asm);

? ? // Create an instance of decompiler

? ? var decompiler = new CSharpDecompiler(file, resolver, new DecompilerSettings());


? ? // Get an "EntityHandle" instance for the lambda's underlying method

? ? var method = MetadataTokenHelpers.TryAsEntityHandle(action.Method.MetadataToken);?


? ? var ast = decompiler.Decompile(new List<EntityHandle>() { method.Value });

}

正如我所提到的,您CSharpDecompiler為實(shí)例提供了一個(gè)解析器 ( IAssemblyResolver),其任務(wù)是在反編譯過(guò)程中加載引用的程序集。


ICSharpCode.Decompiler有一個(gè)UniversalAssemblyResolver(源),它通過(guò)搜索文件系統(tǒng)中的公共文件夾來(lái)完成工作(它接收一個(gè)框架版本以知道在哪里搜索)。我不喜歡它,因?yàn)樗僭O(shè)太多并且需要太多信息(我并不總是知道運(yùn)行時(shí)的框架或其他部分),因此我創(chuàng)建了自己的解析器,它遍歷程序集圖(從調(diào)用程序集開(kāi)始)。


class CustomAssemblyResolver : IAssemblyResolver

{

? ? private Dictionary<string, Assembly> _references;


? ? public CustomAssemblyResolver(Assembly asm)

? ? {

? ? ? ? _references = new Dictionary<string, Assembly>();

? ? ? ? var stack = new Stack<Assembly>();

? ? ? ? stack.Push(asm);


? ? ? ? while (stack.Count > 0)

? ? ? ? {

? ? ? ? ? ? var top = stack.Pop();

? ? ? ? ? ? if (_references.ContainsKey(top.FullName)) continue;


? ? ? ? ? ? _references[top.FullName] = top;


? ? ? ? ? ? var refs = top.GetReferencedAssemblies();

? ? ? ? ? ? if (refs != null && refs.Length > 0)

? ? ? ? ? ? {

? ? ? ? ? ? ? ? foreach (var r in refs)

? ? ? ? ? ? ? ? {

? ? ? ? ? ? ? ? ? ? stack.Push(Assembly.Load(r));

? ? ? ? ? ? ? ? }

? ? ? ? ? ? }

? ? ? ? }


? ? ? ? ;

? ? }


? ? public PEFile Resolve(IAssemblyReference reference)

? ? {

? ? ? ? var asm = _references[reference.FullName];

? ? ? ? var file = asm.Location;

? ? ? ? return new PEFile(file, new FileStream(file, FileMode.Open, FileAccess.Read), PEStreamOptions.Default, MetadataReaderOptions.Default);

? ? }


? ? public PEFile ResolveModule(PEFile mainModule, string moduleName)

? ? {

? ? ? ? var baseDir = Path.GetDirectoryName(mainModule.FileName);

? ? ? ? var moduleFileName = Path.Combine(baseDir, moduleName);

? ? ? ? if (!File.Exists(moduleFileName))

? ? ? ? {

? ? ? ? ? ? throw new Exception($"Module {moduleName} could not be found");

? ? ? ? }

? ? ? ? return new PEFile(moduleFileName, new FileStream(moduleFileName, FileMode.Open, FileAccess.Read), PEStreamOptions.Default, MetadataReaderOptions.Default);

? ? }

}

我不知道這是否是適合所有用例的最佳方法,但它對(duì)我來(lái)說(shuō)非常有效,至少到目前為止是這樣。


查看完整回答
反對(duì) 回復(fù) 2023-07-22
  • 1 回答
  • 0 關(guān)注
  • 240 瀏覽

添加回答

舉報(bào)

0/150
提交
取消
微信客服

購(gòu)課補(bǔ)貼
聯(lián)系客服咨詢(xún)優(yōu)惠詳情

幫助反饋 APP下載

慕課網(wǎng)APP
您的移動(dòng)學(xué)習(xí)伙伴

公眾號(hào)

掃描二維碼
關(guān)注慕課網(wǎng)微信公眾號(hào)