在.NET核心和Xamarin中使用由IL编译的程序集
使用对我有用的解决方案进行更新.请参阅此问题的底部. 上下文: 我需要一种方法来评估通用类型的大小,以便计算数组长度以适合某个字节大小.基本上, sizeof类似于C/C ++提供的. c c#'s sizeof和 marshal.sizeof.sizeof 由于其许多局限性而不适合此. 考虑到这一点,我在IL中编写了一个汇编,该组件能够通过sizeof opcode寻找的功能.我知道它本质上是通过参考类型评估IntPtr.Size. i将其重复为.NET标准&Core,引用了我认为是Mscorlib的正确等效物.请注意,IL编译良好,此问题是关于另一个问题的. 代码: 每个目标框架的标题: .net :( Windows \ Microsoft.net \ Framework \ V4.0.30319 \ Ilasm.exe) .assembly extern mscorlib {} .net标准:( ilasm从.assembly e
2 2024-01-08
编程技术问答社区
使用IL Emit调用现有对象的一个方法
我试图编写一个基于属性的拦截器(类似于DynamicProxy).这个想法是基于某些自定义属性的,该属性内部的方法将被调用,即 在调用实际方法之前调用属性类中的方法. 调用实际方法. 我能够使用MethodBuilder和TypeBuilder覆盖现有方法.但是,我不知道如何调用属性内的方法. 我的代码: static void CreateMethods(TypeBuilder tb) { foreach (var methodToOverride in typeof(T).GetMethods(BindingFlags.Instance | BindingFlags.Public | BindingFlags.DeclaredOnly)) { var attribute = (ProxyMethod)methodToOverride.GetCustomAtt
6 2024-01-08
编程技术问答社区
方法实现中的主体签名和声明不匹配
我想在运行时实现接口,但是当我执行 时 return Activator.CreateInstance(typeBuilder.CreateTypeInfo().AsType(), new RPCRequestProxy()); in rpcclientfactory.cs 它投掷 System.TypeLoadException: Signature of the body and declaration in a method implementation do not match. 我使用dotnet core 1.0.4. 入口点 program.cs : namespace RPC { interface IRCPClient { Task Foo([UrlParam]int b, [UrlParam]string a, [UrlParam] DateTime c); } class Progra
2 2024-01-08
编程技术问答社区
验证.NET框架程序集
我刚刚经历了我们的实际上可以使用Reflexil或其他IL编辑器来编辑.NET框架组件.您唯一需要绕过的是大会的强烈签名.更改汇编IL后,您必须运行sn.exe -Vr [assemblyname]才能跳过强名称验证.之后,您必须清除缓存的本地图像.只需浏览C:\Windows\assembly目录,然后删除与您的汇编相关的每个图像.然后重新启动.登录时,运行ngen install [assemblyname].现在生成了新的本地图像. 这有效.我在虚拟环境(Windows XP X86)中验证了此过程.现在,最让我担心的是,您可以轻松地绕过.net VerifyHash 或 VerifyData VerifyData VerifyData RSACryptoServiceProvider的方法.这实际上也有效.我和我经过测试的一个朋友可以验证此问题(请参阅屏幕截图).那很容易. 例如,如果我创建一个构建在.NET框架加密类中的许可系统,则可以绕过 每个 .net appl
0 2024-01-08
编程技术问答社区
为什么C#->CIL的每条指令都有一个标签?
在编译C#程序上使用Ildasm.exe时,它表明方法中的每个说明都有一个标签. 例如: IL_0001: ldc.i4.4 IL_0002: stloc.0 IL_0003: ldc.r8 12.34 IL_000c: stloc.1 IL_000d: ldc.r8 3.1415926535897931 IL_0016: stloc.2 IL_0017: ldstr "Ehsan" IL_001c: stloc.3 IL_001d: ret 为什么?执行此操作不是效率低下还是CIL编译器优化这些标签本身? 解决方案 标签不存在于编译的CIL中.为了方便您在分解代码中显示它们. 这些特定的标签对应于指令偏移,而手工制作的代码没有这种限制(标签可能是任意字符串). 其他解决方案 在编译的IL中,没有标签.相反,跳跃指令从以下说明开始时使用相对偏移. 例如,考虑这个微不足道的C#函数: public
2 2024-01-08
编程技术问答社区
什么是"<Module>"类型?
我正在使用mono.cecil读取Regex.CompileToAssembly()生成的组件.当我迭代这些类型时,root名称空间中有一种名为的类型.该类型没有基本类型.这类型是什么?这是一些单件工具还是实际上是.NET组件的实际组成部分?它扮演什么角色? 解决方案 类型是不适合CLI模型的声明的地位.通常仅与混合模式的组件相关,其中包含用托管语言编写的代码以及诸如C或C ++之类的未管理的代码.它是纯托管组件的空的. 这些语言支持免费功能和全局变量. CLR不直接支持该方法,方法和变量必须始终是类型的成员.因此,元数据生成器使用了一个简单的技巧,它创建了一个假类型,成为此类功能和变量的家.该假类型的名称是.它总是具有隐藏成员的内部可访问性.这些类型中只有一种,它的失效总是1. CLR源代码称其为"全局类".
4 2024-01-08
编程技术问答社区
堆栈的目的是什么?我们为什么需要它?
所以我现在正在学习MSIL,以学习调试我的C#.NET应用程序. 我一直想知道:堆栈的目的是什么? 只是将我的问题放在上下文中: 为什么会从内存到堆栈或"加载"转移? 另一方面,为什么会从堆栈到内存或"存储"转移? 为什么不只是将它们都放在内存中? 是因为它更快吗? 是因为它是基于RAM的? 提高效率? 我正在尝试掌握这一点,以帮助我理解 cil 编码更深入. 解决方案 更新:我非常喜欢这个问题,我把它做到了我的博客于2011年11月18日.感谢您的好问题! 我一直想知道:堆栈的目的是什么? 我假设您的意思是MSIL语言的评估堆栈,而不是运行时的实际每线程堆栈. 为什么会从内存到堆栈或"加载"转移?另一方面,为什么会从堆栈到内存或"存储"转移?为什么不只是将它们都放在内存中呢? MSIL是一种"虚拟机"语言. C#编译器之类的编译器生成 cil "> cil )编译器将IL变成可以执行的实际机器代码. 所以首先让我们回答"为
0 2024-01-08
编程技术问答社区
.NET 4.5 MethodBuilder.SetMethodBody
在.NET框架的最新版本,版本4.5中,MethodBuilder类具有一种称为SetMethodBody的方法,我相信我认为我认为使用iLgenererator的替代方法(这很烦人且有限奇怪的方式).可以找到该文档 a>,尽管.NET 4.5尚未出现,但尚未完全记录下来.我可以提供除两个论点以外的所有论点,但是我将需要帮助. . 我不了解的第一个是byte[] localSignature,第三个参数. MSDN指出,它是"包含序列化局部变量结构的字节数组.如果该方法没有局部变量,则指定null."问题是,仅此而已,我找不到"序列化局部变量签名"的格式.我尝试查看ECMA-335规格,但我发现的只是如何在未组装的CIL中指定本地变量.如果有人可以帮助我弄清楚这一点,那将不胜感激. 另外,最后一个参数是IEnumerable tokenFixups,它是"代表IL中偏移的值的集合,每个值指定可以修改的令牌的开头.要修改.".我怀疑我不需要使用这些,但是我想知道它们是什
0 2024-01-08
编程技术问答社区
如何验证C#代码?
我正在研究一个WPF应用程序,该应用程序从文件中验证C#代码. 我能够获取该文件,并且出于不同的需求,请实例化其类型. 现在我需要的是根据我设定的某些标准验证该代码. 我是什么意思? 假设我有一个文件" test.cs",并且此文件具有以下代码: using xpto; using abcd; public class Test { public static void Testing() { Iqueryable var1 = ctx.Where(c => c.IdSomething == number); var1 = var1.Where(v => v.Count(x => x.ValZ) > 0); } } 在我的应用程序中,我将实例化此文件(已经完成),然后根据某些规则进行验证.例如,在此行中: var1 = var1.Where(v => v.Count(x => x.Val
0 2024-01-07
编程技术问答社区
通过DynamicMethod调用varargs方法
我试图使用DynamicMethod调用非托管printf的函数.在运行时我得到 BadImageFormateXception:找不到索引. (Hresult的例外: 0x80131124) 这是运行时的限制还是我的发出代码错误? public class Program { [DllImport("msvcrt40.dll",CallingConvention = CallingConvention.Cdecl)] public static extern int printf(string format, __arglist); static void Main(string[] args) { var method = new DynamicMethod("printf", typeof(void), new Type[0], true); var il = method.GetILGenerator(
6 2024-01-07
编程技术问答社区
在IL代码中,为什么在特定情况下没有nop操作码?为什么在给定的情况下有一个br.s操作码?
假设我有以下代码: public class Class1 { private Class2 obj; public void MethodA() { var class2 = new Class2(); class2.PropertyI = 2; obj = MethodB(class2); } public Class2 MethodB(Class2 class2) { return class2; } } public class Class2 { public int PropertyI { get; set; } } 与Visual Studio 2010一起编译为.NET 2.0组件的生成的IL代码如下: .method public hidebysig instance void MethodA() cil managed {
4 2024-01-07
编程技术问答社区
用Regex解析代码--如何捕获带有额外{...}的方法主体?}?
可能的重复: 用REGEX PARSE CIL代码 这个问题来自用Regex parse CIL代码 为了捕获方法的身体,我添加了括号(),它变成 var regex3 = @"(\.method\s[^{]+({(?!\s*}).*?}))"; 效果很好.例如,capture.Groups[2]给我 { .entrypoint // .maxstack 8 IL_0000: nop IL_0001: call void TestAssemblyConsole.Test::Method1() IL_0006: nop IL_0007: call int32 TestAssemblyConsole.Test::Method2() IL_000c: pop IL_000d: call string [mscorlib]System.Consol
2 2024-01-07
编程技术问答社区
IL方法将一个引用的T值引为无效*(从并行代码中对Span<T>工作)。
在实际问题之前,一个小的免责声明: 这是一个相关/后续问题,与这个,但是由于在这里,我在谈论一个更一般的问题(如何固定一个ref T变量以便能够对Pointer Opertations of On Octer to Pointer oter它),我提出了一个可能的解决方案(可能是错误的)解决方案,我打开了一个单独的问题. 因此,问题是:给定的ref T变量(假设它是数组的第一项),我如何固定它,以便GC在使用下面的数组时不会引起问题不安全的指针? 我不确定这是在C#中是否可以的(但我希望我错了),但是查看IL代码的方法只是修复了ref int变量,我试图提出一个变体从事通用类型的工作.这是我的想法: 假设我在" mytestclass"类中有这个delegate: public unsafe delegate void UnsafeAction(void* p); 然后,在IL中: .method public hidebysig static v
0 2024-01-07
编程技术问答社区
如何通过调用类的构造函数为其静态字段赋值/引用?
(我的代码有些混乱,c#和vb.net) 我正在尝试发出看起来如下的课程: public class SWTTFields { private string fieldName; private int startPosition; private int endPosition; public static readonly SWTTFields ISO = new SWTTFields("ISO", 1, 2); public static readonly SWTTFields EPC = new SWTTFields("EPC", 3, 4); private SWTTFields(String fieldName, Int32 startPositon, Int32 endPositon) { this.fieldName = fieldName; this.startPositi
2 2024-01-07
编程技术问答社区
Reflector是如何对代码进行反编译的?
红色大门蚂蚁探测器或反射器之类的工具如何将IL转换为c#或vb.net代码? 我最近注意到,红门蚂蚁探测器不会生成最初编写的相同源代码. 它生成了我使用foreach的while循环. 让我思考.我在反射器中打开了反射器.exe本身,但它们的代码大多是(并非全部)混淆. . 解决方案 通过查看IL和构建与IL等同的源代码的源代码,在一般工作中的分解器.这不能总是产生原始源代码,因为IL会丢弃一些高级信息(尽管不如机器代码),并且因为通常有几块代码将其编译到同一IL.例如,a foreach环相当于某种类型的while循环(首先设置枚举器的循环,然后循环直到枚举器耗尽,并在每个步骤中提出枚举者). ) ). ) 其他解决方案 实施解码的一种常见技术是使用"间隔分析"来识别循环的程度. 与成语识别结合在一起,并且模式称为"派生的图序列"时,可以从包含汇编语言(或MSIL)的控制流程图开始,然后迭代地将其简化为止,直到您拥有一个AST(抽象的synt
0 2024-01-07
编程技术问答社区
如何检测哪个.NET语言在调用我的代码
我正在构建一个生成一个用户代理字符串的库,该库报告了一些Nifty数据,例如OS版本和当前安装的.NET框架版本.我很好奇: 是否可以通过编程来检测哪种语言正在称呼我的库?还是源语言一旦将其编译成CIL? 是完全不透明的吗? 解决方案 edit :我将其变成我想出了一个启发式方法,似乎足以满足我自己的需求. @don的答案,这些问题给了我一些提示: 分解dll-线索有助于判断是c#还是vb.net? 分解VB.NET汇编生成带有无效的成员变量名称的代码;名称以$ static $ 开始 警告: 仅区分vb.net和c#,而没有其他任何CLR语言.假设C#如果没有足够的VB证据. 这是一个有根据的猜测,因此假阳性的机会是> 0. 一些提示基于编译器实施详细信息,这些详细信息可能会改变. 这似乎也适用于单声道,但是ymmv. 这是昂贵的反射,因此在现实生活中,您想将其包裹在Lazy或其他一些机制中,以确保仅被称为一次. 正如@habo
2 2024-01-06
编程技术问答社区
是否有工具可以将CIL编译为二进制文件?
在看到上一篇文章后" 制作应用程序编程在.net语言上使用旧机器",我必须想知道; 是否有将CIL编译为二进制的工具? 如果是这样,则可以将CIL文件转换为本机Windows应用程序,如果您不希望用户需要.NET框架?甚至针对.NET的Linux平台!那太棒了! 解决方案 检查一下:和此: . 其他解决方案 MS提供了一个免费的实用程序,称为但是请注意,CLR仍然需要您的组件在本机图像无效的情况下可用于后备,这可能出于多种原因而发生.而且,NGEN并没有删除最终用户安装.NET框架的必要性.最后,ngen可以更改应用程序的性能配置文件,并非总是会更好. 有公用事业,例如其他解决方案
0 2024-01-06
编程技术问答社区
如何强迫编译器使用ldc.i8 IL指令而不是ldc.i4加conv.i8?
这是我的C#代码: const long pSize = 20; 无论我使用x64还是在发行模式下构建它,我都以下是MSIL指令: IL_0010: ldc.i4.s 20 IL_0012: conv.i8 但是,MSIL具有LDC.I8指令.如何使编译器使用此功能? 解决方案 MSIL具有LDC.I8指令.如何使编译器使用此功能? 你不.那将是更糟糕的代码. ldc.i4.s 20 conv.i8 是代码的三个字节:指令两个字节,一个用于常数.而 ldc.i8 20 是九个字节:一个用于指令的字节,为八个字节. 编译器足够聪明,可以避免六个不必要的字节.请记住,代码的速度可能会受到将其加载到内存所需的页面故障数量的不利影响;生成代码大于需要的三倍. 但是,等等,还有更多,这一切都很糟糕. 基本代码的基本块越大,周围的分支的可能性就越大,将比紧凑的分支指令格式的拟合更长.这意味着这种除优化可以使分
2 2024-01-06
编程技术问答社区
.NET VM是一个编译器还是一个解释器?
.NET的虚拟机是否编译了CIL字节码(然后以最低级别-CPU汇编器执行代码),或者它是解释器(读取以下说明并执行它们)? ) 解决方案 做.NET的虚拟机 编译CIL字节码(然后 以最低级别执行代码 - CPU汇编器) 是的,这是CLR的组成部分,称为 jit 汇编)将中介语言代码(由编程语言的编译器发出)转换为机器代码. 没有动态语言中的解释器,例如Ruby,PHP,Python. 更新: @nick Craver在评论中指出,自添加 dlr in. NET 4带来了在Clr中使用动态语言概念的可能性.
4 2024-01-05
编程技术问答社区