I am trying to modify an APK which came with my official firmware.
Actually only some resources should be modified (sounds should be replaced with silent files).
I moved APK and ODEX to backup folder, unzipped APK on a PC, modified files, zipped APK with 7Zip again and placed it into /system/app folder with corresponding permissions. After a reboot Camera application disappeared from everywhere.
Ok, I copied ODEX file back to /system/app, rebooted, and application appeared, but trying to run it makes it crash.
APK file has no DEX inside.
I thought that ODEX file contains code only and shouldn't be re-created.
What I was doing wrong and how to do it right?
You can't modify apk's without signing them again. The Android system will notice that the apk has been tampered with and refuse to load it. You could sign it with your own key, but then your signature wont match the official signature for that package name and that will prevent you from getting any updates for that application as long as your modified apk is installed. Also if that application is relying on being signed with the same certificates as other applications from the same manufacturer it wont work correctly.
You can read about signing android applications in the official documentation
Why do you want to do this?
Related
I'm trying to modify the Androidmanifest.xml for the browser on my device so that I can execute an app by loading a URI in the browser.
I've been running around the file system in ADB SHELL all day, but can't seem to find it. Plus there is no FIND, nor LOCATE command on the system.
You can theoretically find the Androidmanifest.xml file in the APK.
Every APK contains the compiled source code of the application. There is no useable decompiler for APKs at the moment so it is not possible to change the content of one.
In addition to the compiled code and the other resources of the application, an APK also contains a signature from the developer, which will become invalid when the content is changed to verify the source of an APK. An Android system won't install an APK with an invalid signature, so even if you could change the content of the APK, you still couldn't use it.
The conclusion: You cannot do what you are trying to do.
Android Studio on Windows 10/11, it’s in: app/src/main.
Are these two ways equal and correct?
Method 1:
Odex the APK to a .apk and a .odex
Sign the .apk file produced in step 1
Method 2:
Sign the APK
Odex the APK to a .apk and a .odex
First you need to understand working of .apk and .odex file.
.Odex file:
Odex file is the extracted and optimized DEX file (classes.dex) from APK or JAR files.
An ODEX file has dependencies on every file in the BOOTCLASSPATH that is loaded when it is generated.
The odex file is only valid when used with these exact BOOTCLASSPATH files.
Android Application come in packages with the extension .apk. These application packages, or APKs contain certain .odex files whose supposed function is to save space.
These ‘odex’ files are actually collections of parts of an application that are optimized before booting.
It also makes hacking those applications difficult because a part of the coding has already been extracted to another location before execution.
How it work:-
Android OS uses a Java-based virtual machine for running applications, called the Dalvik Virtual Machine. A deodexed, or .dex file contains the cache used by this virtual machine (referred to as Dalvik-cache) for a program, and it is stored inside the APK. An .odex file, on the other hand, is an optimized version of this same .dex file that is stored next to the APK as opposed to inside it.
Android applies this technique by default to all the system applications.
Now, when an Android-based system is booting, the davlik cache for the Davlik VM is built using these .odex files, allowing the OS to learn in advance what applications will be loaded, and thus speeds up the booting process.
By deodexing these APKs, a developer actually puts the .odex files back inside their respective APK packages. Since all code is now contained within the APK itself, it becomes possible to modify any application package without conflicting with the operating system’s execution environment.
You can find some information Here and
Here is one StackOverFlow question may helpful to you.
I'm creating a software that will guide the user through a few steps, to publish an android application (APK file).
The way I am doing this, is that the APK file is already compiled, and all I need to do is replace an XML file in the package, and that will change the behaviour of the application. My big problem now, is that unpacking the apk file, and doing any tiny text edit, and then packing it again, breaks the signature and prevents the application from running on any device, giving a message that the signature is incorrect.
How can I solve this? I want to safely open the APK, write something in a text file, and close it again. Note that this operation will be done on the user's computer (after he purchases our application) so we're look for a command-line tool with no special requirements like JDK.
Any help?
Ok I reached the best "tested" solution - I'm posting it here to save other developers hours of googling. The only downside is that I will require the customer to install JDK on his machine, unfortunately. The reason is because I did not find any apk-signing tool that works purely on windows, without relying on JDK.
I have my android application created using Air, so this makes things easy for me - all of the air files are treated as resource assets. So have your APK archive file ready.
Once you have your modifications ready, put them inside a temporary folder named "assets". You will use the 7-zip command line tool (free: http://sourceforge.net/projects/sevenzip/) to update the contents of your apk. To have it working with your apk you will have to rename your apk's extension to zip - don't worry, you'll change it back later.
Now from a .bat file (or directly in the command prompt) from the location containing both your apk file (zip extensioned) and your assets folder, you'll call: 7za u APK-file.zip assets
Now your apk file is updated. Rename it back to .apk extension
Now you'll use the signAPK tool from here https://code.google.com/p/signapk/ and note that this is the only step requiring JDK installed. It also assumes that you have your key files ready (replace the dummy ones included in the package). Extract the file contents and call: java -jar signapk.jar key.x509.pem key.pk8 [android_app].apk [signed_android_app].apk
At the very end, you may find your signed apk file size drammatically increased. So you need to use the android's zipAlign tool: (darn, can't post the link since new users can only post a maximum of two hyperlinks)
you will be calling the command: zipAlign -c 4 [signed_android_app].apk
And voila! That's the route I'm taking.
If someone finds a way to do the signing process without relying on JDK (assuming the key files are ready) please share.
How can I solve this?
You don't. If you modify an APK file, by any means, it must be re-signed.
Android apk files must be signed. That signature proves that the contents of the apk have NOT BEEN MODIFIED from what was initially published. (Which is exactly what you are doing.) The signature at the same time, also proves who the author is.
So in a normal signed apk file:
You know who the author is. (Even if it's not something you as a human can understand.)
You know the contents were put there by the author, and not modified since.
This is a key security measure built into Android, is there for very good reason, and cannot be overcome. It prevents things like viruses from being embedded inside innocent apk files.
This is a very interesting thing. I have an APK file, com.company.app.apk. When installed to an emulator by using Eclipse, by using the following code to get the apk's file name:
String fileName = activity.getPackageManager().getApplicationInfo(
activity.getPackageName(), PackageManager.GET_META_DATA).publicSourceDir;
I get a pathname like this com.company.app-1.apk. The file size is the same as the apk file I built.
Now when I publish this app to Market, and install it to a real device (Android 2.3), the same code returned a pathname like this: com.company.app-2.zip. Note that the file extension has changed to .zip and, most importantly, the file size is significantly smaller than the original size.
Now if I transfer these two files to my PC and use WinZip to open them, I found one really interesting thing:
The one installed on emulator by Eclipse has exactly the same stuff as I expected. Namely: the code ('com' folder), the resource ('res' folder), the signature ('META-INF' folder), the assets ('assets' folder), and the manifest file (AndroidManifest.xml). However, the one installed on a real device by Market has only two parts: the resource, and the manifest file.
Question: I think when installed from Market, the .apk file is split into two (or more) files. One file is pointed to by ApplicationInfo.publicSourceDir, which contains only the resource. How can I get the pathname to the other file(s)?
ADDED: I have two versions of the same app, one is paid using Google's Vendor Licensing Service, the other is free. The above mentioned phenomenon happens only to the paid version. Why?
Correction: When I said the 'com' folder exists in the installed apk file in the first case, I should be more clear. The code per se, the *.java files, are not in the 'com' folder. As a matter of fact, the 'com' folder contains only a few garbage files that were inadvertently left there during the build process. If not for those garbage files, I don't think the 'com' folder would be there in the first place.
I think you are not right. The market works in the following way: you choose an application and push a button to install it. After that market sends the intent to gtalk service to install the application. This service downloads apk file that you've uploaded to the market and when finishes it installs this apk. Just during the installation can some changes happen. It seems to me that from the application during the installation classes.dex file is extracted and from this file optimized dex (.odex) is produced and put in the separate directory. That's why you see the difference in the files.
Ok, here is what I've found out, in case this helps someone out there:
When Market installs the free version of my app, the apk file is installed to /data/app/com.company.app.apk, the file content is exactly the same as I built it, same file size, same everything.
For the paid version that uses Market Vendor Licensing, the apk file itself is installed to /data/app-private/com.company.app.apk. This is the same file as I released. However, the resources are extracted and installed to another file /data/app/com.company.app.zip, note the file extension. This zip file contains only resources, so it's significantly smaller. But the .apk file in /data/app-private has everything, so the file size is the same as I built it.
ApplicationInfo.publicSourceDir always points to the file in /data/app, so it's /data/app/com.company.app.zip in the paid version's case, and /data/app/com.company.app.apk for the free version. For the paid version, I obtained the pathname from publicSourceDir, then replace.app with app-private, and replace .zip with .apk to get the original file.
If I install the apk directly to an emulator, then there is only one file and is always installed under /data/app.
I am working on an automatic app updating solution for devices (LG p509 - Optimus 1) which we deploy to our customers. We have control of these devices and currently install a custom kernel on them (but not a full custom ROM). Since we are trying to do auto-updating of our app on the device, we need the system to be signed by a key which we control so we can sign our apps with the same key (to get the INSTALL_PACKAGES permission).
I have been having a few issues running AOSP builds on the device (using the LG released source for the device), and am trying to take a step back and evaluate our options. I have a few questions:
Is it viable to just pull the system.img off the phone and resign the contents? If so, where is the system apk located? I poked through the PackageManager source and it uses a systempackage (seemingly called "android") to compare apps with to see if they are allowed to have system permissions.
Has anyone here created a custom ROM for the device that could offer some advice on how just get our signature be the system signature?
Any insight would be appreciated.
Ok, so we figured it out. I am not going to go into full detail (too much writing), but here is the basic gist for anyone who stumbles on this:
If you want change the key which the system is signed with, you need to do the following steps:
Extract /system/ dir from the running phone
Inspect the .apk files (from /system/app and /system/framework) to figure out which ones are signed by the same key as the framework-res.apk. I used a modified version of the script linked here to figure out which APKs to sign.
If the APKs in /system/app which share the signing key with framework-res.apk are odexed, you need to de-odex them.
resign the APKs and the framework-res.apk and pack them in an update.zip (google how to do that).
On my specific device I had to resign both /system/framework/framework-res.apk and /system/framework/lge-res.apk from /system/framework and also had to de-odex and sign 20 .apks from the /system/app folder in order to get everything running smoothly.
The "system apk" is /system/framework/framework.jar. I've never tried to re-sign the system image but I've written code which was part of the system image (not within a normal apk project) and it became part of this jar. There are additional jars in this directory which may need to be re-signed also.
The signature is created randomly and placed in two files in your build environment, build/target/product/security/platform.pk8 and build/target/product/security/platform.x509.pem. I don't know how to extract these from a normal key store, however I've been able to copy them from one firmware build to another to ensure that both images had the same platform key. Also, I've been able to change the signature of APKs with this command: java -jar signapk.jar platform.x509.pem platform.pk8 Old.apk New.apk. You'll find signapk.jar in your build, at out/host/linux-x86/framework/signapk.jar