标签: il

为什么人们反汇编.NET(CLR)二进制文件?

我对.NET有些陌生,但对编程并不陌生,我对有关反汇编编译.NET代码的趋势和兴奋感到有些困惑.这似乎毫无意义.

.NET的高级易用性是我使用它的原因.我在资源有限的环境中编写了C和实际(硬件处理器)程序集.为了提高效率,这就是为了这么多细节而花费精力的原因.在.NET领域,如果你浪费时间深入了解实现中最神秘的细节,那就有可能失去拥有高级面向对象语言的目的.在使用.NET的过程中,我调试了通常的性能问题,这是一个奇怪的竞争条件,我通过阅读自己的源代码完成了所有这些,从来没有想过编译器生成什么中间语言.例如,很明显,for(;;)循环比数组上的foreach()更快,考虑到foreach()将使用带有方法调用的枚举对象来进行下一次而不是变量的简单增量,这很容易通过几百万次紧密循环运行来证明(不需要拆卸).

究竟是什么让IL愚蠢地拆解是因为它不是真正的机器代码.这是虚拟机代码.我听说有些人实际上喜欢移动指令来优化它.你在跟我开玩笑吗?即时编译的虚拟机代码甚至不能以本机编译代码的速度对(;;)循环进行简单的紧缩.如果你想从处理器中挤出最后一个循环,那么使用C/C++并花时间学习实际的汇编.这样你花在理解大量低级细节上的时间实际上是值得的.

那么,除了手上有太多时间之外,人们为什么要拆解.NET(CLR)二进制文件呢?

il reflector disassembly

4
推荐指数
1
解决办法
2754
查看次数

可以在MSIL中编码吗?

我很想知道是否可以这样做.如果它没有包含一些重要的性能优势,我不打算这样做.我是网络和游戏开发者,但我通常不用c#开发游戏.

.net il cil

4
推荐指数
1
解决办法
811
查看次数

ildasm,然后是具有相同元数据的ilasm

我们需要修补程序集,目前无法从源代码重建.我可以使用ildasm mydll.dll/all /out=mydll.il转储IL,然后我可以用ilasm/dll mydll.il重建它,除了文件版本,公钥等等都缺少新的二进制文件.我怎么能告诉ilasm添加这些?我没试过/ mdv开关.

.net il ildasm ilasm

4
推荐指数
1
解决办法
1410
查看次数

如何找到带有params参数的方法的用法,使得参数不为空?

我有一个方法,其最后一个参数是params string[].我希望搜索一个程序集并使用params至少一个值来计算传递参数的用法数.

对这个方法有几百个调用,其中大多数都没有传递给最后一个params参数,所以使用像ReSharper的Find Usages这样的东西来计算那些没有传递给params参数的用法是不切实际的.

我如何使用反射/反汇编来做到这一点?或者,有没有可以做到这一点的工具?

c# reflection il params c#-4.0

4
推荐指数
1
解决办法
142
查看次数

使用IL中的Initobj操作码初始化可空类型

为什么不C#编译器简单地调用默认的隐式的无参数.ctor,而不是intobj用于null分配的空值类型?

让我们说我们有代码:

Nullable<int> ex1 = new Nullable<int>();
Nullable<int> ex2 = null;
Nullable<int> ex3 = new Nullable<int>(10); 
Run Code Online (Sandbox Code Playgroud)

这两行的IL输出如下所示:

在此输入图像描述

它只调用.ctor最后一个语句,为什么我们不能拥有两个带有归零字段的第一个语句的实例?

.net c# il struct nullable

4
推荐指数
1
解决办法
872
查看次数

Mono.Cecil如何定义输出参数

我想通过Mono.Cecil添加一个具有输出参数的新方法,例如:

private static bool XXXXX(out Int32 a)
Run Code Online (Sandbox Code Playgroud)

我尝试了以下代码来添加此参数

TypeReference typeInt32 = targetAssembly.MainModule.TypeSystem.Int32.Resolve();
typeInt32 = targetAssembly.MainModule.Import(typeInt32);
method.Parameters.Add(new ParameterDefinition(typeInt32) { Name = "a", IsOut = true });
Run Code Online (Sandbox Code Playgroud)

然后,我在添加的IL和编译器生成的IL代码之间进行比较。它们不一样。

Cecil添加的矿井:

.method private hidebysig static bool XXXXX([out] int32 a) cil managed
Run Code Online (Sandbox Code Playgroud)

编译器生成:

.method private hidebysig static bool XXXXX([out] int32& a) cil managed
Run Code Online (Sandbox Code Playgroud)

请谁知道如何使我的Cecil添加方法与编译器生成的方法相同?

.net il mono.cecil

4
推荐指数
1
解决办法
804
查看次数

AppDynamics或NewRelic系统 - 它是如何工作的?

如何构建AppDynamic或New Relic系统,通过仅在运行应用程序的服务器上安装软件来收集应用程序的性能指标,包括详细的调用树统计信息?

是否可以在不使用调试信息编译应用程序的情况下收集此类指标?

在构建此类服务时需要考虑哪些性能折衷?这些软件如何最大限度地降低他们自己可能对应用程序产生的性能影响.

.net performance il monitoring appdynamics

4
推荐指数
2
解决办法
3541
查看次数

隐藏IL中接口的公共成员

考虑以下代码行:

ConcurrentDictionary<string, object> error = new ConcurrentDictionary<string, object>();
error.Add("hello", "world"); //actually throws a compiler error
Run Code Online (Sandbox Code Playgroud)

IDictionary<string, object> noError = new ConcurrentDictionary<string, object>();
noError.Add("hello", "world");
Run Code Online (Sandbox Code Playgroud)

我最终发现你所要做的就是改变IL以使Add函数变为私有.

现在本着解耦代码的精神,我很可能会使用接口,但似乎并没有找到Concurrent字典的Add方法.

真正使用它是否安全Add(我无法查看IL,因此我不知道它是否真的是线程安全的.)?或者我应该使用具体类型ConcurrentDictionary<TKey, TValue>并明确使用TryAdd.

c# il

4
推荐指数
2
解决办法
127
查看次数

在泛型类中创建的Func &lt;string&gt;调用RuntimeHelpers.PrepareMethod时不起作用

我目前正在对Moq框架进行扩展,以模拟非虚拟方法的实现。目前,我已经通过获取原始方法的方法句柄并将其与用户定义的Func的指针进行交换来进行此工作。

我仍然遇到的一个问题是,当我在Moq内部代码中(在使用泛型的类中)创建Func时,遇到了RuntimeHelpers.PrepareMethod的问题。(在执行指针交换之前,需要准备Func)。

当我在普通类(例如Program)中创建完全相同的Func时,一切正常。

进一步调查该问题可以追溯到调用类是否具有通用参数。

抛出异常:

An unhandled exception of type 'System.ArgumentException' occurred in mscorlib.dll

Additional information: The given generic instantiation was invalid.
Run Code Online (Sandbox Code Playgroud)

我在以下代码块中隔离了该问题:

class Program
{
    static void Main(string[] args)
    {
        new WithoutGeneric().GoExecute();
        new WithGeneric<string>().GoExecute();
    }
}

public class WithoutGeneric
{
    public void GoExecute()
    {
        //Works fine
        StaticMethods.PrepareThisFunc(() => "Test");
    }
}

public class WithGeneric<T>
{
    public void GoExecute()
    {
        //Breaks
        StaticMethods.PrepareThisFunc(() => "Test");
    }
}

public static class StaticMethods
{
    public static void PrepareThisFunc(Func<string> theFunc)
    {
        RuntimeHelpers.PrepareMethod(theFunc.Method.MethodHandle);
    }
} …
Run Code Online (Sandbox Code Playgroud)

.net c# reflection il runtime-compilation

4
推荐指数
1
解决办法
1103
查看次数

如何在IL中浮动和双重工作

当我们声明一个变量时int,例如:

int i = 4;
Run Code Online (Sandbox Code Playgroud)

生成以下IL:

IL_0001:  /* 1A   |                  */ ldc.i4.4
Run Code Online (Sandbox Code Playgroud)

我可以理解1A是16的十六进制表示,所以我理解正确的十六进制值被保存用于指代它的值或它意味着不同的东西?

当我声明一个双变量时:

double d = 12.34;
Run Code Online (Sandbox Code Playgroud)

生成IL后,我无法得到一些东西:

IL_0003:  /* 23   | AE47E17A14AE2840 */ ldc.r8     12.34
Run Code Online (Sandbox Code Playgroud)

23怎么样,它意味着什么,AE47E17A14AE2840这里有什么?

当我声明一个具有相同值的浮点数时:

float f = 12.34f;
Run Code Online (Sandbox Code Playgroud)

我现在有这个IL:

IL_000d:  /* 22   | A4704541         */ ldc.r4     12.34
Run Code Online (Sandbox Code Playgroud)

同样的问题在这里是怎么22来的,它意味着什么,是A4704541什么?

c# binary il byte ildasm

4
推荐指数
3
解决办法
283
查看次数