Reputation: 3117
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
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
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.
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
.
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
.
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".
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
.
Now we can put a breaking on MessageBox.Show
like so:
!bpmd System.Windows.Forms.dll System.Windows.Forms.MessageBox.Show
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.
Then we can step into Show
with t
.
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
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