Apk with system privileges

19 de October de 2011 41 comments

Hello everyone!

Many people ask me how to sign an APK with the system certificate. With system privileges you can install APKs in background as I showed in the previous post. It isn’t simple and it is not a common case, but if it is really your need, here follows a little tip for you.

First of all, you do not need to do any of that if: the Android that is running on your device used default certificates that comes in the Android source code. It happens if the engineer don’t create its own certificate to sign the system – which is the case of the Android emulator or, if you are using some ROM that uses the default one (yes, some ROMs have a huge vulnerability!).

To achieve that first you have to obtain the certificates that were used to sign the Android OS installed on the device – a pair of certificates (.pk8 + x509.pem) – to generate a java certificate.

The certificates pair (platform.pk8 + platform.x509.pem) can be found under {Android Source}/build/target/product/security.

With those certificate on hand, you should create a java keystore file (.keystore) merging these two certificates (.pk8 + x509.pem) into one.

To be able to do that, you can use the keytool-importkeypair with the command:

./keytool-importkeypair -k google_certificate.keystore -p android -pk8 platform.pk8 -cert platform.x509.pem -alias platform

You can download keytool-importkeypair here or direct download zip file here

usage: keytool-importkeypair [-k keystore] [-p storepass] -pk8 pk8 -cert cert -alias key_alias

After running this command it will generate a file in your current folder named “google_certificate.keystore”. Note: the alias is “platform” and the password is “android”.

To get that super power it just about to sign your apk with the generated “google_certificate.keystore” certificate.

Just remember, “with great power comes great responsibility”. Enjoy!😉

Categories: Android Tags: , , ,

How to install an application in background on Android

2 de July de 2011 72 comments

You need to attention to four things before use these codes:

1 – This technique is only useful and just will work for you if you will make an application for a specific device you have its certificate, just like me.
2 – Doing this technique you will access classes that the Google doesn’t guarantee its portability to future versions;
3 – I used and tested it in version 2.2;
4 – You need remember put the permission in your AndroidManifest.xml.

<uses-permission android:name="android.permission.INSTALL_PACKAGES"/>

A video was added on Youtube to quickly show the feature:

I also recommend you read the previous post.

So, let’s go. Today I’ll pass for you guys something that I think is very interesting. I’ll talk about how you can install APKs in background (without user interaction). It’s a good tip because this issue isn’t easily found on the web. Beyond that, you can learn more about how the Android frameworks works.

I needed to find a solution for this because I had to develop an application that it needed to be updated remotely and it couldn’t be exposed in the Android Market. It was a private commercial application. The customer did not want to the user had the option to cancel the installation (which happens if you sends the user to the default screen installation). The update was an obligation.

So let’s begin where I began. First of all, I wondered how the Android System does to uninstall applications. You can see it in [Settings -> Applications -> Manage applications -> “choose any app” -> “click in Uninstall”]. So I searched for the source code this activity. There is a text “Uninstall application?”, then I searched for this string in the source code of Android:

find . -name *.xml | xargs grep Uninstall application

./packages/apps/PackageInstaller/res/values/strings.xml:
<string name="uninstall_application_question">Uninstall application?</string>

I found the string with the name “uninstall_application_question”. So I searched for the activity that use it:

find . -name *.java | xargs grep uninstall_application_question

./packages/apps/PackageInstaller/src/com/android/
packageinstaller/UninstallerActivity.java:
question.setText(R.string.uninstall_application_question);

I found UninstallerActivity.java. In UninstallerActivity class there is a button “mOk” that sends you to UninstallAppProgress.java. In this class we see PackageDeleteObserver that removes the application. It extends android.content.pm.IPackageDeleteObserver. Let’s search for this class:

find . -name IPackageDeleteObserver.java

./out/target/common/obj/JAVA_LIBRARIES/framework_intermediates/
src/core/java/android/content/pm/IPackageDeleteObserver.java

In this package we also have IPackageInstallObserver.java. In this class we see:

/**
 * API for installation callbacks from the Package Manager.
 * @hide
 */

It’s what we want, but I tried to import this class and I saw that it doesn’t exist in android.jar. Apparently the Android system have access to it and we don’t. But, did you remember that in my previous post I said that the Google remove the access of some framework’s class? It puts “@hide” in comments on the methods and classes of the source code of the framework that it doesn’t want to expose to the developer.

Now the big tip: you can access these classes through reflection, because they have loaded into the system. I don’t know if this is a bug, but… this solves our issue!

But, why have theses classes been loaded into the system? As I said in previous post, the android.jar has everything you need to develop your application using Java, but the classes are in the jar just for you compile your aplication properly, ensuring that it will run on future versions of Android. The applications are compiled without them, the framework’s classes aren’t built into your apk. The codes inside the jar are stubbed out. This is because the code inside the jar is never runs, so there’s no reason to make your application bigger because of this. Beyond that, all applications on device share the same framework, so these classes are already running on the device actually. That means: you can load any framework’s class through reflection.

So finally let’s to do the code to install the application directly by API without interface. First, download my code, let’s see it:

final ApplicationManager am = new ApplicationManager(InstallInBackgroundSample.this);
am.setOnInstalledPackaged(new OnInstalledPackaged() {

	public void packageInstalled(String packageName, int returnCode) {
		if (returnCode == ApplicationManager.INSTALL_SUCCEEDED) {
			Log.d(TAG, "Install succeeded");
		} else {
			Log.d(TAG, "Install failed: " + returnCode);
		}
	}
});

...

Button btnInstall = (Button) findViewById(R.id.btnInstall);
btnInstall.setOnClickListener(new OnClickListener() {

	@Override
	public void onClick(View arg0) {
		
		try {
			am.installPackage(txtApkFilePath.getText().toString());
		} catch (Exception e) {
			logError(e);
		}
	}
});

Let’s see the ApplicationManager.java class that I created:

public void installPackage(Uri apkFile) throws IllegalArgumentException, IllegalAccessException, InvocationTargetException {
	method.invoke(pm, new Object[] {apkFile, observer, INSTALL_REPLACE_EXISTING, null});
}

As you can see, I invoked the method by reflection. To obtain the method I did:

public ApplicationManager(Context context) throws SecurityException, NoSuchMethodException {
	
    observer = new PackageInstallObserver();
    pm = context.getPackageManager();
    
    Class<?>[] types = new Class[] {Uri.class, IPackageInstallObserver.class, int.class, String.class};
	method = pm.getClass().getMethod("installPackage", types);
}

To determine whether the application is installed successfully, we need to create a class to implement the callback “packageInstalled”. We must pass an observer in the parameter of the method “installPackage”. Thus we need to extend IPackageInstallObserver.Stub to obtain the return as did UninstallAppProgress activity:

class PackageInstallObserver extends IPackageInstallObserver.Stub {

	public void packageInstalled(String packageName, int returnCode) throws RemoteException {
		if (onInstalledPackaged != null) {
			onInstalledPackaged.packageInstalled(packageName, returnCode);
		}
	}
}

But we don’t have access to IPackageInstallObserver class (it is @hide in SDK) and how could we get the class by reflection and create a subclass of this? How would we do? Well, I did not know to do this, then I discovered an other way to do it.

I know that IPackageInstallObserver class has already loaded in the VM, so I decided to create a copy of the class in my project with the same package structure and the method signatures, but stubbed out, exactly as does android.jar! The VM loads the framework’s class first so I used my class just to compile. When is running, the VM uses the framework’s class and not the mine.

So that’s it, folks. I hope this has helped you. Download the code, run it and read it, everything will seem easier. Please, leave comments.

The complete code the project is exposed in the Github: here or direct download zip file here

ads: Tiny Tray – Servidores cloud Linux com acesso SSH com root a partir de R$49,95/mês

Android Application Framework

14 de April de 2011 8 comments

Android applications runs in the Dalvik virtual machine. This isn’t the Oracle’s Java Virtual Machine. This is the Google’s virtual machine optimized for mobile devices.

The Android SDK provides the tools and APIs necessary for developing applications on the Android platform using the Java programming language. In a standard project Java (from Oracle) is necessary to include the JDK (Java Development Kit) adding some jar in our project as rt.jar, resources.jar, among others, while in an Android project must include the Android SDK, only the android.jar, in our project.

Although this may sound strange at first, almost all the core classes of Oracle SDK are present in the Android SDK (totally rewritten in spite of it must have the same behavior). For example, the class String.java from Oracle’s Java is inside the rt.jar in the package java.lang, while the String.java from Google’s Java is inside android.jar in the same package structure, java.lang.

Beyond the core we find in Android SDK some classes that gives developers the ability to take advantage of the device hardware, such as access location information, background services, alarms, notifications, among others. The android.jar is a compilation of all the APIs you can use to develop your applications using Java.

An interesting note on Android SDK is that the code in android.jar is stubbed out. This because the code inside the jar is never runs, so there’s no reason to make the SDK bigger because of this. To better undersand, if you look at these classes using a decompiler (with jad for example) you will only see: public void something(…){ throw new RuntimeException(“Stub!”); }. This means that you use android.jar only for the purpose of compiling the code, use autocomplete and imports in Eclipse.

Moreover, android.jar contains only the APIs exposed for the level of applications development. It’s a promise from Google that if you compile your application using this jar, you are guaranteed your application will run in future versions of Android. There is a part of the compilation process in the Android system that removes methods and classes of API. It’s used internally by the framework and should not be used for an Android developer. Why does Google do it? Well, I believe it’s because Google needs to write too much code to get API exposed. A lot of code starting in the hardware until to get a high-level API, which can be changed from one version to another, even codes that may no longer exist in future versions.

But, how the Android is an open source project, we can download the code at: http://source.android.com/source/download.html

So, you can find, for example, the source of Activity.java into {base-code}/frameworks/base/core/java/android/app/. After compiling the source code, you can see a folder called “out” is created. For example, there is the Android system image in out/target/product/generic (files system.img, userdata.img and ramdisk.img). But what interests us, the library of the SDK, is in {base-code}/prebuilt/sdk/. You can see that was built a stub Activity class in out/target/common/obj/JAVA_LIBRARIES/android_stubs_current_intermediates/src/android/app/Activity.java.

To be continued…

ads: Tiny Tray – Servidores cloud Linux com acesso SSH com root a partir de R$49,95/mês

Categories: Android Tags: , , ,

Customize your Android application!

19 de March de 2011 2 comments

My first difficulty and disappointment (at first!) in Android development was the look original the Android API. Only two themes are provided: one white theme and other black, where the buttons and others components are gray… -_____-

But, for our happiness, the Android is totally customizable. See the video below an example what you can do to make your application look better. So, change the title bar, put a color, insert images, customize the buttons.

Do not use black screens! Be creative! =)

Tip: If you want to use this project, read these articles before:

The complete code the project is exposed in the Github: here or direct download zip file here








A video was added on Youtube to quickly show the feature:

ads: Tiny Tray – Servidores cloud Linux com acesso SSH com root a partir de R$49,95/mês

How to implement a paging feature in Android

19 de March de 2011 5 comments

One day I needed to create a paging feature in Android. Something to create a swipe action in Android, like the home screen. After searching in Google, I discovered that was possible to make this effects using a HorizontalScrollView. It’s a good idea. So, I adapted some codes according my necessity. I created a class (PaginationLayout). You just need to add elements into this layout and it will do all work.

Basically the PaginationLayout class creates two views: a bar with “Previous” and “Next” buttons and a horizontal scroll, one below the other. The paging effect is built using the scroll. Gestures are calculated to move and stop just to pass an exact page (visible screen size). It also applies to the click event of the buttons.

The complete code the project is exposed in the Github: here or direct download zip file here

A video was added on Youtube to quickly show the feature:

Usage example:

public class Sample extends Activity {

	@Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        
        // creates the Pagination Layout
        PaginationLayout paginationLayout = new PaginationLayout(this);
        paginationLayout.setLayoutParams(new LayoutParams(
			  LayoutParams.FILL_PARENT, LayoutParams.FILL_PARENT));
        
        // creates content only for sample
        TableLayout table = new TableLayout(this);
        TableRow row = new TableRow(this);
        TableRow row2 = new TableRow(this);
        table.addView(row);
        
        .... and blablabla ...

        for(int i = 0; i< 50;i++){
            Button button = new Button(this);
            button.setText("Button " + i);
            if (i%2==0) {
            	row.addView(button);
            } else {
            	row2.addView(button);
            }
        }
        
        // add the content in pagination
        paginationLayout.addView(table);
        // set pagination layout
        setContentView(paginationLayout);
    }
}
}

ads: Tiny Tray – Servidores cloud Linux com acesso SSH com root a partir de R$49,95/mês

Follow

Get every new post delivered to your Inbox.