{"id":801,"date":"2010-06-16T19:59:04","date_gmt":"2010-06-16T17:59:04","guid":{"rendered":"http:\/\/192.168.1.2:8080\/?p=801"},"modified":"2010-06-16T19:59:04","modified_gmt":"2010-06-16T17:59:04","slug":"decompilar-una-aplicacion-de-android","status":"publish","type":"post","link":"https:\/\/nauj27.com\/blog\/?p=801","title":{"rendered":"Decompilar una aplicaci\u00f3n de Android"},"content":{"rendered":"<p>Las aplicaciones en Android se programan en Java y es un hecho conocido que Java se puede decompilar con relativa sencillez. Existen varios programas con interfaz gr\u00e1fica, distintos nombres, distintas utilidades pero al final todos usan uno internamente <span title=\"As Far As I Know\"><span style=\"text-decoration: underline;\">AFAIK<\/span><\/span> para funcionar: <a href=\"http:\/\/www.varaneckas.com\/jad\">jad<\/a>.<\/p>\n<p>Debido a esto es f\u00e1cil caer en el error como a mi me ocurri\u00f3 de pensar en que los programas de Android se van a poder decompilar y modificar f\u00e1cilmente. Esto en la realidad no ocurre as\u00ed ya que el c\u00f3digo binario generado para Android es para su ejecuci\u00f3n en la <a href=\"http:\/\/www.dalvikvm.com\/\">DalvikVM<\/a> que no tiene nada que ver con el bytecode de Java.<\/p>\n<p>Cuando descomprimes un apk (porque tambi\u00e9n es bien sabido que no es m\u00e1s que un zip renombrado con unas caracter\u00edsticas especiales), se puede encontrar un fichero classes.dex que contiene las clases de java usadas por la aplicaci\u00f3n, entre otras cosas:<\/p>\n<blockquote>\n<div id=\"_mcePaste\">$ file classes.dex<\/div>\n<div id=\"_mcePaste\">classes.dex: Dalvik dex file version 035<\/div>\n<\/blockquote>\n<p>Este fichero se puede deconstruir por ejemplo con las utilidades del proyecto <a href=\"http:\/\/code.google.com\/p\/smali\/\">smali<\/a>, lo cual generar\u00e1 una serie de ficheros .smali con los opcodes de Dalvik. Estos ficheros .smali tienen el siguiente aspecto:<\/p>\n<blockquote><p>.class public LHelloWorld;<br \/>\n.super Ljava\/lang\/Object;<br \/>\n.method public static main([Ljava\/lang\/String;)V<br \/>\n    .registers 2<\/p>\n<p>    sget-object v0, Ljava\/lang\/System;->out:Ljava\/io\/PrintStream;<\/p>\n<p>    const-string\tv1, \u00abHello World!\u00bb<\/p>\n<p>    invoke-virtual {v0, v1}, Ljava\/io\/PrintStream;->println(Ljava\/lang\/String;)V<\/p>\n<p>    return-void<br \/>\n.end method<\/p><\/blockquote>\n<p>As\u00ed el fichero se puede en principio modificar con mayor o menor dificultad y volver a compilar con smali.<\/p>\n<p>Pero no todo es tan bonito como parece hasta aqu\u00ed, porque ahora hay que reconstruir el apk de la aplicaci\u00f3n. El primer paso ser\u00e1 actualizar el classes.dex dentro del apk. Esto se puede hacer con la misma utilidad zip est\u00e1ndar. Despu\u00e9s hay que firmar el archivo con algo como:<\/p>\n<blockquote><p>$ jarsigner -verbose -keystore my_keystore com.nauj27.android.hackme.apk android<\/p><\/blockquote>\n<p>El problema viene cuando se intenta verificar la firma del paquete, obteniendo el siguiente mensaje:<\/p>\n<blockquote><p>$ jarsigner -verify com.nauj27.android.hackme.apk<br \/>\njarsigner: java.lang.SecurityException: invalid SHA1 signature file digest for classes.dex<\/p><\/blockquote>\n<p>Cada fichero lleva una firma SHA1 que <span title=\"As Far As I Know\"><span style=\"text-decoration: underline;\">AFAIK<\/span><\/span> no es posible saltarse. Probablemente se podr\u00e1 hacer algo m\u00e1s pero por ahora lo voy a dejar aqu\u00ed.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Las aplicaciones en Android se programan en Java y es un hecho conocido que Java se puede decompilar con relativa sencillez. Existen varios programas con interfaz gr\u00e1fica, distintos nombres, distintas utilidades pero al final todos usan uno internamente AFAIK para funcionar: jad. Debido a esto es f\u00e1cil caer en el error como a mi me [&hellip;]<\/p>\n","protected":false},"author":4,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":[],"categories":[151],"tags":[85,165,164,153],"_links":{"self":[{"href":"https:\/\/nauj27.com\/blog\/index.php?rest_route=\/wp\/v2\/posts\/801"}],"collection":[{"href":"https:\/\/nauj27.com\/blog\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/nauj27.com\/blog\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/nauj27.com\/blog\/index.php?rest_route=\/wp\/v2\/users\/4"}],"replies":[{"embeddable":true,"href":"https:\/\/nauj27.com\/blog\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=801"}],"version-history":[{"count":2,"href":"https:\/\/nauj27.com\/blog\/index.php?rest_route=\/wp\/v2\/posts\/801\/revisions"}],"predecessor-version":[{"id":803,"href":"https:\/\/nauj27.com\/blog\/index.php?rest_route=\/wp\/v2\/posts\/801\/revisions\/803"}],"wp:attachment":[{"href":"https:\/\/nauj27.com\/blog\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=801"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/nauj27.com\/blog\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=801"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/nauj27.com\/blog\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=801"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}