Skip to content

Récupérer les notifications Windows supprimées

Pourquoi les toasts fermés ou expirés survivent dans wpndatabase.db, où SQLite les laisse et comment les récupérer sans se tromper soi-même.

Publié le 4 min de lecture

En bref. Supprimer une ligne dans SQLite marque son espace comme libre ; les octets restent jusqu'à leur réutilisation (sauf si secure_delete est activé). Dans wpndatabase.db, cela signifie que les notifications fermées et expirées — y compris les aperçus de messagerie — peuvent souvent être récupérées depuis l'espace libre des pages, la freelist et les anciennes images de pages présentes dans le fichier et le WAL. Considérez chaque ligne récupérée comme une piste, pas comme un enregistrement.

Où se cachent les lignes supprimées

Le format de fichier SQLite offre quatre emplacements :

  1. Les freeblocks. L'espace d'une cellule supprimée devient un freeblock dans la même page de b-tree. Seuls ses quatre premiers octets sont écrasés (le pointeur vers le freeblock suivant et la taille du bloc) ; le reste de l'enregistrement — y compris le payload — est intact.
  2. La freelist. Lorsqu'une page ne contient plus aucune ligne, elle rejoint la freelist, avec tout son contenu, jusqu'à ce que SQLite ait de nouveau besoin d'une page.
  3. Les pages obsolètes du fichier de base. Lorsque le WAL est présent, le fichier contient la page telle qu'elle était au dernier checkpoint. Si une transaction ultérieure a supprimé une ligne, l'ancienne image de page la contient encore.
  4. Les trames WAL. Le WAL contient des versions successives des pages. Les trames plus anciennes, et celles d'une génération précédente du WAL, peuvent porter des lignes que les versions plus récentes n'ont plus.

Une base de notifications s'y prête bien : les payloads font quelques centaines d'octets de XML caractéristique, les lignes changent en permanence et le fichier est rarement compacté (vacuum).

Comment le parseur les récupère

Le Windows Notification Parser utilise deux méthodes :

  • Supprimées par le WAL. Les lignes présentes dans la base après checkpoint mais absentes une fois le WAL appliqué sont exactes : le parseur les lit avec le décodeur d'enregistrements habituel et les signale comme « supprimées par une transaction du WAL ».
  • Carving ancré sur le payload. Chaque <toast, <tile, <badge ou <?xml trouvé dans une page ou une trame WAL est un début potentiel de valeur Payload. Pour chacun, le parseur remonte à la recherche d'un en-tête d'enregistrement dont les types sériels correspondent au schéma Notification actif et placent le payload exactement à cet offset. Les types de colonnes, un FILETIME plausible et un Type en ASCII doivent aussi être cohérents. Les payloads débordant sur des pages d'overflow sont reconstitués à partir de la chaîne lorsqu'elle existe encore ; sinon, la ligne est marquée comme partielle.

Les lignes identiques à une ligne active sont écartées. Une ligne extraite ayant le même Id qu'une ligne active mais un contenu différent est présentée comme une version antérieure.

Lire une ligne récupérée

Chaque notification récupérée indique sa provenance, par exemple free space in page 4, freelist page 12 ou WAL frame 3 (page 5). Vérifiez trois points avant de l'utiliser :

  • Est-elle complète ? Une ligne partielle a un payload tronqué ou des champs manquants.
  • Son gestionnaire existe-t-il encore ? HandlerId est résolu dans la table des gestionnaires actifs ; un gestionnaire manquant est possible.
  • S'inscrit-elle dans la chronologie ? Une heure d'arrivée au milieu d'autres activités est bon signe ; une heure très éloignée des autres données mérite la méfiance.

Limites

  • L'espace est réutilisé à mesure que de nouvelles notifications arrivent : plus la suppression est ancienne, moins la récupération aboutit.
  • VACUUM réécrit le fichier et élimine l'espace libre.
  • Si une build a activé secure_delete, le contenu libéré est mis à zéro. Aucune documentation n'indique si une build de Windows le fait ; un résultat vide ne prouve pas l'absence.
  • Un enregistrement dont l'en-tête a été écrasé ne peut pas être récupéré par cette méthode. D'autres approches de carving existent ; celle-ci privilégie un faible taux de faux positifs.

FAQ

Peut-on récupérer des notifications Windows supprimées ?

Souvent, tant que SQLite n'a pas réutilisé l'espace. Une ligne supprimée reste dans la page sous forme de freeblock, les pages entières rejoignent la freelist, et d'anciennes images de pages subsistent dans le fichier de base et dans le WAL. Les lignes récupérées constituent des éléments de preuve obtenus au mieux et doivent être signalées comme telles.

Ouvrir la base détruit-il les enregistrements supprimés ?

C'est possible. Ouvrir une base en mode WAL avec SQLite puis la fermer peut déclencher un checkpoint et réinitialiser le WAL, et y écrire réutilise l'espace libre. Travaillez sur des copies dont l'empreinte a été calculée.

Articles liés

Référence des champs de la base de notifications Windows : Notification, NotificationHandler, HandlerAssets, WNSPushChannel, FILETIME et payload XML.

Ce que la base de notifications Windows enregistre, où elle se trouve, ce qu'elle prouve et ses limites : guide pratique de wpndatabase.db pour le DFIR.

Cas fictif : l'apport d'une base de notifications à la chronologie d'une intrusion — téléchargement, alerte antivirus, nouvelle app, message supprimé.