Symboles et modules synthétiques (WinDbg / DbgEng)

Cette publication se concentrera sur les modules synthĂ©tiques et les symboles du moteur de dĂ©bogage Windows (moteur de dĂ©bogage). C'est-Ă -dire sur les entitĂ©s qui peuvent ĂȘtre artificiellement ajoutĂ©es au dĂ©bogueur pour colorer les adresses mĂ©moire.



Modules synthétiques


En général, un module faisant partie d'un moteur de débogage est une certaine zone continue de mémoire virtuelle: l'adresse de base du module (adresse du premier octet du fichier projeté) et sa taille. Pour chaque type de débogage (débogage en direct / analyse de vidage, mode utilisateur / mode noyau, etc.), le débogueur possÚde son propre mécanisme de lecture et de mise à jour de la liste des modules chargés. La façon la plus simple de forcer la mise à jour de la liste des modules chargés est la commande .reload avec l'option / s .


Si nous parlons, par exemple, du dĂ©bogage en direct du processus en mode utilisateur, la liste des modules chargĂ©s est construite selon trois listes principales du chargeur : une liste de l'ordre de chargement des modules (InLoadOrderModuleList), une liste des modules en mĂ©moire (InMemoryOrderModuleList) et une liste de prioritĂ© d'initialisation (InInitializationOrderModuleList). D'une part, ce n'est ( presque ) rien qui nous empĂȘche de prendre des donnĂ©es arbitraires (d'un fichier PE sur disque, par exemple) et de les marquer en mĂ©moire pour les exĂ©cuter de nos propres mains. D'un autre cĂŽtĂ©, les techniques de suppression des DLL chargĂ©es avec des moyens rĂ©guliers des trois listes de chargeurs ci-dessus (masquant le module) sont connues depuis longtemps.


Dans les deux cas, lors du dĂ©bogage de cette situation, il sera utile de marquer la zone du module cachĂ©. Pour cela, des modules synthĂ©tiques conviennent. Comme expĂ©rience pratique, vous pouvez simplement faire en sorte que WinDbg supprime le module chargĂ© de sa liste interne avec la mĂȘme commande .reload, mais avec l'option / u .


De plus, dans la qualité des listes listées, j'utiliserai le débogage habituel du processus en mode utilisateur (notepad.exe). Tout d'abord, souvenez-vous de l'adresse de base du module ntdll (0x07ffa8a160000) et calculez sa taille (0x01e1000):


0:007> lm m ntdll Browse full module list start end module name 00007ffa`8a160000 00007ffa`8a341000 ntdll 0:007> ? 00007ffa`8a341000-00007ffa`8a160000 Evaluate expression: 1970176 = 00000000`001e1000 

Considérez une liste de la fonction RtlFreeSid simple du module ntdll, qui appelle la fonction RtlFreeHeap de ce module, en se souvenant simultanément des adresses des caractÚres RtlFreeSid et RtlFreeHeap (0x7ffa8a1cbc20 et 0x7ffa8a176df0):


 0:007> uf ntdll!RtlFreeSid ntdll!RtlFreeSid: 00007ffa`8a1cbc20 4053 push rbx 00007ffa`8a1cbc22 4883ec20 sub rsp,20h 00007ffa`8a1cbc26 488bd9 mov rbx,rcx 00007ffa`8a1cbc29 33d2 xor edx,edx 00007ffa`8a1cbc2b 65488b0c2560000000 mov rcx,qword ptr gs:[60h] 00007ffa`8a1cbc34 4c8bc3 mov r8,rbx 00007ffa`8a1cbc37 488b4930 mov rcx,qword ptr [rcx+30h] 00007ffa`8a1cbc3b e8b0b1faff call ntdll!RtlFreeHeap (00007ffa`8a176df0) 00007ffa`8a1cbc40 33c9 xor ecx,ecx 00007ffa`8a1cbc42 85c0 test eax,eax 00007ffa`8a1cbc44 480f45d9 cmovne rbx,rcx 00007ffa`8a1cbc48 488bc3 mov rax,rbx 00007ffa`8a1cbc4b 4883c420 add rsp,20h 00007ffa`8a1cbc4f 5b pop rbx 00007ffa`8a1cbc50 c3 ret 

De plus, selon la liste, il est facile de calculer la taille de la fonction ntdll! RtlFreeSid:


 0:007> ? 00007ffa`8a1cbc51 - 0x07ffa8a1cbc20 Evaluate expression: 49 = 00000000`00000031 

Et la taille de la fonction ntdll! RtlFreeHeap n'est pas importante pour notre expérience, donc pour plus de simplicité vous pouvez la prendre égale à un octet.


Simulez maintenant le masquage du module ntdll:


 0:007> .reload /u ntdll Unloaded ntdll 

Le champ de ce travail avec l'adresse de la fonction ntdll! RtlFreeSid dans le débogueur n'est pas si informatif (et vous ne pouvez déjà accéder au début de la fonction que par l'adresse virtuelle):


 0:007> uf 00007ffa`8a1cbc20 00007ffa`8a1cbc20 4053 push rbx 00007ffa`8a1cbc22 4883ec20 sub rsp,20h 00007ffa`8a1cbc26 488bd9 mov rbx,rcx 00007ffa`8a1cbc29 33d2 xor edx,edx 00007ffa`8a1cbc2b 65488b0c2560000000 mov rcx,qword ptr gs:[60h] 00007ffa`8a1cbc34 4c8bc3 mov r8,rbx 00007ffa`8a1cbc37 488b4930 mov rcx,qword ptr [rcx+30h] 00007ffa`8a1cbc3b e8b0b1faff call 00007ffa`8a176df0 00007ffa`8a1cbc40 33c9 xor ecx,ecx 00007ffa`8a1cbc42 85c0 test eax,eax 00007ffa`8a1cbc44 480f45d9 cmovne rbx,rcx 00007ffa`8a1cbc48 488bc3 mov rax,rbx 00007ffa`8a1cbc4b 4883c420 add rsp,20h 00007ffa`8a1cbc4f 5b pop rbx 00007ffa`8a1cbc50 c3 ret 

Pour ajouter un module synthĂ©tique, vous devez appeler l'interface du programme IDebugSymbols3 :: AddSyntheticModule . Il n'y a tout simplement pas de commandes intĂ©grĂ©es qui permettraient de faire cet appel (pour autant que je sache). Mikhail I. Izmestev a suggĂ©rĂ© qu'il existe un mĂ©canisme similaire - le mĂȘme .reload , mais avec les paramĂštres de nom, d'adresse et de taille: "Module = Address, Size" (et, Ă©ventuellement, il est implĂ©mentĂ© sur des modules synthĂ©tiques).


.reload ntdll = 00007ff8`470e1000,001e1000
 0:007> .reload ntdll=00007ff8`470e1000,001e1000 *** WARNING: Unable to verify timestamp for ntdll *** ERROR: Module load completed but symbols could not be loaded for ntdll 0:007> uf 00007ff8`4714bc20 ntdll+0x6ac20: 00007ff8`4714bc20 4053 push rbx 00007ff8`4714bc22 4883ec20 sub rsp,20h 00007ff8`4714bc26 488bd9 mov rbx,rcx 00007ff8`4714bc29 33d2 xor edx,edx 00007ff8`4714bc2b 65488b0c2560000000 mov rcx,qword ptr gs:[60h] 00007ff8`4714bc34 4c8bc3 mov r8,rbx 00007ff8`4714bc37 488b4930 mov rcx,qword ptr [rcx+30h] 00007ff8`4714bc3b e8b0b1faff call ntdll+0x15df0 (00007ff8`470f6df0) 00007ff8`4714bc40 33c9 xor ecx,ecx 00007ff8`4714bc42 85c0 test eax,eax 00007ff8`4714bc44 480f45d9 cmovne rbx,rcx 00007ff8`4714bc48 488bc3 mov rax,rbx 00007ff8`4714bc4b 4883c420 add rsp,20h 00007ff8`4714bc4f 5b pop rbx 00007ff8`4714bc50 c3 ret 

Eh bien, nous utiliserons l'extension du débogueur, et ici pykd viendra à la rescousse . Dans la derniÚre version (au moment de la rédaction) 0.3.4.3 , des fonctions de gestion des modules synthétiques ont été ajoutées: addSyntheticModule (...) (ce qui est nécessaire dans notre cas) et removeSyntheticModule (...).


En utilisant l'adresse de base et la taille du module prĂ©cĂ©demment enregistrĂ©es, nous ajoutons des informations sur le module ntdll cachĂ© au dĂ©bogueur (en cas d'erreur, une exception sera levĂ©e, donc une exĂ©cution silencieuse est un signe de succĂšs, les avertissements d'impression peuvent ĂȘtre ignorĂ©s):


 0:007> !py Python 2.7.15 (v2.7.15:ca079a3ea3, Apr 30 2018, 16:30:26) [MSC v.1500 64 bit (AMD64)] on win32 Type "help", "copyright", "credits" or "license" for more information. (InteractiveConsole) >>> addSyntheticModule(0x07ffa8a160000, 0x01e1000, 'ntdll') *** WARNING: Unable to verify timestamp for ntdll >>> exit() 

Maintenant, la liste des désassembleurs est devenue un peu plus informative:


 0:007> uf 00007ffa`8a1cbc20 ntdll+0x6bc20: 00007ffa`8a1cbc20 4053 push rbx 00007ffa`8a1cbc22 4883ec20 sub rsp,20h 00007ffa`8a1cbc26 488bd9 mov rbx,rcx 00007ffa`8a1cbc29 33d2 xor edx,edx 00007ffa`8a1cbc2b 65488b0c2560000000 mov rcx,qword ptr gs:[60h] 00007ffa`8a1cbc34 4c8bc3 mov r8,rbx 00007ffa`8a1cbc37 488b4930 mov rcx,qword ptr [rcx+30h] 00007ffa`8a1cbc3b e8b0b1faff call ntdll+0x16df0 (00007ffa`8a176df0) 00007ffa`8a1cbc40 33c9 xor ecx,ecx 00007ffa`8a1cbc42 85c0 test eax,eax 00007ffa`8a1cbc44 480f45d9 cmovne rbx,rcx 00007ffa`8a1cbc48 488bc3 mov rax,rbx 00007ffa`8a1cbc4b 4883c420 add rsp,20h 00007ffa`8a1cbc4f 5b pop rbx 00007ffa`8a1cbc50 c3 ret 

Plus prĂ©cisĂ©ment, nous voyons que la fonction Ă  l'intĂ©rieur du module ntdll appelle une autre fonction Ă  l'intĂ©rieur du mĂȘme module.


Symboles synthétiques


L'inscription, aprĂšs l'ajout d'un module synthĂ©tique, est devenue plus informative, mais pas aussi Ă©loquente que l'original. Il manque des caractĂšres (dans notre cas, les noms des fonctions RtlFreeSid et RtlFreeHeap). Pour rĂ©soudre ce problĂšme, un appel est Ă  nouveau requis, mais d'une interface de programme diffĂ©rente - IDebugSymbols3 :: AddSyntheticSymbol . Pykd Ă  nouveau prĂȘt Ă  nous aider avec ceci:


 0:007> !py Python 2.7.15 (v2.7.15:ca079a3ea3, Apr 30 2018, 16:30:26) [MSC v.1500 64 bit (AMD64)] on win32 Type "help", "copyright", "credits" or "license" for more information. (InteractiveConsole) >>> addSyntheticSymbol(0x07ffa8a1cbc20, 0x31, 'RtlFreeSid') <pykd.syntheticSymbol object at 0x0000014D47699518> >>> addSyntheticSymbol(0x07ffa8a176df0, 1, 'RtlFreeHeap') <pykd.syntheticSymbol object at 0x0000014D476994A8> >>> exit() 

Le résultat est trÚs similaire à celui qui était lors de l'utilisation des symboles du fichier pdb ntdll:


 0:007> uf 00007ffa`8a1cbc20 ntdll!RtlFreeSid: 00007ffa`8a1cbc20 4053 push rbx 00007ffa`8a1cbc22 4883ec20 sub rsp,20h 00007ffa`8a1cbc26 488bd9 mov rbx,rcx 00007ffa`8a1cbc29 33d2 xor edx,edx 00007ffa`8a1cbc2b 65488b0c2560000000 mov rcx,qword ptr gs:[60h] 00007ffa`8a1cbc34 4c8bc3 mov r8,rbx 00007ffa`8a1cbc37 488b4930 mov rcx,qword ptr [rcx+30h] 00007ffa`8a1cbc3b e8b0b1faff call ntdll!RtlFreeHeap (00007ffa`8a176df0) 00007ffa`8a1cbc40 33c9 xor ecx,ecx 00007ffa`8a1cbc42 85c0 test eax,eax 00007ffa`8a1cbc44 480f45d9 cmovne rbx,rcx 00007ffa`8a1cbc48 488bc3 mov rax,rbx 00007ffa`8a1cbc4b 4883c420 add rsp,20h 00007ffa`8a1cbc4f 5b pop rbx 00007ffa`8a1cbc50 c3 ret 

Caractéristiques des entités synthétiques


Il convient de noter que la crĂ©ation de symboles synthĂ©tiques est autorisĂ©e dans tous les modules existants, et pas seulement dans les modules synthĂ©tiques. Autrement dit, vous pouvez ajouter des symboles Ă  la fois aux modules avec des fichiers pdb accessibles et aux modules pour lesquels nous n'avons pas de fichiers avec des informations de dĂ©bogage. Mais vous ne pouvez pas crĂ©er de personnages en dehors des modules. C'est-Ă -dire que pour marquer une adresse mĂ©moire arbitraire en dehors des limites des modules existants, vous devez d'abord crĂ©er un module synthĂ©tique enveloppant, puis (si nĂ©cessaire, car le nom du module peut ĂȘtre assez suffisant pour la coloration ) y crĂ©er un symbole synthĂ©tique.


Il convient Ă©galement de mentionner que les modules et symboles synthĂ©tiques peuvent ĂȘtre supprimĂ©s par un mouvement imprudent de la main:


  • le rechargement des symboles de dĂ©bogage du module supprime tous les symboles synthĂ©tiques de ce module;
  • le rechargement de tous les modules supprimera tous les modules synthĂ©tiques.

! synexts


Bien que l'utilisation de pykd soit pratique dans la grande majoritĂ© des cas (en particulier compte tenu de la prĂ©sence d'un bootstarpper ), vous pouvez parfois vous retrouver dans une situation oĂč vous devrez consacrer des efforts considĂ©rables pour utiliser pykd. Par exemple, j'ai dĂ» une fois dĂ©boguer Ă  partir de la machine host'ovy sur laquelle Windows XP fonctionnait. Il s'est avĂ©rĂ© que pykd ne supportait pas XP depuis un certain temps, et j'avais besoin de caractĂšres et de modules synthĂ©tiques. Il m'a semblĂ© que pour cette tĂąche, il est plus facile d'assembler une petite extension distincte qui rĂ©soudra une gamme Ă©troite de tĂąches nĂ©cessaires que de restaurer la prise en charge complĂšte de XP pour pykd. En consĂ©quence, un projet distinct ! Synexts a Ă©tĂ© créé.


Il s'agit d'une extension simple qui dispose de deux exportations disponibles pour l'utilisateur:


  • ! synexts.addsymbol - crĂ©e un symbole synthĂ©tique dans n'importe quel module existant;
  • ! synexts.addmodule - crĂ©e un module synthĂ©tique dans la liste interne du moteur de dĂ©bogage.

Pour le démontrer, nous simulons à nouveau le masquage du module ntdll:


 0:007> .reload /u ntdll Unloaded ntdll 0:007> uf 00007ffa`8a1cbc20 00007ffa`8a1cbc20 4053 push rbx 00007ffa`8a1cbc22 4883ec20 sub rsp,20h 00007ffa`8a1cbc26 488bd9 mov rbx,rcx 00007ffa`8a1cbc29 33d2 xor edx,edx 00007ffa`8a1cbc2b 65488b0c2560000000 mov rcx,qword ptr gs:[60h] 00007ffa`8a1cbc34 4c8bc3 mov r8,rbx 00007ffa`8a1cbc37 488b4930 mov rcx,qword ptr [rcx+30h] 00007ffa`8a1cbc3b e8b0b1faff call 00007ffa`8a176df0 00007ffa`8a1cbc40 33c9 xor ecx,ecx 00007ffa`8a1cbc42 85c0 test eax,eax 00007ffa`8a1cbc44 480f45d9 cmovne rbx,rcx 00007ffa`8a1cbc48 488bc3 mov rax,rbx 00007ffa`8a1cbc4b 4883c420 add rsp,20h 00007ffa`8a1cbc4f 5b pop rbx 00007ffa`8a1cbc50 c3 ret 

Encore une fois, nous rétablissons la connaissance du module et des symboles sous forme d'entités synthétiques, mais en utilisant déjà l'extension! Synexts:


 0:007> !synexts.addmodule ntdll C:\Windows\System32\ntdll.dll 00007ffa`8a160000 0x01e1000 *** WARNING: Unable to verify timestamp for C:\Windows\System32\ntdll.dll Synthetic module successfully added 0:007> !synexts.addsymbol RtlFreeSid 00007ffa`8a1cbc20 31 Synthetic symbol successfully added 0:007> !synexts.addsymbol RtlFreeHeap 00007ffa`8a176df0 1 Synthetic symbol successfully added 

Il est supposé que vous avez déjà copié la bibliothÚque synexts.dll compilée (correspondant à la profondeur de bits utilisée par WinDbg) dans le répertoire winext du débogueur:


 0:007> .chain Extension DLL search Path: C:\Program Files (x86)\Windows Kits\10\Debuggers\x64\WINXP;C:\Program Files (x86)\Windows Kits\10\Debuggers\x64\winext;C:\Program Files (x86)\Windows Kits\10\Debuggers\x64\winext\arcade;C:\Program Files (x86)\Windows Kits\10\Debuggers\x64\pri;C:\Program Files (x86)\Windows Kits\10\Debuggers\x64;<
> Extension DLL chain: pykd.pyd: image 0.3.4.3, API 1.0.0, built Thu Jan 10 19:56:25 2019 [path: C:\Program Files (x86)\Windows Kits\10\Debuggers\x64\winext\pykd.pyd] synexts: API 1.0.0, built Fri Jan 18 17:38:17 2019 [path: C:\Program Files (x86)\Windows Kits\10\Debuggers\x64\winext\synexts.dll] <
> 

Et encore une fois, nous voyons le résultat de l'ajout de caractÚres synthétiques au module synthétique:


 0:007> uf 00007ffa`8a1cbc20 ntdll!RtlFreeSid: 00007ffa`8a1cbc20 4053 push rbx 00007ffa`8a1cbc22 4883ec20 sub rsp,20h 00007ffa`8a1cbc26 488bd9 mov rbx,rcx 00007ffa`8a1cbc29 33d2 xor edx,edx 00007ffa`8a1cbc2b 65488b0c2560000000 mov rcx,qword ptr gs:[60h] 00007ffa`8a1cbc34 4c8bc3 mov r8,rbx 00007ffa`8a1cbc37 488b4930 mov rcx,qword ptr [rcx+30h] 00007ffa`8a1cbc3b e8b0b1faff call ntdll!RtlFreeHeap (00007ffa`8a176df0) 00007ffa`8a1cbc40 33c9 xor ecx,ecx 00007ffa`8a1cbc42 85c0 test eax,eax 00007ffa`8a1cbc44 480f45d9 cmovne rbx,rcx 00007ffa`8a1cbc48 488bc3 mov rax,rbx 00007ffa`8a1cbc4b 4883c420 add rsp,20h 00007ffa`8a1cbc4f 5b pop rbx 00007ffa`8a1cbc50 c3 ret 

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


All Articles