了解 ldstr 如何获取字符串文字

Understanding how ldstr gets string literal

我想分析一个简单的c#方法的IL代码:

public static string test()
{
    return "hello";
}

当我调用 GetILAsByteArray 时,我得到以下字节:

    [0] 0x00    byte
    [1] 0x72    byte
    [2] 0x01    byte
    [3] 0x00    byte
    [4] 0x00    byte
    [5] 0x70    byte
    [6] 0x0a    byte
    [7] 0x2b    byte
    [8] 0x00    byte
    [9] 0x06    byte
    [10]0x2a    byte

第二个操作码是ldstr

我的理解方式 ldstr 从元数据中加载一个字符串并将其压入堆栈。 (Description of ldstr from microsoft)

但是我怎么知道哪些数据是从元数据加载的呢?告诉我以下 0x01 是否必须从元数据中获取索引 1 上的数据?还是 ldstr 后跟一个 int32?我应该如何解释这些字节?

当您在代码中键入 hello 字符串时,编译器会将此字符串写入 PE (exe/dll) 文件的 #US 流中。

#US 流(用户字符串)- 包含 16 位 Unicode 字符串的数组,这些字符串由 ldstr.

直接引用

让我们以您的示例 72 01 00 00 70 为例,因此在这种情况下,您的字符串位于 #US 流中的偏移量 0x01

#US 流以空字节开始,每个后续条目都以 7 位编码整数(表示后续条目的字节大小)开始。

可以在 Ecma-355I I.24.2.4 #US 和 #Blob 堆 部分)

中找到更多信息