2010-10-17 18 views
3

J'ai pris un vidage du processus W3wp.exe et j'essaie de récupérer le contenu de la session en utilisant Windbg. Mon application de test est ASP.net 3.5 sous Windows 7 64 bits et la session est en cours. Je peux récupérer le contenu de divers autres objets mais j'ai du mal à trouver le contenu de la session.Récupérer le contenu d'une session à partir du vidage du processus ASP.net 3.5 dans Windbg

Oui, je sais que stocker des données dans une session est mauvais, mais j'en ai besoin pour aider à déboguer un problème sur un site client.

J'ai trouvé un excellent message par Tess Ferrendez (http://blogs.msdn.com/b/tess/archive/2007/09/18/debugging-script-dumping-out-asp-net-session-contents .aspx) qui décrit la création d'un script pour parcourir tous les éléments de la session.

Je suppose cependant que cela visait une version précédente d'IIS (et peut-être .net & 32 bits) car le script de Tess cherche des objets InProcSessionState qui ne semblent pas exister dans ma sauvegarde.

Des idées pour obtenir le contenu d'une session à partir d'un vidage?

Merci,

Alex

Répondre

3

Cette solution est pour le dumping des objets de session asp.net x64.

Voici l'exemple de code que j'ai utilisé pour ajouter les éléments à la 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"); 
    } 
} 

Voici le script pour obtenir le contenu de l'objet 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); [email protected]$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)[email protected]$t1) = 0) 
      { 
       .continue 
      } 
      .else 
      {    
       .echo ************; 
       ? @$t0 
       $$ Session Key 
       .printf "Session Key is :- "; !ds poi(poi((@$t5-0x8)[email protected]$t1)+0x8); 
       $$ Session value 
       .printf "Session value is :- ";!ds poi(poi((@$t5-0x8)[email protected]$t1)+0x10) 
      } 
     } 
     } 
} 

Copiez le script ci-dessus dans un fichier et appeler le script comme celui-ci dans les $$>a<"c:\temp\test.txt" 000007fef4115c20 Windbg. Passer le MT de System.Web.SessionState.HttpSessionState comme argument de script.

Et voici la sortie du 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 

J'utilise l'alias !ds pour les chaînes au lieu d'utiliser le dumping !dumpobj. Pour créer l'alias, utilisez cette commande. as !ds .printf "%mu \n", 10+

Le script est un peu arcane, sauf si vous avez l'habitude d'écrire des scripts windbg.

Voici une brève explication du script

  1. $t5 - Contient référence au tableau de type System.Collections.Specialized.NameObjectCollectionBase+NameObjectEntry
  2. La boucle .for imbriquée est de parcourir les éléments du tableau. J'ai blogué à peu près la même chose si vous êtes intéressé à comprendre custom dumparray
  3. L'instruction .if dans la boucle for imbriquée .if (poi((@$t5-0x8)[email protected]$t1) = 0) vérifie si l'élément est nul avant de vider le contenu à l'aide de la commande !ds.
  4. !ds poi(poi((@$t5-0x8)[email protected]$t1)+0x8) : - La chaîne de clé pour la session. Exemple Name
  5. !ds poi(poi((@$t5-0x8)[email protected]$t1)+0x10): - La valeur de session.Exemple Test

HTH

EDIT: - Aussi ici est une plate-forme de script indépendant. Cela devrait fonctionner pour x86 et 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}[email protected]$t9)[email protected]$t6)[email protected]$t9)[email protected]$t9); 
     .for (r $t0=0; @$t0 < poi(@[email protected]$t9); [email protected]$t0+1) 
     { 
      .if(@$t0 = 0) 
      { 
      $$ First occurence of the element in the array would be in the 20 offset 
      [email protected]$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((@[email protected]$t9)[email protected]$t1) = 0) 
      { 
       .continue 
      } 
      .else 
      {    
       .echo ************; 
       ? @$t0 
       $$ Session Key 
       .printf "Session Key is :- "; !ds poi(poi((@[email protected]$t9)[email protected]$t1)[email protected]$t9); 
       $$ Session value 
       .printf "Session value is :- ";!ds poi(poi((@[email protected]$t9)[email protected]$t1)[email protected]$t6) 
      } 
     } 
     } 
} 
+0

Salut Naveen merci beaucoup pour la question mais je reçois l'erreur suivante: erreur d'accès mémoire à «) + 0x4) + 0x4); .for (r $ t0 = 0; @ $ t0 alexmac

+0

Salut Alexmac, Désolé à ce sujet j'ai utilisé le x86 au lieu de x64. J'ai corrigé le script pour x64 et mis à jour la réponse. – Naveen