asudhak
asudhak

Reputation: 3117

How does Visual Basic store Strings in memory?

I ran into a situation where I needed to find the memory address of a String that I use in a piece of VB Code. I tried using various debuggers and also using the simple procexplorer to display a list of printable strings in memory. But it does not show anything which puzzles me. Does VB (.net framework 4) use some kind of encoding mechanism to store strings so that it does not appear in a printable format ?

Here's the variable am trying to locate in memory: "spoilt"

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

Upvotes: 0

Views: 1990

Answers (2)

asudhak
asudhak

Reputation: 3117

To answer my own question regarding encoding: Yes, Unicode encoding is used to store all strings. The above answer by @vcsjones provides a detailed explanation of how to find the memory location of these strings.

For the benefit of people who are looking for answers on how to find this address, there is a simpler way. mona.py (http://redmine.corelan.be/projects/mona) is a plugin for immunity debugger to do this job. I used it to find the memory location. The only reason I wasn't able to find what I was looking for is because of the unicode format. But, with mona.py there is an option to search for unicode strings as well.

Upvotes: 0

vcsjones
vcsjones

Reputation: 141638

These are managed strings. I'm not sure if the tools you are using know how to read managed strings out of memory.

.NET string literals are stored in the metadata section of the portable executable. Unless the tool understand how to read it out of .NET's metadata section, it won't find it. You can see the strings with a tool like ildasm. Under "View", and "MetaInfo", click "Show!". Somewhere in the new window will be a "User Strings" section. Here's mine for a sample application.

User Strings
-------------------------------------------------------
70000001 : (35) L"Property can only be set to Nothing"
70000049 : (28) L"WinForms_RecursiveFormCreate"
70000083 : (26) L"WinForms_SeeInnerException"
700000b9 : ( 7) L"Button1"
700000c9 : ( 6) L"Label1"
700000d7 : ( 8) L"TextBox1"
700000e9 : ( 5) L"Form1"
700000f5 : (29) L"WindowsApplication1.Resources"

Here we can see that the MetaData Token of the string (in my case) is 700000b9.


Now if you wanted to find the address of the string at runtime...

The tool of choice I would use to do this is WinDbg with the SOS extensions. Here's how to find that string in memory.

This is all for the x86 .NET Framework 4.

  1. Start by opening WinDbg and selecting Open Process and open your EXE. It will immediately break to give you the opportunity to set things up, like breakpoints.
  2. Set a stop on exception when the CLR JIT is loaded. This will be the right time to load SOS debugger extension.

    sxe ld:clrjit
    

    Then go ahead and continue execution with g.

  3. At this point we should have hit a breakpoint on a modload for clrjit.

    ModLoad: 57910000 57970000   C:\Windows\Microsoft.NET\Framework\v4.0.30319\clrjit.dll
    

    From there we can load the SOS debugging extensions with .loadby sos clr.

  4. We can test that SOS loaded correctly by running !eeversion to get the Execution Enging version. For me this gives "4.0.30319.269 retail".

  5. Now to find that string. Let's start by breaking when the System.Windows.Forms.dll module is loaded.

     sxe ld:System.Windows.Forms
    

    And use g to continue the execution. We should break when the module is loaded. Go ahead and step over it so the module is actually loaded with p.

  6. Now we can put a breaking on MessageBox.Show like so:

    !bpmd System.Windows.Forms.dll System.Windows.Forms.MessageBox.Show
    
  7. Now go ahead and go with g. Your application should be running now. Go ahead and click the button, and our breakpoint should be hit.

  8. Then we can step into Show with t.

  9. From there we can use !clrstack -p to show the stack trace with parameters. At the top of the stack will be the call to MessageBox.Show.

    004ee820 5c22839c System.Windows.Forms.MessageBox.Show(System.String)
    PARAMETERS:
    text (<CLR reg>) = 0x022a1058
    
  10. So now we know that the string's address is 0x022a1058. This of course will be different for you. If we do a !do 0x022a1058 it gives us the string:

    Name:        System.String
    MethodTable: 638afb08
    EEClass:     635e8bb0
    Size:        28(0x1c) bytes
    File:        C:\Windows\Microsoft.Net\assembly\GAC_32\mscorlib\v4.0_4.0.0.0__b77a5c561934e089\mscorlib.dll
    String:      Button1
    

Upvotes: 1

Related Questions