Get session content from a dump of an ASP.net 3.5 process in Windbg

I took a dump of the W3wp.exe process and am trying to get the contents of the session using Windbg. My test application is ASP.net 3.5, running Windows 7 64 bit, and the session is inprocess. I can get the contents of various other objects, but try my best to find where the contents of the session are.

Yes, I know that storing data in a session is bad, but I need this to help debug the problem on the client’s site.

I found a great post by Tess Ferrendes (http://blogs.msdn.com/b/tess/archive/2007/09/18/debugging- script-dumping-out-asp-net-session- contents.aspx) creating a script to repeat all sessions.

I suspect, however, that this was aimed at a previous version of IIS (and possibly .net and 32bit) as the Tess script is looking for InProcSessionState objects that don't seem to exist in my dump.

Any ideas on how to get session contents from a dump?

Thank,

Alex

+3
source share
1 answer

This solution is designed to unpack x64 asp.net session objects.

Here is an example of the code that I used to add items to the session.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;

public partial class _Default : System.Web.UI.Page 
{
    protected void Page_Load(object sender, EventArgs e)
    {
        this.Session.Add("Name", "Test");
        this.Session.Add("Name1", "Test1");
    }
}

Here is a script to get the contents of an HttpSession object

  .foreach ($obj {!dumpheap -mt ${$arg1} -short}) 
{
   $$ The !dumpheap -short option has last result as --------------- and 
   $$ this .if is to avoid this
   .if ($spat ("${$obj}","------------------------------")) 
     {} 
   .else 
     {
        $$ $t5 contains refernce to the array which has key and value for the
        $$ session contents

        r$t5 = poi(poi(poi(poi(${$obj}+0x8)+0x10)+0x8)+0x8);
         r$t1 = 0
        .for (r $t0=0; @$t0 < poi(@$t5+0x8); r$t0=@$t0+1 ) 
        {
          .if(@$t0 = 0) 
          { 
            $$ First occurence of the element in the array would be in the 20 offset
             r$t1=20
          }
          .else 
           { 
            $$ the rest of the elements would be in the 8th offset
            r$t1= 20+(@$t0*8)
           };

          $$ Check for null before trying to dump          

          .if (poi((@$t5-0x8)+@$t1) = 0 )
           {
              .continue
           } 
          .else
           {              
               .echo ************;
               ? @$t0
               $$ Session Key
               .printf "Session Key is :- "; !ds poi(poi((@$t5-0x8)+@$t1)+0x8);
               $$ Session value
               .printf "Session value is :- ";!ds poi(poi((@$t5-0x8)+@$t1)+0x10)
           }
        }
      }
}

Copy the above script into a file and call the script, like this one $$>a<"c:\temp\test.txt" 000007fef4115c20in Windbg. Passing MT System.Web.SessionState.HttpSessionStateas a script argument.

And here is the output from the script

************ 
Evaluate expression: 0 = 00000000`00000000 
Session Key is :- Name  
Session value is :- Test 
************ 
Evaluate expression: 1 = 00000000`00000001 
Session Key is :- Name1  
Session value is :- Test1

!ds !dumpobj. , as !ds .printf "%mu \n", 10+

script , windbg.

script

  • $t5 - System.Collections.Specialized.NameObjectCollectionBase+NameObjectEntry
  • .for . , custom dumparray
  • .if .if (poi((@$t5-0x8)+@$t1) = 0) , , !ds.
  • !ds poi(poi((@$t5-0x8)+@$t1)+0x8) : - . Name
  • !ds poi(poi((@$t5-0x8)+@$t1)+0x10): - . Test

EDIT: - script. x86 x64

r $t9 = @$ptrsize;
$$ $t8 register contains the next offset of the variable 
$$ $t7 register contains array start address 
.if (@$ptrsize = 8)
{ 
  r $t8 = 10
  r $t7 = 20
  r $t6 = 10
} 
.else 
{
  r $t8 = 6
  r $t6 = 8
  r $t7 = 10
}  
.foreach ($obj {!dumpheap -mt ${$arg1} -short}) 
{
   $$ The !dumpheap -short option has last result as --------------- and 
   $$ this .if is to avoid this
   .if ($spat ("${$obj}","------------------------------")) 
     {} 
   .else 
     {
        $$ $t5 contains refernce to the array which has key and value for the
        $$ session contents

         r$t5 = poi(poi(poi(poi(${$obj}+@$t9)+@$t6)+@$t9)+@$t9);
        .for (r $t0=0; @$t0 < poi(@$t5+@$t9); r$t0=@$t0+1 ) 
        {
          .if(@$t0 = 0) 
          { 
            $$ First occurence of the element in the array would be in the 20 offset
             r$t1=@$t7
          }
          .else 
           { 
            $$ the rest of the elements would be in the 8th offset
            r$t1= @$t7+(@$t0*@$t9)
           };
          $$ Check for null before trying to dump          
          .if (poi((@$t5-@$t9)+@$t1) = 0 )
           {
              .continue
           } 
          .else
           {              
               .echo ************;
               ? @$t0
               $$ Session Key
               .printf "Session Key is :- "; !ds poi(poi((@$t5-@$t9)+@$t1)+@$t9);
               $$ Session value
               .printf "Session value is :- ";!ds poi(poi((@$t5-@$t9)+@$t1)+@$t6)
           }
        }
      }
}
+3

Source: https://habr.com/ru/post/1769948/


All Articles