skip to main | skip to sidebar

Android Development Tutorial

Pages

  • Home
 
  • RSS
  • Twitter
Related Posts Plugin for WordPress, Blogger...
Wednesday, October 17, 2012

Get XML from APK

Posted by Raju Gupta at 10:54 PM – 0 comments
 

Step 1. Pass the <APK> file path+name in getIntents(...) method.
Step 2. Run the attached code.

This will convert all layout xmls and extract all files in same directory struture as defined.

import java.io.InputStream;
import java.util.jar.JarFile;

public class Test {

 public static void main(String[] args) {
  Test t = new Test();
  t.getIntents("C:\android\apk\TestPlayer.apk");
  System.out.println("complete ...");
 }

 public void getIntents(String path) {
    try {
      JarFile jf = new JarFile(path);
      InputStream is = jf.getInputStream(jf.getEntry("main.xml"));
      byte[] xml = new byte[is.available()];
      int br = is.read(xml);
      //Tree tr = TrunkFactory.newTree();
      System.out.println("calling ...");
      decompressXML(xml);
      //prt("XMLn"+tr.list());
    } catch (Exception ex) {
     ex.printStackTrace();
      //console.log("getIntents, ex: "+ex);  ex.printStackTrace();
    }
  } // end of getIntents

 
 
 
 
 // decompressXML -- Parse the 'compressed' binary form of Android XML docs 
 // such as for AndroidManifest.xml in .apk files
 public static int endDocTag = 0x00100101;
 public static int startTag =  0x00100102;
 public static int endTag =    0x00100103;
 public void decompressXML(byte[] xml) {
 // Compressed XML file/bytes starts with 24x bytes of data,
 // 9 32 bit words in little endian order (LSB first):
 //   0th word is 03 00 08 00
 //   3rd word SEEMS TO BE:  Offset at then of StringTable
 //   4th word is: Number of strings in string table
 // WARNING: Sometime I indiscriminently display or refer to word in 
 //   little endian storage format, or in integer format (ie MSB first).
 int numbStrings = LEW(xml, 4*4);

 // StringIndexTable starts at offset 24x, an array of 32 bit LE offsets
 // of the length/string data in the StringTable.
 int sitOff = 0x24;  // Offset of start of StringIndexTable

 // StringTable, each string is represented with a 16 bit little endian 
 // character count, followed by that number of 16 bit (LE) (Unicode) chars.
 int stOff = sitOff + numbStrings*4;  // StringTable follows StrIndexTable

 // XMLTags, The XML tag tree starts after some unknown content after the
 // StringTable.  There is some unknown data after the StringTable, scan
 // forward from this point to the flag for the start of an XML start tag.
 int xmlTagOff = LEW(xml, 3*4);  // Start from the offset in the 3rd word.
 // Scan forward until we find the bytes: 0x02011000(x00100102 in normal int)
 for (int ii=xmlTagOff; ii<xml.length-4; ii+=4) {
   if (LEW(xml, ii) == startTag) { 
     xmlTagOff = ii;  break;
   }
 } // end of hack, scanning for start of first start tag

 // XML tags and attributes:
 // Every XML start and end tag consists of 6 32 bit words:
 //   0th word: 02011000 for startTag and 03011000 for endTag 
 //   1st word: a flag?, like 38000000
 //   2nd word: Line of where this tag appeared in the original source file
 //   3rd word: FFFFFFFF ??
 //   4th word: StringIndex of NameSpace name, or FFFFFFFF for default NS
 //   5th word: StringIndex of Element Name
 //   (Note: 01011000 in 0th word means end of XML document, endDocTag)

 // Start tags (not end tags) contain 3 more words:
 //   6th word: 14001400 meaning?? 
 //   7th word: Number of Attributes that follow this tag(follow word 8th)
 //   8th word: 00000000 meaning??

 // Attributes consist of 5 words: 
 //   0th word: StringIndex of Attribute Name's Namespace, or FFFFFFFF
 //   1st word: StringIndex of Attribute Name
 //   2nd word: StringIndex of Attribute Value, or FFFFFFF if ResourceId used
 //   3rd word: Flags?
 //   4th word: str ind of attr value again, or ResourceId of value

 // TMP, dump string table to tr for debugging
 //tr.addSelect("strings", null);
 //for (int ii=0; ii<numbStrings; ii++) {
 //  // Length of string starts at StringTable plus offset in StrIndTable
 //  String str = compXmlString(xml, sitOff, stOff, ii);
 //  tr.add(String.valueOf(ii), str);
 //}
 //tr.parent();

 // Step through the XML tree element tags and attributes
 int off = xmlTagOff;
 int indent = 0;
 int startTagLineNo = -2;
 while (off < xml.length) {
   int tag0 = LEW(xml, off);
   //int tag1 = LEW(xml, off+1*4);
   int lineNo = LEW(xml, off+2*4);
   //int tag3 = LEW(xml, off+3*4);
   int nameNsSi = LEW(xml, off+4*4);
   int nameSi = LEW(xml, off+5*4);

   if (tag0 == startTag) { // XML START TAG
     int tag6 = LEW(xml, off+6*4);  // Expected to be 14001400
     int numbAttrs = LEW(xml, off+7*4);  // Number of Attributes to follow
     //int tag8 = LEW(xml, off+8*4);  // Expected to be 00000000
     off += 9*4;  // Skip over 6+3 words of startTag data
     String name = compXmlString(xml, sitOff, stOff, nameSi);
     //tr.addSelect(name, null);
     startTagLineNo = lineNo;

     // Look for the Attributes
     StringBuffer sb = new StringBuffer();
     for (int ii=0; ii<numbAttrs; ii++) {
       int attrNameNsSi = LEW(xml, off);  // AttrName Namespace Str Ind, or FFFFFFFF
       int attrNameSi = LEW(xml, off+1*4);  // AttrName String Index
       int attrValueSi = LEW(xml, off+2*4); // AttrValue Str Ind, or FFFFFFFF
       int attrFlags = LEW(xml, off+3*4);  
       int attrResId = LEW(xml, off+4*4);  // AttrValue ResourceId or dup AttrValue StrInd
       off += 5*4;  // Skip over the 5 words of an attribute

       String attrName = compXmlString(xml, sitOff, stOff, attrNameSi);
       String attrValue = attrValueSi!=-1
         ? compXmlString(xml, sitOff, stOff, attrValueSi)
         : "resourceID 0x"+Integer.toHexString(attrResId);
       sb.append(" "+attrName+"=""+attrValue+""");
       //tr.add(attrName, attrValue);
     }
     prtIndent(indent, "<"+name+sb+">");
     indent++;

   } else if (tag0 == endTag) { // XML END TAG
     indent--;
     off += 6*4;  // Skip over 6 words of endTag data
     String name = compXmlString(xml, sitOff, stOff, nameSi);
     prtIndent(indent, "</"+name+">  (line "+startTagLineNo+"-"+lineNo+")");
     //tr.parent();  // Step back up the NobTree

   } else if (tag0 == endDocTag) {  // END OF XML DOC TAG
     break;

   } else {
     System.out.println("  Unrecognized tag code '"+Integer.toHexString(tag0)
       +"' at offset "+off);
     break;
   }
 } // end of while loop scanning tags and attributes of XML tree
 System.out.println("    end at offset "+off);
 } // end of decompressXML


 public String compXmlString(byte[] xml, int sitOff, int stOff, int strInd) {
   if (strInd < 0) return null;
   int strOff = stOff + LEW(xml, sitOff+strInd*4);
   return compXmlStringAt(xml, strOff);
 }


 public static String spaces = "                                             ";
 public void prtIndent(int indent, String str) {
  System.out.println(spaces.substring(0, Math.min(indent*2, spaces.length()))+str);
 }


 // compXmlStringAt -- Return the string stored in StringTable format at
 // offset strOff.  This offset points to the 16 bit string length, which 
 // is followed by that number of 16 bit (Unicode) chars.
 public String compXmlStringAt(byte[] arr, int strOff) {
   int strLen = arr[strOff+1]<<8&0xff00 | arr[strOff]&0xff;
   byte[] chars = new byte[strLen];
   for (int ii=0; ii<strLen; ii++) {
     chars[ii] = arr[strOff+2+ii*2];
   }
   return new String(chars);  // Hack, just use 8 byte chars
 } // end of compXmlStringAt


 // LEW -- Return value of a Little Endian 32 bit word from the byte array
 //   at offset off.
 public int LEW(byte[] arr, int off) {
   return arr[off+3]<<24&0xff000000 | arr[off+2]<<16&0xff0000
     | arr[off+1]<<8&0xff00 | arr[off]&0xFF;
 } // end of LEW


}
Email This BlogThis! Share to X Share to Facebook

Leave a Reply

Newer Post Older Post
Subscribe to: Post Comments (Atom)

More Technical Blogs

  • Tech Savvy - Technology Tips
  • PHP Video Tutorial
  • Java Programs with Output
  • C Programming Tutorial
  • Linux Tutorial
  • Language Tutorial
  • Web Development tutorial
  • Popular
  • Recent
  • Archives

Popular Posts

  • Reordering of listview
    Listview rows order can be changed using drag and drop functionality.Dragging should be enabled beyond the visible listview position. ...
Powered by Blogger.

Archives

  • ▼  2012 (44)
    • ▼  October (31)
      • Reordering of listview
      • Text-to-Speech capability for Android Devices
      • Android Stub uninstalling the existing client and ...
      • Tab creation in android screen
      • ListView Recordering by drag drop in Android
      • Android app for SimpleWiktionary
      • App in android for random quote generation
      • Implementing ListView-Adapter in Android
      • Extract all java classes from APK
      • Get XML from APK
      • Sending SMS from the Android Application
      • How to create Drop Down in Android
      • Android Page Navigation
      • To retrieve the cell info for Android device
      • Creating the enrty in the agenda for Android devices.
      • Test Application for Samsung Android devices
      • Color Picker from Image in Android
      • Image Switcher & Gallery in Android
      • Andorid application that listens to incoming sms
      • Accelerometer management for the Android devices
      • Alert box for Confirm
      • 3D Rotation in Android
      • Custom Bar Control for Android using Java
      • Creating Layouts TableRows and TextViews dynamical...
      • Android SeekBar
      • Dialing phone number from Google Android Application
      • Login Screen Creation using Android
      • Add a Progress Bar to Android based Mobile Screens
      • Adding a button to Android based mobile screens
      • Android Dynamically generating views
      • Timezone converter
    • ►  September (3)
    • ►  March (1)
    • ►  February (9)
  • ►  2011 (69)
    • ►  December (69)
 

Followers

Labels

  • Activities (9)
  • Andoird Menu (2)
  • Android timelineActivity. (1)
  • Android Adapter (1)
  • Android app (9)
  • Android App Inventor (1)
  • Android App Publishing (2)
  • Android Application Components (3)
  • Android Application Fundamental (2)
  • Android Architecture (1)
  • Android AsyncTask (1)
  • Android Basic (7)
  • Android Bootcamp Training (18)
  • Android Button Widget (3)
  • Android Custom Style (1)
  • Android Dialog (1)
  • Android Drawable (2)
  • Android Environment (1)
  • Android example (9)
  • Android File System (2)
  • Android Geolocation (2)
  • Android ImageView (1)
  • Android Installation (8)
  • Android intents (5)
  • Android lifecycle (1)
  • Android LIst (4)
  • Android Listener (4)
  • Android Manifest (3)
  • Android Market (1)
  • Android Notification (1)
  • Android Object (1)
  • Android Package File (1)
  • Android Platform (1)
  • Android service (4)
  • Android StatusActivity (1)
  • Android Theme Style (3)
  • Android Traceview (1)
  • Android UI (6)
  • Android Unit Testing (1)
  • Android Widget (4)
  • AndroidManifest.xml (4)
  • Application Icon (1)
  • Broadcast Receiver (2)
  • Content Providers (1)
  • Creating Activities (1)
  • Creating Custom Styles in Android (1)
  • Creating Multiple Activities (1)
  • Database (3)
  • draw9patch (1)
  • Eclipse (12)
  • Explicit Intents (2)
  • Explicit Intents Example (1)
  • Hello world with Android (1)
  • Helloworld with Android (5)
  • Implicit Intents (2)
  • Implicit Intents Example (1)
  • Layout View (3)
  • lifemichael (8)
  • Location Sensor (1)
  • Multiple Activities (2)
  • Netbeans (1)
  • OpenGL ES Graphics (1)
  • Passing Values with Intents (2)
  • Project Structure (1)
  • Retrieving Image URI from Intents (1)
  • Setting Android Environment (1)
  • SQLite (3)
  • TGENT (8)
  • UserGroupAtGoogle (8)
  • XML (1)
  • xtensive arts Training (11)
 
 
© 2011 Android Development Tutorial | Designs by Web2feel & Fab Themes

Bloggerized by DheTemplate.com - Main Blogger