代码之家  ›  专栏  ›  技术社区  ›  alexmac

从Windbg中的ASP.net 3.5进程转储中检索会话内容

  •  3
  • alexmac  · 技术社区  · 14 年前

    我已经转储了W3wp.exe进程,并试图使用Windbg检索会话的内容。我的测试应用程序是在Windows764位上运行的ASP.NET3.5,会话正在处理中。我可以检索各种其他对象的内容,但是很难找到会话内容的位置。

    我发现了一篇由Tess Ferrendez撰写的很棒的文章(http://blogs.msdn.com/b/Tess/archive/2007/09/18/debugging-script-dumping-out-asp-net-session-contents.aspx),描述了如何创建一个脚本来遍历会话中的所有内容。

    不过,我怀疑这是针对以前版本的I I s(可能还有.net&32位),因为Tess的脚本正在查找在我的转储中似乎不存在的InProcSessionState对象。

    有什么办法可以从垃圾场得到会议的内容吗?

    谢谢,

    亚历克斯

    1 回复  |  直到 14 年前
        1
  •  3
  •   Naveen    14 年前

    此解决方案用于转储x64 asp.net会话对象。

    这是我用来将项目添加到会话的示例代码。

    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");
        }
    }
    

    下面是获取HttpSession对象内容的脚本

      .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)
               }
            }
          }
    }
    

    将上面的脚本复制到一个文件中并像这样调用脚本 $$>a<"c:\temp\test.txt" 000007fef4115c20 System.Web.SessionState.HttpSessionState 作为脚本参数。

    这是脚本的输出

    ************ 
    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+

    除非您习惯于编写windbg脚本,否则脚本有点神秘。

    以下是剧本的简要说明

    1. $t5 -包含对类型数组的引用 System.Collections.Specialized.NameObjectCollectionBase+NameObjectEntry
    2. .for 循环是遍历数组项。如果你有兴趣了解 custom dumparray
    3. 这个 .if 嵌套for循环中的语句 .if (poi((@$t5-0x8)+@$t1) = 0) !ds公司 命令。
    4. !ds poi(poi((@$t5-0x8)+@$t1)+0x8) :-会话的密钥字符串。例子 Name
    5. !ds poi(poi((@$t5-0x8)+@$t1)+0x10) :-会话值。例子 Test

    高温高压

    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)
               }
            }
          }
    }