Pregunta

Información general

Para guardar los volcados de memoria, tengo un script pasado a cdb.exe en el valor Debugger de la clave de registro AeDebug:

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"

Aquí está la primera parte del 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

* (...)

El problema

Con símbolos, esto funciona exactamente como me gustaría, obtengo archivos de registro con nombres sensibles como:

  • LHCBDRDT.exe_process_147c_2009-01-06_23-10-05-371.log

Sin embargo, si los símbolos no están disponibles, obtengo un nombre de archivo de registro como este:

  • ${CrashFirstModule}_process_17a8_2009-01-06_23-10-01-124.log

Esto se debe a que el comando alias no pudo establecer el alias. El comando alias es uno que obtuve de DumpAnalysis.org . Este comando extrae el nombre del encabezado PEB para la imagen, usando ntdll.dll. Sin símbolos para el sistema operativo, no sabe dónde encontrar la función a la que está llamando desde ntdll.dll.

La pregunta

¿Alguien sabe o tiene un comando para obtener el nombre de la imagen como un alias para usar en nombres de archivos que aún funcionarían en estas situaciones?

¿Fue útil?

Solución

Entonces, aquí estoy, años después, con una respuesta.

La respuesta

En ausencia de archivos de símbolos, esta es la mejor manera que he encontrado para obtener el nombre del ejecutable que se bloqueó para que pueda usarse en un nombre de archivo para escribir un archivo de registro o volcado por caída de un script:

aS ${/v:CrashFirstModule} "UnknownModule"
.foreach /pS b /ps b (name {.imgscan}) { .if($spat("${name}","*.exe") !=0){aS ${/v:CrashFirstModule} "${name}"; .break} }

Después de estas dos líneas, CrashFirstModule tendrá un alias para " UnknownModule " o el nombre del ejecutable. Esto solo funciona si el ejecutable termina en & Quot; .exe & Quot ;, pero eso me parece razonable, y funciona bien en el caso donde lo estoy usando. Puede agregar otro .if para manejar otro final si necesita admitir cosas como & Quot; .com & Quot ;.

La respuesta: explicada

.imgscan

.imgscan proporciona una lista de módulos ejecutables, que incluirá .exe, .dll, .drv, etc. Este es el punto de partida para encontrar el nombre del ejecutable.

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 se usa para recorrer la lista de imágenes. /pS especifica qué tan lejos de la lista está el primer valor. /ps especifica la distancia entre valores. (b = 11 en hexadecimal) Esto es necesario ya que $spat se separará en los espacios. Con estos argumentos, la lista se convierte en:

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

$ spat

${} es la función de coincidencia de cadenas comodín MASM. Emparejará el primer argumento contra el patrón en el segundo argumento. No distingue entre mayúsculas y minúsculas, por lo que coincidirá con NOTEPAD.EXE y NotePad.eXe, etc.

.if($spat("${name}","*.exe") !=0) {.echo "found it!"}

$ {}

${<alias name>} es el intérprete de alias. Incruste .echo CrashFirstmodule donde quiera que el valor de su alias se escriba en una cadena. si está utilizando el alias en un comando, puede usarlo, por lo que notepad.exe se haría eco ${/v:<alias name>}. En aquellos casos en los que realmente te refieres al nombre del alias, puedes especificarlo como aS CrashFirstModule "${name}", lo que simplemente resolverá el nombre del alias. Esta prevención de expansión es necesaria al reasignar un alias. UnknownModule habría resultado en establecer el alias aS en .break, ya que <=> se habría expandido a su valor antes de ejecutar el comando.

aS

<=> es uno de los comandos para asignar alias. <=> es terminado por; o al final de la línea y eliminará el " desde la entrada. La siguiente línea alias <=> a <=>:

aS ${/v:CrashFirstModule} "UnknownModule"

.break

<=> finaliza el <=> después de encontrar una coincidencia.

Fin

Esas son todas las piezas que componen el comando que estoy usando. ¡Espero que alguien más se beneficie de esta pregunta y respuesta!

Otros consejos

¿por qué no usar información de peb? A continuación se muestra lo que necesita:

?? @$peb->ProcessParameters

ntdll.dll estará presente en cada proceso, así que supongo que el problema es la carga de símbolos.

De todos modos, esto debería funcionar para deshacerse del salto de línea:

.foreach(Module {lm 1m}) { aS CrashApp Module; .break }

.foreach(Module {lm 1m a $exentry}) { aS CrashApp Module }
Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top