Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/vb.net/15.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Vb.net Visual Basic如何在内存中存储字符串?_Vb.net_String_Memory Management_.net 4.0_Reverse Engineering - Fatal编程技术网

Vb.net Visual Basic如何在内存中存储字符串?

Vb.net Visual Basic如何在内存中存储字符串?,vb.net,string,memory-management,.net-4.0,reverse-engineering,Vb.net,String,Memory Management,.net 4.0,Reverse Engineering,我遇到了这样一种情况,我需要找到我在一段VB代码中使用的字符串的内存地址。我尝试使用各种调试器,还使用简单的procexplorer在内存中显示可打印字符串的列表。但它没有显示任何让我困惑的东西。VB(.net framework 4)是否使用某种编码机制来存储字符串,使其不会以可打印格式显示 这是我试图在内存中找到的变量:“破坏” 这些是托管字符串。我不确定您使用的工具是否知道如何从内存中读取托管字符串 .NET字符串文本存储在可移植可执行文件的元数据部分中。除非工具理解如何从.NET的元数据

我遇到了这样一种情况,我需要找到我在一段VB代码中使用的字符串的内存地址。我尝试使用各种调试器,还使用简单的procexplorer在内存中显示可打印字符串的列表。但它没有显示任何让我困惑的东西。VB(.net framework 4)是否使用某种编码机制来存储字符串,使其不会以可打印格式显示

这是我试图在内存中找到的变量:“破坏”

这些是托管字符串。我不确定您使用的工具是否知道如何从内存中读取托管字符串

.NET字符串文本存储在可移植可执行文件的元数据部分中。除非工具理解如何从.NET的元数据部分读取它,否则它将找不到它。您可以使用类似的工具查看字符串。在“视图”和“元信息”下,单击“显示!”。在新窗口的某个地方将有一个“用户字符串”部分。这是我的一个示例应用程序

用户字符串
-------------------------------------------------------
70000001:(35)L“属性只能设置为无”
7000049:(28)L“WinForms_RecursiveFormCreate”
70000083:(26)L“WinForms_SeeInnerException”
700000b9:(7)L“按钮1”
700000c9:(6)L“标签1”
700000d7:(8)L“文本框1”
700000e9:(5)L“表格1”
700000f5:(29)L“WindowsApplication1.资源”
这里我们可以看到字符串的元数据标记(在我的例子中)是
700000b9


现在,如果您想在运行时查找字符串的地址

我选择的工具是使用。下面是如何在内存中找到该字符串

这就是x86.NETFramework4的全部内容

  • 首先打开WinDbg,选择Open Process并打开您的EXE。它会立即中断,让您有机会设置一些东西,比如断点
  • 在加载CLR JIT时设置异常停止。这将是加载SOS调试器扩展的正确时机

    sxe-ld:clrjit
    
    然后继续执行
    g

  • 此时,我们应该在clrjit的modload上找到一个断点

    ModLoad:57910000 57970000 C:\Windows\Microsoft.NET\Framework\v4.0.30319\clrjit.dll
    
    从那里,我们可以使用
    加载SOS调试扩展。loadby SOS clr

  • 我们可以通过运行
    来测试SOS是否正确加载!eeversion
    以获取执行引擎版本。对我来说,这是“4.0.30319.269零售”

  • 现在找到那个字符串。让我们从加载
    System.Windows.Forms.dll
    模块开始

    sxe-ld:System.Windows.Forms
    
    并使用
    g
    继续执行。我们应该在模块加载时中断。继续,并在其上跨一步,使模块实际加载
    p

  • 现在我们可以在
    消息框上设置一个中断。如下所示:

    !bpmd System.Windows.Forms.dll System.Windows.Forms.MessageBox.Show
    
  • 现在继续并使用
    g
    。您的应用程序现在应该正在运行。继续并单击按钮,我们的断点应该被击中

  • 然后我们可以使用
    t
    进入
    Show

  • 从那里我们可以使用
    !clrstack-p
    显示带有参数的堆栈跟踪。堆栈顶部将调用
    MessageBox.Show

    004ee820 5c22839c System.Windows.Forms.MessageBox.Show(System.String)
    参数:
    text()=0x022a1058
    
  • 现在我们知道字符串的地址是
    0x022a1058
    。当然,这对你来说是不同的。如果我们做一个
    !执行0x022a1058
    它为我们提供字符串:

    Name:System.String
    方法表:638afb08
    EEClass:635e8bb0
    大小:28(0x1c)字节
    文件:C:\Windows\Microsoft.Net\assembly\GAC_32\mscorlib\v4.0.0.0\uu_b77a5c561934e089\mscorlib.dll
    字符串:按钮1
    

  • 回答我自己关于编码的问题:是的,Unicode编码用于存储所有字符串。@vcsjones的上述回答详细解释了如何查找这些字符串的内存位置

    对于那些正在寻找如何找到此地址的答案的人来说,有一种更简单的方法mona.py(http://redmine.corelan.be/projects/mona)是一个插件,用于执行此任务。我用它来找到记忆的位置。我找不到我要找的东西的唯一原因是因为unicode格式。但是,使用mona.py也可以选择搜索unicode字符串

    Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
            MessageBox.Show("Button1")
            Dim spoilt As String
            spoilt = TextBox1.Text
            Label1.Text = spoilt
    
    
        End Sub