0

VBコードで使用している文字列のメモリアドレスを見つける必要がある状況に遭遇しました。さまざまなデバッガーを使用し、単純なprocexplorerを使用して、メモリ内の印刷可能な文字列のリストを表示してみました。しかし、それは私を困惑させるものを何も示していません。VB(.net Framework 4)は、文字列を印刷可能な形式で表示されないように格納するために、ある種のエンコードメカニズムを使用していますか?

これがメモリ内で見つけようとしている変数です: "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
4

2 に答える 2

1

これらは管理された文字列です。使用しているツールが、管理対象文字列をメモリから読み取る方法を知っているかどうかはわかりません。

.NET文字列リテラルは、ポータブル実行可能ファイルのメタデータセクションに格納されます。ツールが.NETのメタデータセクションからそれを読み取る方法を理解しない限り、ツールはそれを見つけられません。ildasmのようなツールで文字列を見ることができます。[表示]と[MetaInfo]で、[表示]をクリックします。新しいウィンドウのどこかに「ユーザー文字列」セクションがあります。これがサンプルアプリケーションの私のものです。

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"

ここで、文字列(私の場合)のメタデータトークンがであることがわかります700000b9


実行時に文字列のアドレスを検索したい場合は...

これを行うために使用するツールは、 SOS拡張機能を備えたWinDbgです。メモリ内でその文字列を見つける方法は次のとおりです。

これはすべてx86.NETFramework4の場合です。

  1. WinDbgを開き、[プロセスを開く]を選択して、EXEを開きます。ブレークポイントなどを設定する機会を与えるために、すぐに壊れます。
  2. CLRJITがロードされたときに例外で停止を設定します。これは、SOSデバッガ拡張をロードする適切なタイミングになります。

    sxe ld:clrjit
    

    次に、先に進み、で実行を続行しgます。

  3. この時点で、clrjitのmodloadでブレークポイントに到達するはずです。

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

    そこから、SOSデバッグ拡張機能を。でロードできます.loadby sos clr

  4. !eeversion実行してExecutionEngingバージョンを取得することにより、SOSが正しくロードされたことをテストできます。私にとって、これは「4.0.30319.269小売」を与えます。

  5. 次に、その文字列を検索します。System.Windows.Forms.dllモジュールがロードされたときにブレークすることから始めましょう。

     sxe ld:System.Windows.Forms
    

    そしてg、実行を継続するために使用します。モジュールがロードされたときに壊れるべきです。モジュールに実際にがロードされるように、先に進んでステップオーバーしpます。

  6. MessageBox.Show今、私たちはそのように休憩を入れることができます:

    !bpmd System.Windows.Forms.dll System.Windows.Forms.MessageBox.Show
    
  7. さあ、先に進んでgください。これでアプリケーションが実行されているはずです。先に進んでボタンをクリックすると、ブレークポイントがヒットするはずです。

  8. 次に、でステップイン できます。Showt

  9. そこから!clrstack -p、パラメータを使用してスタックトレースを表示するために使用できます。スタックの一番上には、への呼び出しがありますMessageBox.Show

    004ee820 5c22839c System.Windows.Forms.MessageBox.Show(System.String)
    PARAMETERS:
    text (<CLR reg>) = 0x022a1058
    
  10. これで、文字列のアドレスがであることがわかりました0x022a1058。もちろん、これはあなたにとっては異なります。これを行うと、!do 0x022a1058次の文字列が得られます。

    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
    
于 2012-08-13T17:40:45.657 に答える
0

エンコーディングに関する私自身の質問に答えるには:はい、Unicodeエンコーディングはすべての文字列を格納するために使用されます。@vcsjonesによる上記の回答は、これらの文字列のメモリ位置を見つける方法の詳細な説明を提供します。

この住所を見つける方法についての答えを探している人々の利益のために、より簡単な方法があります。mona.py(http://redmine.corelan.be/projects/mona)は、このジョブを実行するためのイミュニティデバッガー用のプラグインです。私はそれを使ってメモリの場所を見つけました。探していたものが見つからなかった唯一の理由は、Unicode形式のためです。ただし、mona.pyには、Unicode文字列を検索するオプションもあります。

于 2012-08-15T14:03:50.440 に答える