Descodificación de trazas de pila
Ofuscar una aplicación añade una capa de protección a la propiedad intelectual y ofrece una ventaja competitiva, porque dificulta la ingeniería inversa. Sin embargo, esta seguridad adicional complica los informes de errores. La ofuscación puede dificultar el análisis de los cierres inesperados, ya que la traza de pila suele convertirse en una serie de símbolos ilegibles, lo que complica la depuración.
Descodificación de trazas de pila en .NET
Los desarrolladores de .NET suelen recurrir a las trazas de pila para localizar la causa de los errores de una aplicación. Sin embargo, la ofuscación convierte estas trazas en algo ininteligible. Con Babel Obfuscator, descodificar estas trazas de pila ofuscadas es sencillo. La herramienta necesita un archivo map, que se genera durante el proceso de ofuscación.
Generación del archivo map
Cuando se activa la generación del archivo map XML en Babel Obfuscator, el archivo map se genera de forma predeterminada en el mismo directorio que el ensamblado ofuscado. El archivo toma el nombre del ensamblado original con .map.xml añadido al final (por ejemplo, MyApp.exe.map.xml).
El archivo map generado contiene la relación entre los nombres ofuscados de los símbolos y los originales.
Tenga en cuenta que conviene desactivar el renombrado con sobrecarga (--nooverloaded), porque asigna el mismo nombre a métodos distintos y puede añadir ambigüedad al descodificar la traza de pila. Si el renombrado con sobrecarga está activado, Babel muestra durante la descodificación todos los métodos que pueden coincidir.
Puede cambiar la ubicación de salida del archivo map de distintas maneras, según cómo use Babel.
Línea de comandos
babel MyApp.exe --mapout CustomPath/MyMapping.xmlSi omite el parámetro con la ruta del archivo, se usa la convención de nombres predeterminada en el directorio de destino.
Tarea de MSBuild
<Babel GenerateMapOutFile="true" MapOutFile="CustomPath/MyMapping.xml" />Paquete NuGet de Babel Obfuscator
<PropertyGroup>
<GenerateMapOutFile>true</GenerateMapOutFile>
<BabelMapOutFile>CustomPath/MyMapping.xml</BabelMapOutFile>
</PropertyGroup>Babel Desktop
En Babel Desktop, seleccione el ensamblado y active GenerateMapOutFile en el grupo Output & diagnostics del panel de propiedades. Establezca MapOutFile para escribir el archivo map en una ruta personalizada. Consulte Proyectos de ofuscación.
Descodificación de la traza de pila ofuscada
Cuando una aplicación ofuscada se cierra de forma inesperada y produce una traza de pila ofuscada, use Babel para descodificarla. Babel Obfuscator incluye herramientas integradas para descodificar las trazas de pila ofuscadas mediante los archivos map.
Babel Desktop
Los pasos siguientes son un resumen; consulte Descodificador de pila para ver la guía completa.
Abrir el descodificador de pila
Abra la paleta de comandos y ejecute Herramientas: descodificador de pila.
Añadir los archivos map
Añada los archivos map XML con Añadir archivos map…, o suéltelos sobre el descodificador. Puede añadir varios archivos map cuando la traza abarca varios ensamblados.
Pegar la traza de pila
Pegue la traza de pila ofuscada, o cárguela desde un archivo con Abrir traza….
Descodificar
Haga clic en Descodificar para ver la traza de pila descodificada.
Línea de comandos
Como alternativa, use la herramienta de línea de comandos babel:
babel --stacktrace StackTrace.txt --mapin MyApp.exe.map.xml --mapin Library.dll.map.xmlPuede incluir varios archivos map si la traza de pila abarca varios ensamblados.
Frames del proxy dinámico
Cuando el proxy dinámico está activado, Babel dirige las llamadas elegibles a través de métodos puente generados. Cada puente aparece como un frame adicional, de modo que una traza descodificada intercala sus propios métodos con la infraestructura interna de Babel. Babel registra en el archivo map el método al que sustituye cada puente, y el descodificador lo muestra:
at Acme.Backup.ZipReader.OpenZip(System.String filename)
at (System.String ) -> proxy for System.IO.Compression.ZipFile::OpenRead
at Acme.Backup.BackupReader.IsBackupFile(System.String path)La anotación -> proxy for <DeclaringType>::<Method> indica exactamente a qué método llamaba el puente. La firma ya se muestra en el frame, así que no se repite en la anotación. Los archivos map producidos por versiones anteriores de Babel, que no registran el destino del proxy, se descodifican como antes y muestran en su lugar la nota genérica -> babel generated code.
Ocultar los frames generados por Babel
Si solo le interesa su propia cadena de llamadas, Babel puede descartar todos los frames que ha generado (los puentes del proxy y los frames anónimos de tiempo de ejecución por los que pasan sus llamadas) y dejar una traza idéntica a la que obtendría con la aplicación sin ofuscar.
Desde la línea de comandos, añada la clave frames=user a la opción --stacktrace:
babel --stacktrace StackTrace.txt --stacktrace frames=user --mapin MyApp.exe.map.xmlframes=all es el valor predeterminado y conserva todos los frames. En Babel Desktop, el descodificador de pila oculta estos frames de forma predeterminada: la casilla Ocultar los frames añadidos por Babel está marcada. Desmárquela para conservar todos los frames.
Con los frames generados ocultos, la traza anterior queda así:
at System.IO.Compression.ZipFile.Open(System.String archiveFileName)
at Acme.Backup.ZipReader.OpenZip(System.String filename)
at Acme.Backup.BackupReader.IsBackupFile(System.String path)Automatización de la desofuscación de trazas de pila
Babel Obfuscator ofrece una interfaz para automatizar la descodificación de trazas de pila. Incluya en su ensamblado .NET una referencia a babel.dll (o a babel.exe en las aplicaciones heredadas de .NET Framework) y use la API proporcionada para descodificar las trazas de pila mediante código.
El fragmento de código siguiente muestra cómo configurar una aplicación de consola para desofuscar una traza de pila cargada desde un archivo externo:
// Example of setting up the console application
static int Main(string[] args)
{
if (args.Length < 2)
{
Console.WriteLine("Usage: stackdecode.exe <filename> <xmlmapfile1> [xmlmapfile2 ...]");
return 1;
}
StackTraceDeobfuscator stk = new StackTraceDeobfuscator();
foreach (var xmlMapFile in args.Skip(1))
{
try
{
stk.AddMapFile(xmlMapFile);
}
catch (Exception ex)
{
Console.WriteLine(String.Format("Error reading XML map file '{0}':n{1}", xmlMapFile, ex.Message));
return 1;
}
}
try
{
StreamReader sr = new StreamReader(args[0]);
Console.WriteLine("Deobfuscated Stack Trace:");
Console.WriteLine(stk.DeobfuscateStack(sr));
}
catch (Exception ex)
{
Console.WriteLine(String.Format("Could not decode stack trace file '{0}':n{1}", args[0], ex.Message));
return 1;
}
return 0;
}Para descartar los frames generados por Babel (consulte Ocultar los frames generados por Babel) al descodificar mediante código, establezca HideGeneratedFrames en el desofuscador antes de llamar a DeobfuscateStack:
StackTraceDeobfuscator stk = new StackTraceDeobfuscator();
stk.HideGeneratedFrames = true;La interfaz de programación para desofuscar trazas de pila ofrece a los desarrolladores una herramienta eficaz para mejorar su forma de depurar. Al integrar este mecanismo en sus aplicaciones, los desarrolladores pueden automatizar el proceso de descodificación, tratar con eficiencia las trazas de pila ofuscadas y mantener la integridad y la seguridad de su código.
Uso de archivos PDB con trazas de pila ofuscadas
Opcionalmente, use archivos PDB en producción para obtener el archivo de código fuente y los números de línea en la traza de pila descodificada. En concreto, Babel puede cifrar los nombres de archivo y los nombres de símbolo de los PDB, de modo que aparezcan cifrados en las trazas de pila y no se revele información confidencial sobre las rutas de los archivos.
Para activar esta función, establezca una contraseña de PDB. Elija una contraseña segura: cifra los nombres de archivo del PDB y se necesita después para desofuscar las trazas de pila.
- Línea de comandos: use la opción
--pdbpwd, por ejemplobabel MyApp.exe --debug --pdbpwd <password>. - MSBuild: establezca la propiedad
PdbPwdde la tarea Babel. - Babel Desktop: seleccione el ensamblado y establezca
PdbPwden el grupo Advanced del panel de propiedades. La contraseña solo se conserva durante la sesión actual: no se guarda en el proyecto y hay que volver a introducirla después de reiniciar Babel Desktop.
Una vez activada esta función y establecida la contraseña de PDB, Babel cifra los nombres de archivo y otra información relevante durante el proceso de ofuscación. Como resultado, en sus trazas de pila los nombres de archivo aparecen como cadenas cifradas en lugar de las rutas originales.
System.Exception: (0x80131904): A network-related or instance-specific error occurred while establishing a connection to the server.
at System.Data.SqlClient.SqlConnection.Open()
at b.a(String g)
at c.b() in <GFpQHv9iwQzX1Zmh+… >:line 21
at c.a(String h)
at Acme.ViewModel.MainViewModel.get_Message() in <GFpQHv9iwQzX1Zmh+… >:line 28 Todos los datos necesarios para el descifrado se almacenan en el archivo map XML, por lo que el archivo PDB no hace falta para la descodificación. La traza de pila descodificada contiene el nombre de archivo descifrado.
System.Exception: (0x80131904): A network-related or instance-specific error occurred while establishing a connection to the server.
at System.Data.SqlClient.SqlConnection.Open()
at Acme.Entities.DatabaseContext.ConnectToDatabase(System.String connectionString)
at Acme.ViewModel.RS.CheckResourceLoaded() in C:AcmeAcme.ViewModelRS.cs:line 21
at Acme.ViewModel.RS.GetString(System.String name)
at Acme.ViewModel.MainViewModel.get_Message() in C:AcmeAcme.ViewModelViewModelMainViewModel.cs:line 28Este método ofrece un equilibrio entre seguridad y facilidad de mantenimiento. Protege la propiedad intelectual implícita en la estructura de sus archivos y, al mismo tiempo, permite obtener información útil de las trazas de pila para la depuración y el análisis de errores.
Al configurar el cifrado de los PDB, la estructura interna de su aplicación y la organización de sus archivos se mantienen seguras y confidenciales, incluso cuando comparte los PDB para la solución de problemas o el soporte.