Quelle est la meilleure alias d'un nom d'exécutable dans un script de blocage WinDBG?
-
05-07-2019 - |
Question
Informations générales
Pour enregistrer les vidages sur incident, un script est passé à cdb.exe
dans la Debugger
valeur de la AeDebug
clé de registre:
C:\progra~1\debugg~1\cdb.exe -p %ld -e %ld -g -y SRV*c:\mss*http://msdl.microsoft.com/download/symbols -c "$<d:\tgticker\Dumps\RDFD.cdbscript"
Voici la première partie du script:
as /c CrashFirstModule .printf "%mu", @@c++((*(ntdll!_LDR_DATA_TABLE_ENTRY**)&@$peb->Ldr->InLoadOrderModuleList.Flink)->BaseDllName.Buffer)
.logopen /t d:\tgticker\dumps\${CrashFirstModule}_process.log
* (...)
Le problème
Avec les symboles, cela fonctionne exactement comme je le voudrais, je reçois des fichiers de log avec des noms raisonnables comme:
-
LHCBDRDT.exe_process_147c_2009-01-06_23-10-05-371.log
Cependant, si les symboles ne sont pas disponibles, j'obtiens un nom de fichier journal comme celui-ci:
-
${CrashFirstModule}_process_17a8_2009-01-06_23-10-01-124.log
Cela est dû au fait que la commande d'alias n'a pas réussi à définir l'alias. La commande alias est celle que j'ai recueillie à partir de DumpAnalysis.org . Cette commande extrait le nom de l'en-tête PEB de l'image à l'aide de ntdll.dll
. Sans symboles pour le système d'exploitation, il ne sait pas où trouver la fonction qu'il appelle depuis ntdll.dll.
La question
Quelqu'un sait-il ou a-t-il une commande pour obtenir le nom de l'image sous forme d'alias à utiliser dans les noms de fichiers qui fonctionneraient encore dans ces situations?
La solution
Me voici donc des années plus tard avec une réponse.
La réponse
En l’absence de fichiers de symboles, c’est le meilleur moyen que j’ai trouvé pour obtenir le nom du fichier exécutable qui s’était écrasé afin qu’il puisse être utilisé dans un nom de fichier pour écrire un fichier journal ou un vidage sur incident à partir d’un script:
aS ${/v:CrashFirstModule} "UnknownModule"
.foreach /pS b /ps b (name {.imgscan}) { .if($spat("${name}","*.exe") !=0){aS ${/v:CrashFirstModule} "${name}"; .break} }
Après ces deux lignes, CrashFirstModule
sera associé à & "UnknownModule &"; ou le nom de l'exécutable. Cela ne fonctionne que si l'exécutable se termine par & ";Exe &"; Mais cela me semble raisonnable et fonctionne bien dans le cas où je l'utilise. Vous pouvez ajouter un autre .if
pour gérer une autre terminaison si vous devez prendre en charge des éléments tels que & ".Com &";.
La réponse: expliquée
.imgscan
.imgscan
donne une liste des modules exécutables, qui comprendront les fichiers .exe, .dll, .drv, etc. C'est le point de départ pour trouver le nom de l'exécutable.
0:000> .imgscan
MZ at 01000000, prot 00000002, type 01000000 - size 14000
Name: notepad.exe
MZ at 73070000, prot 00000002, type 01000000 - size 27000
Name: WINSPOOL.DRV
MZ at 762b0000, prot 00000002, type 01000000 - size 49000
Name: comdlg32.dll
MZ at 76f50000, prot 00000002, type 01000000 - size 13000
Name: Secur32.dll
MZ at 77380000, prot 00000002, type 01000000 - size 91000
Name: USER32.dll
MZ at 77420000, prot 00000002, type 01000000 - size 103000
Name: COMCTL32.dll
MZ at 77ba0000, prot 00000002, type 01000000 - size 5a000
Name: msvcrt.dll
MZ at 77c00000, prot 00000002, type 01000000 - size 48000
Name: GDI32.dll
MZ at 77c50000, prot 00000002, type 01000000 - size a0000
Name: RPCRT4.dll
MZ at 77e40000, prot 00000002, type 01000000 - size 102000
Name: KERNEL32.dll
MZ at 7c800000, prot 00000002, type 01000000 - size c3000
Name: ntdll.dll
MZ at 7c8d0000, prot 00000002, type 01000000 - size 7ff000
Name: SHELL32.dll
MZ at 7d180000, prot 00000002, type 01000000 - size 52000
Name: SHLWAPI.dll
MZ at 7d1e0000, prot 00000002, type 01000000 - size 9c000
Name: ADVAPI32.dll
.foreach
.foreach
est utilisé pour parcourir la liste des images. /pS
indique à quelle distance de la liste se trouve la première valeur. /ps
spécifie la distance entre les valeurs. (b = 11 en hex) Ceci est nécessaire car $spat
séparera les espaces. Avec ces arguments, la liste devient:
0:000> .foreach /pS b /ps b (name {.imgscan}) { .echo name }
notepad.exe
WINSPOOL.DRV
comdlg32.dll
Secur32.dll
USER32.dll
COMCTL32.dll
msvcrt.dll
GDI32.dll
RPCRT4.dll
KERNEL32.dll
ntdll.dll
SHELL32.dll
SHLWAPI.dll
ADVAPI32.dll
$ craché
${}
est la fonction de correspondance de chaîne générique MASM. Il fera correspondre le premier argument au motif du second argument. Il ne fait pas la différence entre les majuscules et les minuscules. Par conséquent, NOTEPAD.EXE, NotePad.eXe, etc.
.if($spat("${name}","*.exe") !=0) {.echo "found it!"}
$ {}
${<alias name>}
est l'interpréteur d'alias. Vous intégrez .echo CrashFirstmodule
où vous voulez que la valeur de votre alias soit écrite dans une chaîne. Si vous utilisez l'alias dans une commande, vous pouvez simplement l'utiliser pour que notepad.exe
renvoie en écho ${/v:<alias name>}
. Dans les cas où vous entendez le nom de l’alias, vous pouvez le spécifier comme aS CrashFirstModule "${name}"
, ce qui résoudra simplement le nom de l’alias. Cette prévention d'extension est nécessaire lors de la réaffectation d'un alias. UnknownModule
aurait eu pour effet de définir l'alias aS
sur .break
, car <=> aurait été étendu à sa valeur avant l'exécution de la commande.
aS
<=> est l’une des commandes permettant d’attribuer des alias. <=> se termine par; ou la fin de la ligne et dépouiller le " de l'entrée. La ligne suivante sera alias <=> à <=>:
aS ${/v:CrashFirstModule} "UnknownModule"
.break
<=> termine le <=> après qu'une correspondance ait été trouvée.
Fin
Ce sont tous les éléments qui composent la commande que j'utilise. J'espère que quelqu'un d'autre tirera profit de cette question et de sa réponse!
Autres conseils
pourquoi ne pas utiliser info peb? Vous trouverez ci-dessous ce dont vous avez besoin:
?? @$peb->ProcessParameters
ntdll.dll
sera présent dans chaque processus, donc je suppose que le problème est le chargement de symboles.
Quoi qu’il en soit, cela devrait permettre de supprimer le saut de ligne:
.foreach(Module {lm 1m}) { aS CrashApp Module; .break }
.foreach(Module {lm 1m a $exentry}) { aS CrashApp Module }