windows - online - tag rename
¿Cómo se puede cambiar un PDB que no coincida con la edad para que coincida correctamente? (3)
O simplemente puede usar la sugerencia aquí para que windbg ignore firmas y edades no coincidentes:
http://www.debuginfo.com/articles/debuginfomatch.html
... Mientras que por defecto [windbg] tampoco permite cargar información de depuración no coincidente, el comando del depurador .symopt puede cambiar el comportamiento predeterminado. Después de que hayamos emitido el comando ".symopt + 0x40", el depurador aceptará y cargará los archivos de PDB y DBG no coincidentes.
Espero que esto ayude.
Nuestro proceso de compilación nocturno se interrumpió durante mucho tiempo, por lo que generó archivos PDB que tenían unas horas de antigüedad diferentes a los archivos de imagen correspondientes. Desde entonces he solucionado el problema.
Sin embargo, me gustaría comenzar a usar un servidor de símbolos, pero no puedo tener que usar estos archivos pdb que no coinciden con la edad. Resuelvo este problema utilizando el método .symopt + 0x40 en windbg. Eso significa que tengo que organizar todos mis archivos pdb a mano, y después de años y años de lanzamientos, eso se suma.
Estoy buscando una manera de modificar el mecanismo que usa windbg para marcar la edad de un pdb, y forzarlo para que coincida con mi archivo de imagen. La utilidad ChkMatch hace algo similar, pero para firmas pdb. El desarrollador afirma en la página "ChkMatch es capaz de hacer que un ejecutable y un archivo PDB coincidan si tienen firmas diferentes pero de la misma edad (consulte este artículo para obtener más información sobre la firma y la edad de la PDB). Si la antigüedad es diferente, la herramienta no puede los archivos coinciden ".
Eché un vistazo dentro de un hexeditor, e incluso encontré lo que parecían los bits correspondientes a la edad, pero debe tirar algunos trucos más internamente, porque no pude hacerlo funcionar.
¿Algunas ideas?
EDITAR : No sé si esto ayuda, pero en mi caso particular, la diferencia de edad fue causada por el hecho de volver a vincular los archivos DLL, lo que también recrearía los archivos de PDB. Sin embargo, nuestro proceso de compilación estaba almacenando las dlls originales (antes del relink), y el pdb después del relink. Pensé en recrear de alguna manera tal situación a mano. Es decir, forzar un relink en un DLL, pero guardar el pdb en ambos casos. Entonces podría hacer una comparación binaria de los dos archivos para ver cómo cambiaron. ¿Tal vez ejecutar algún tipo de software de parches que haga esto automáticamente? Al ver qué cambió exactamente en mi caso de control, ¿quizás podría hacer lo mismo con las DLL y las PDB guardadas en el proceso de compilación de mi empresa?
EDITAR : lo he demostrado fuera !!!! Gracias a uno de los comentarios de la primera respuesta, verifiqué un enlace a los archivos PDF del libro "Los secretos de Windows 2000 no documentados: un libro de cocina para programadores". Y el autor entra en gran detalle sobre el formato de archivo pdb. Como dije antes, ya había cargado el pdb en un editor hexadecimal y giré algunos bits apareciendo que hice la coincidencia de edad / firma, pero no funcionó. Bueno, después de usar la utilidad del libro de secretos de W2k para "explotar" el pdb en las transmisiones incluidas, descubrí que ocultaban otra referencia a la era en la transmisión 3 !!!!!!! Una vez que también lo volteé, se combinó en windbg. Esto es enorme! Muchas gracias .... servidor de símbolos AQUÍ YO VINO!
windbg no modificará la edad de pdb; solo lo busca para que coincida con el ejecutable; el compilador lo hace cuando (re) genera archivos ejecutables y de depuración.
ahora, según el artículo debuginfo.com, no es demasiado difícil llegar al directorio de depuración adecuado (de tipo vista de código), compararlo con la firma PDB7 y realizar modificaciones a la edad o GUID dentro de un ejecutable. ¿Por qué no es esa una opción?
Supongo que quieres actualizar pdb en su lugar? Tengo miedo, PDB es un formato propietario. hay varias API de solo lectura (dbghelp.dll y dia sdk), pero en cuanto a las modificaciones, debe adivinar los detalles para poder modificarlos.
Aunque como dijo SamB, en PDB (formato 7, mi prueba se basa en .exe y .pdb generados por VS2010, y windbg 6.9.0003.113 X86) hay una referencia adicional a la antigüedad, por lo que habrá 3 edades para modificar en el archivo PDB. . Desafortunadamente, SamB no nos dijo cómo encontrar la tercera edad mágica, la secuencia 3? ¡no! Según mi prueba, extraigo más de 100 flujos de pdb, probé 02 (si SamB tiene un índice de 0) y 03, ambos no pueden encontrar la edad.
Reparar las otras 2 edades es fácil, tan pronto como tenga un editor hexadecimal y windbg.
- Encuentra el GUID y la edad
usando symchk para obtener la firma (un GUID) del archivo PDB que no coincide: symchk your.exe / v / s.
La salida típica contendrá:
[SYMCHK] ------------------------------------
SymbolCheckVersion 0x00000002
Result 0x00010001
DbgFilename CPP_Snippet.dbg
DbgTimeDateStamp 0x00000000
DbgSizeOfImage 0x00000000
DbgChecksum 0x00000000
PdbFilename E:/zrf/C_CPP/CPP_Snippet.pdb
PdbSignature {6D8D99B0-E96B-4093-9D97-8BDC5152B6E0}
PdbDbiAge 0x00000188
- Arregla las 2 edades más fáciles.
Busque la última parte del GUID: 8BDC5152B6E0, porque solo la última parte está libre de bytes del problema big-endian / little-endian, es exactamente igual que en los archivos pdb. Tenga cuidado de buscar como valor hexadecimal en bruto, para hacerlo más preciso, debe verificar que los otros valores en el GUID (necesidad de revertir el orden de bytes en X86) coincidan exactamente. Se encontrarán exactamente 2 GUID dentro del archivo PDB, la edad que lo acompaña es justo antes del primer byte del GUID. Modificarlo ¡Eso es!
Mi forma bruta de descubrir la tercera edad.
volcar el número hexadecimal de su archivo PDB, un byte (2 números hexadecimales) por línea. od -v -t x1 your.pdb | sed ''s / ^ [0-9a-f] * //; s / / / n / g''> age_offset.txt
obtenga el número de línea de cada edad coincidente, en mi caso son 4 líneas consecutivas que tienen un valor 88 01 00 00, vim age_offset.txt: g / 88 / n01 / n00 / n00 / s / ^ / / = (línea (''. '').'': '') /
Este es un comando de modo ex, que debe ser compatible con una versión reciente de vim.
:enfermedad venérea
Esto eliminará todas las líneas que no contengan '':'', las líneas restantes son números de línea que son el desplazamiento de cada edad coincidente.
:% s /:.*//
Esto recortará: 88 y dejando el offset solo.
:% s /.*//= (submatch (0) - 1) /
Este comando resta cada número por 1, lo hago porque el número de línea en vim es 1-index, y el byte offset de todas las edades debe ser 0-index para hacer feliz a la empresa de servicios públicos.
: w
guarda el archivo
Ahora obtenemos un archivo de texto con cada línea que contiene un número decimal que representa un desplazamiento, a partir de este desplazamiento, los siguientes 4 bytes son candidatos para su edad de sueño.
A continuación, trato de modificar todas las edades potenciales y luego trato de verificarlo por symchk hasta que coincida, cada vez que solo se corrija un offset.
En primer lugar, haré una copia de seguridad de un PDB con las 2 edades (y GUID) que se modificarán. Llamémoslo ori.pdb
Aquí está el script por lotes para hacer el trabajo duro:
for /F usebackq %%i in (`type age_offset.txt`) DO ( copy /y ori.pdb CPP_Snippet.pdb @rem dd if=ori.pdb bs=1c count=4 skip=%%i | xxd -g1 | grep "88 01 00 00" || echo "Bad data at %%i" && goto exit dd if=pdb_age.dat of=CPP_Snippet.pdb bs=1c count=4 seek=%%i conv=notrunc symchk CPP_Snippet.exe /s . && echo "Found it at offset %%i" && goto exit ) :exit
Buena suerte, encontré el lugar correcto en la compensación 38.
No es la forma más rápida de probar el error de la corrección correcta al parche, pero a mi me funciona, es mi prototipo para asegurarse de que solo haya una edad adicional para corregir, de lo contrario, la posible combinación es enorme (tengo 111 candidatos de edad) intentarlo) y por lo tanto una forma de error de prueba no es pragmática.
Creo que es muy fácil escribir una utilidad para hacer el mismo trabajo de una manera más rápida.
Por cierto: de acuerdo a mi prueba. chkmatch puede reportar coincidencias mientras que symchk y windbg vs piensan que no coinciden.
windbg command! itoldyouso match mientras que .reload / f your_module.exe aún no puede coincidir.
Después de que las 3 edades hayan sido reparadas, no solo windbg sino Visual Studio pueden cargar los archivos pdb.