Home > Android, hacks > Using internal (com.android.internal) and hidden (@hide) APIs [Part 2, customizing android.jar]

Using internal (com.android.internal) and hidden (@hide) APIs [Part 2, customizing android.jar]

(Parts 1, 2, 3, 4, 5)

[note: if you don’t have time to follow this post, you can go here and download the final results]

In previous post I explained why there is no easy way to use com.android.internal package (internal API) or anything marked with @hide attribute (hidden API) without using reflection. That’s because android.jar file does not contain classes from internal and hidden API and because of this nobody can reference those classes in compile time.

This part describes how to restore original android.jar. This will allow usage of internal and hidden APIs as if they were public APIs.

How to get original (uncut) version of android.jar?

We need to modify android.jar so it contains all original *.class files (including Internal and Hidden API classes). There are two ways:

1) Android is an open source project. We can download the source code and customize build system so it does not exclude internal & hidden classes from android.jar. This is a hard way.

2) Each emulator or real device must have some equivalent of android.jar that is used in runtime. We can get this jar from device, extract original .class files and copy them into android.jar from Android SDK.

I’ll stick with second approach. It’s easier to start with and does not require setting up Linux machine (if you are working on Windows), building all source code tree, customizing build system and so on.

Getting framework.jar from device

You can download files from device or emulator using command line ( adb pull ) or using DDMS (from eclipse or as standalone application from android sdk).

(Note: Emulator always contains code in .dex files, while real devices usually contain their code in optimized version of dex – odex files. Working with odex files is harder, and that’s why I prefer emulator in this post.)

The runtime equivalent of Android SDK’s android.jar file is framework.jar. This file is located at /system/framework/framework.jar on a device.

adb pull /system/framework/framework.jar

When framework.jar is downloaded from device, rename it to framework.zip and unzip it to separate folder. You should get something like this:

image

File classes.dex is what we need.

Creating framework-classes.zip

First we need to convert .dex file to .jar file format. This can be done using a small utility called dex2jar. You just need to run:

dev2jar classes.dex

When conversion is done you should have classes.dex.dex2jar.jar file. Just rename it to framework-classes.zip. Using zip file viewer, go to framework-classes.zip/com/android/internal:

image

Voilà. We’ve got all the .class files for internal and hidden API (though screenshot only confirms the internal part).

Creating original-android.jar

Android SDK’s android.jar is located at ANDROID_SDK/platforms/android-X/android.jar (where X is API Level of your interest, in my case X == 9).

Copy android.jar as custom-android.zip. Unzip to folder custom-android. Copy all .class files from framework-classes.zip to custom-android folder (you’ll need to replace all already existing .class files).

Then zip custom-android folder back as original-android.zip. Rename to original-android.jar.

Summary of steps

  1. Choose your target android platform X (I used API Level 9 platform, X == 9)
  2. Create emulator that targets platform X
  3. Start emulator, download /system/framework/framework.jar file from it.
  4. Rename framework.jar –> framework.zip
  5. Extract classes.dex from framework.zip
  6. Using dex2jar convert classed.dex to classes.jar
  7. Rename classes.jar as framework-classes.zip
  8. Copy android.jar from ANDROID_SDK/platforms/android-X/ as custom-android.zip
  9. Extract custom-android.zip to custom-android folder.
  10. Copy everything from framework-classes.zip into custom-android folder (replacing all existing files).
  11. Zip custom-android folder as original-android.zip
  12. Rename original-android.zip as original-android.jar

Done.

Conclusions

We restored original android.jar so it contains .class files from internal and hidden APIs. This is only first step. Next step is to create custom android platform that uses this uncut version of android.jar and add it to Android SDK plarforms directory.

( Next post )

Categories: Android, hacks
  1. July 18, 2011 at 10:46

    interesting :-)
    i thought u are gonna recompile the jar with the classes inside or removed the @hide by using grep and sed script.
    i know trying to change the android build (make file maze) is not easy, i never managed to create android.jar including the original source file in it so i can have out of the box source included jar. if you ever succeed in doing that, please let me know :-)

  2. August 10, 2011 at 14:39

    hmm,this post helps me very much,thanks~

  3. karim duran
    August 23, 2011 at 11:43

    Interesting. I had an intuition about that technique because, using my daughter SAMSUNG galaxy spica i5700 ( API level 3 android 1.5 ), i could exchange file with bluetooth, but the bluetooth API is available only since android 2.x. So, i asked myself how it was possible under 1.5. Investigating the system kernel framework, i saw real bluetooth support in system *.jar on the device.
    It’s a good plan. But i think it’s really risked to publish applications that use hidden or internal API. Even if it works fine, the users could complain saying that you used a “hacker” strategy.
    I ask myself what is the Google opinion about a such strategy ?
    Regards.
    Karim Duran.

    • August 23, 2011 at 11:56

      In my first post I’ve mentioned this problem. Basically – all bets are off, if developers decides to use internal/hidden APIs he or she must accept all the risks. As for Google, I don’t think they are happy with this approach. And personally I consider using internal/hidden APIs as a last resort.

  4. August 25, 2011 at 20:06

    Hello, im pulled the framework.jar but hasn’t the classes.dex inside. i have samsung i9003 with android 2.2.1.

    Regards

    • Nai
      April 12, 2012 at 03:52

      same here..any solutions?

  5. dorruk
    December 7, 2011 at 22:34

    all good until step 7.. When I convert that jar to zip, the file appears to be corrupt so when I open it, nothing comes up. Maybe something wrong with dex2jar?

  6. freddy
    December 30, 2011 at 00:39

    I also don’t have classes.dex inside of framework.jar. I pulled framework.jar from HTC EVO as well as Samsung Galaxy S and neither framework.jar contained a classes.dex :-( My thought is that it is possible to re-create classes.dex via framework.odex but, I’m not sure nor do I know how to go about this. If it isn’t possible, then, not sure how to obtain classes.dex :-/

  7. jignesh
    January 13, 2012 at 07:16

    how can i get android.provider.Im

  8. Deepak Goel
    January 20, 2012 at 05:28

    The below solution is for whom they are not getting classes.dex from framework.jar
    1.Just download framework.odex
    2.download baksmali.jar and run the below command
    java -jar baksmali framework.odex
    3.You will get some error and cmd will give you suggestion to download some more odex file like core.odex
    4.Just download it from the same location i.e. where framework.odex exist.
    5.put it in the same directory and run the command
    6.you will get bunch of files in out folder
    7.just download the smali.jar from the net
    8.run the below command
    java -jar smali out
    9.finally you will get out.dex at the same location
    10.use dex2jar and you can continue as illustrated in the tutorial

    • Muhammad Ghandour
      January 30, 2012 at 20:25

      when runnin the command java -jar baksmali.jar framework.odex it came up with the followin error:

      Unexpected Top-Level Exception
      org.jf.dexlib.Util.ExceptionWithContext: regCount does not match the number of arguments of the method at org.jf.dexlib.Util.ExceptionWithContext …

      anyidea how to fix that up ?

      Am i using a newer version of the baksmali than the one you used to Deodex the framework ?!

    • Miquel
      February 17, 2012 at 22:33

      Same problem… Any idea?

    • koliak
      April 13, 2012 at 14:33

      Hello, I do not get either classes.dex from framework.jar and when I follow your 10 steps then:

      When I do step 8) java -jar smali out
      I get in all the files:
      invoke-virtual-quick is an odexed instruction. You cannout reassemble a disassembled odex file unless it has been deodexed

      Also I got error in the step 2) java -jar baksmali framework.odex
      but I solved doing: java -jar baksmali-1.3.2.jar -a 10 framework.odex

      Any help about the issue?

      • Ahmed Memon
        February 8, 2014 at 13:29

        i have same problem…!please help me

    • John
      April 23, 2015 at 14:19

      Where is this framework.odex? How can I download that?

  9. September 14, 2012 at 15:54

    Great Tutorial
    I followed all parts of this tutorial
    edited all files perfectly but eclipse is not resolving the classes although they are now present in the updated jar file
    some have been resolved but some are showing errors.
    tried to clean and debug project but issue is still there.
    Plz help

  10. September 15, 2012 at 12:13

    I’ve taken the framework.jar (classes.dex) from my GalaxyNexus JB and when I see the content of com\internal after using dex2jar, there’s only the directory com\internal\os (tried also with emulator).

  11. viral shah
    September 19, 2012 at 08:31

    dex2jar 0.0.9.9 throwing exceptions and as pcrevenge states…left with only one directory….

  12. Dave
    September 20, 2012 at 18:00

    After creating framework-classes.zip, I don’t find android.jar in the zip file.

  13. November 16, 2012 at 15:31

    in case anyone has a problem finding framework.jar, just download a AOSP ROM with the API version you’re targetting and extract from there, waaaaaaaaaaay simpler ;)

  14. Avinash
    January 16, 2013 at 10:45

    Small Doubt, in 4.2 after i pulled the framework and unzipped i do not see any dex file(no class.dex present). How to proceed now?

  15. Paul
    January 23, 2013 at 19:11

    I followed all parts of this tutorial succesfully. I have following remarks about this part:

    1) On december 4th, 2012 a new version of dex2jar was released. When using this version you will get a message about a deprecated command. Use d2j-dex2jar instead of dex2jar.

    2) Step 10 instructs to copy everything from framework-classes.zip into custom-android folder (replacing all existing files). When switching my project to this android version this results in following error: “[2013-01-23 18:08:10 – Framework Resource Parser] Collect preferences failed, class org/apache/harmony/dalvik/ddmc/ChunkHandler not found in …”
    When only copying classes from framework-classes.zip/com/android/internal/* this error is not thrown.

  16. JB
    January 24, 2013 at 07:52

    I get the following error when running dex2jar on the classes.dex in the latest version of android (API level 17)

    dex2jar classes.dex -> classes_dex2jar.jar
    Error:Landroid/net/VpnService;.protect(I)Z->null

    Does anyone else get this error, and managed to get passed it?

    I’m using the dex2jar version 0.0.9.12.

    Cheers,
    John

  17. abhas
    April 4, 2013 at 16:30

    I extracted the framework with the command without a device , from emulator , but there is no classes.dex in it . any idea why so ?

  18. April 14, 2013 at 17:44

    An easy way of keeping just the .class files _and_ keeping the structure is to use rsync:

    rsync -rav –include=*/ –include=”*.class” –exclude=* framework-classes/ framework-classes-filtered

  19. April 14, 2013 at 22:56

    To make life easier for everyone I have boiled everything here down to a simple shell script that should make life easier for everyone. It also eliminates errors as it does everything in a few simple steps:

    #!/bin/sh
    # Pull framework from device/emulator.
    adb pull /system/framework/framework.jar
    unzip framework.jar
    # Undex classes file – check path name to dex2jar!
    ~/Downloads/dex2jar-0.0.9.13/dex2jar.sh classes.dex
    unzip classes_dex2jar.jar -d framework-classes
    unzip ~/android-sdk-mac_x86/platforms/android-10/android.jar -d custom-android
    # Copy .class files from extracted framework into our new custom android firectory.
    rsync -rav –include=*/ –include=”*.class” –exclude=* framework-classes/ custom-android
    pushd custom-android
    # Wrap everything up in a new jar file.
    zip -r ../original-android.jar .
    # Return to where we started.
    popd

  20. June 21, 2013 at 16:04

    hi thank you for your help. working charm..Issue is, in some devices working very fast,but in some devices, app taking to respond. In samsung s2 working fine in s3 loading veru slowly. Please help me.

  21. June 21, 2013 at 16:14

    ranga :
    hi thank you for your help. working charm..Issue is, in some devices working very fast,but in some devices, app taking time to respond(onclick listeners). In samsung s2 working fine in s3 loading very slowly. Please help me.

    • July 6, 2013 at 09:32

      I refined the script to make it easier to work with. It will cleanup when done and leave you with just the .jar file you want. Note the 3 definitions at top – please set these correctly before running the script.
      Note that you should always pull the android.jar from the emulator – not a real device as vendors might have modified it ever so slightly.

      #!/bin/sh

      DEX2JAR=~/Downloads/dex2jar-0.0.9.13/dex2jar.sh
      SDKDIR=~/android-sdk-mac_x86
      PLATFORM=4.2

      # Pull framework from device/emulator.
      adb pull /system/framework/framework.jar
      unzip framework.jar
      # Undex classes file – check path name to dex2jar!
      ${DEX2JAR} classes.dex
      unzip classes_dex2jar.jar -d framework-classes
      unzip ${SDKDIR}/platforms/android-${PLATFORM}/android.jar -d custom-android
      # Copy .class files from extracted framework into our new custom android firectory.
      rsync -rav –include=*/ –include=”*.class” –exclude=* framework-classes/ custom-android
      pushd custom-android
      # Wrap everything up in a new jar file.
      zip -r ../extended-android.jar .
      # Return to where we started.
      popd
      # Cleanup
      rm -Rf META-INF
      rm classes.dex
      rm classes_dex2jar.jar
      rm framework.jar
      rm preloaded-classes
      rm -Rf custom-android
      rm -Rf framework-classes

      echo Now make a copy of the target platform and replace android.jar with this new extended-android.jar.
      echo Open build.prop and change ro.build.version.sdk to a negative value. If it was 8 then change it to -8.
      echo Open source.properties and change Platform.Version – just append .extended to MacBMacBoMacBoMacBook-Air-MaMacMMMacBooMaMacBMM

  22. November 19, 2013 at 20:49

    Hello,
    I cannot find classes.dex inside framework.jar. i only see preloaded-classes… how to solve this problem?

  23. December 31, 2013 at 06:38

    Hi, I managed to download the framework.jar file, but when I extract it, there are only preloaded-classes and META-INF. What did I miss ? Thanks

  24. myCodeHurts
    January 30, 2014 at 21:10

    Hi – Things have changed a bit. framework.odex is a separate file in device as well as computer. Not able to convert smali files of framework.odex to classes.dex? Smali throws errors. Does any one know how to get through.

  25. Ahmed Memon
    February 8, 2014 at 13:33

    not able to convert com to out to out.dex..!please help

  26. gus
    February 14, 2014 at 06:05

    hey, this is a very useful information to understand more the hidden apis.
    i am trying to use the apis android.net.vpn following this link:
    http://stackoverflow.com/questions/16987663/android-2-2-2-3-vpn-api-connection-no-vpnservice, in a samsung small tablet with android API 10 (gingerbread).
    so i need to make the changes as you showed.
    i am confused about getting the .jar file from the device using “adb pull” command.
    can you provide details about that step?
    also, once I have made all the required changes, how can i “upload” it into the device again?
    thanks in advance for any help you can give me.

  27. July 5, 2014 at 09:15

    There is no “framework-classes.zip/com/android/internal” folder. The path to android I get does not have com and there is no internal folder inside it. Any idea why? I pulled it from my emulator.

  28. Ryan
    July 9, 2014 at 20:50

    I am wondering if this is still a valid method for obtaining the internal api, I’ve successfully pulled the framework jar from the emulator, unziped the classes.dex, used dex2jar to convert it into a jar file but when I look through the created jar there is no internal folder? Is there an updated way for doing this? I am currently using the 21/03/2014 release of the Android SDK.

  29. abm
    September 3, 2014 at 18:11

    Thanks for the info! In my case I tried to modify the API 19 using a Genymotion emulator image, but the process was slightly different. The /system/framework directory had two framework files (framework.jar and framework2.jar) so I had to run dex2jar on both and copy both files’ .classes to the custom android image. Then it worked correctly.

  30. Julius
    September 17, 2014 at 16:28

    For everyone, who is having the error

    Framework Resource Parser] Collect permissions failed, class android.Manifest$permission not found

    or

    Framework Resource Parser] Collect preferences failed, class android.Manifest$permission not found

    1. Instead of just unzipping the original android.jar which is going to be modified by adding the new .class files there use

    jar -xf android.jar

    2. Add your .class files

    3. Use the jar tool to create an android.jar again

    jar cf android.jar .

    That solved the issue for me.

  31. omar
    May 24, 2015 at 18:17

    After doing these steps, will my app need root access to work (I’m using it on the AOSP dialer)?

  32. Pavan Kumar
    August 31, 2015 at 09:04

    framework.jar is not available in this path.what is the next step to solve this problem.
    Users\Pavan\.AndroidStudio1.2\system\frameworks

  1. January 18, 2011 at 22:34
  2. January 18, 2011 at 22:57
  3. June 10, 2011 at 11:48
  4. September 5, 2015 at 22:48
  5. September 5, 2015 at 22:49
  6. September 5, 2015 at 22:49

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s