Is there a way to read META-INF\MANIFEST.MF file of the currently running application using Android API?
I want to read SHA1 for classes.dex file and use it as an encrpytion key to one of my assets.
I cannot use the signature for .apk file because everytime I create a new apk I need to re-encrpyte my asset and put in to apk file which requires re-signing the .apk and it becomes a chicken and egg problem.
I have found a way to do it. I opne the .apk file as a JarFile and then I can access individual files inside .apk. I believe this will only work for the .apk file that is running this code.
Here it is:
// Get Package Name
String packageName = ctx.getPackageName();
// Get classes.dex file signature
ApplicationInfo ai = ctx.getApplicationInfo();
String source = ai.sourceDir;
JarFile jar = new JarFile(source);
Manifest mf = jar.getManifest();
Map<String, Attributes> map = mf.getEntries();
Attributes a = map.get("classes.dex");
String sha1 = (String)a.getValue("SHA1-Digest");
Use following way to detect External Jar/SDK MANIFEST.MF Info. We could use this info for detecting Jar version etc. Use http://docs.oracle.com/javase/6/docs/api/java/util/jar/Manifest.html
public void getSDKInfo() {
Package package = Manifest.class.getPackage();
String specTitle = package.getSpecificationTitle();
String vendor = package.getSpecificationVendor();
String virsion = package.getSpecificationVersion();
}
Related
I am using Unity 5.6.
Until now, the Android used a way to inspect the classes.dex file inside the APK to prevent app tampering
For a typical build, I had no problem importing the classes.dex file.
However, using the 'Split Binary Build' option to use the .obb file, I could not import the classes.dex file properly.
I used to import classes.dex file in the following way
string urlScheme = #"jar:file://";
string apkPath = Application.dataPath;
string separator = #"!/";
string entry = #"classes.dex";
string url = urlScheme + apkPath + separator + entry;
If you use the Split Binay Option in Unity, the path to Application.dataPath will be 'android / data / obb /.../ myobb.obb'
s there a way to get the same result as the existing Application.dataPath using the Split Binary Build option?
I solved it.
It was impossible to solve within Unity.
You can get the same results if you use the values imported from Java in Unity.
PackageManager m = getPackageManager();
String s = getPackageName();
PackageInfo p = m.getPackageInfo(s, 0);
s = p.applicationInfo.sourceDir;
Reference : Get Application Directory
I'm trying to load dynamically external classes using DexClassLoader, like #Shlublu proposes here
When I execute my application and the DexClassLoader object try to find the class, it throws a ClassNotFound exception. I have added read and write permissions in the manifest.xml, so it is not the mistake.
I think the problem is the method that I use to make the .jar that I want to load on my application. So I have some questions...
What is the correct method to convert a .java file to .jar using dx
tool?
It is necessary that the package where the external class is loaded be the same that the package of my .jar file? (I think no)
I'm using an Android emulator API 19 (kit-kat)
Since APK is the standard Android package, my suggestion is that you use an APK instead of a JAR. Build an application APK linking the needed JAR (let the Android build tools "dex" the JAR) but without any activity, then install the APK as if it was a normal app. You can then access the APK file itself using the PackageManager to get its path and load it using DexClassLoader.
public static ClassLoader loadAPK(final Context context, final String appName) throws PackageManager.NameNotFoundException {
final String apkPath = context.getPackageManager().getApplicationInfo(appName, 0).sourceDir;
final File tmpDir = context.getDir("tmp", 0);
return new DexClassLoader(apkPath, tmpDir.getAbsolutePath(), null, context.getClassLoader());
}
I wanted to know that is it possible to find version of an apk file that i've downloaded from the server?
i can retrieve the version of my app that is installed on device but i want to check installed app version on device with the downloaded apk file version.
You cannot easily get the version of the APK file you downloaded until you have installed it.
That being said, you can unzip the APK file (its just a zip file) and parse the AndroidManifest.xml to get the value of the version code.
Since the AndroidManifest.xml you extract is a binary file, you will need to write some code to parse it. It's not as simple as inspecting a plain text file.
Check out this post on how to parse the AndroidManifest which has been extracted from an APK.
How to parse the AndroidManifest.xml file inside an .apk package
PackageManager manager = this.getPackageManager();
PackageInfo info = manager.getPackageInfo("com.whatsapp", 0);
String packageName = info.packageName;
int versionCode = info.versionCode;
String versionName = info.versionName;
Replace com.whatsapp with your package name.
I need to modify preexisting .apk files present in the /data/app folder. After the modifications the signatures change in the Meta-INF folder. So in order to make sure the apk works properly I need to resign them with the correct md5sum.
Is it possible to resign the apks programmatically through java, generating private key and certs through code only?
I am using Bouncy Castle and this class. Re-sign example:
SignedJar bcApk = new SignedJar(
new FileOutputStream("out.apk"), signChain, signCert, signKey);
JarFile jsApk = new JarFile(new File("in.apk"));
Enumeration<JarEntry> entries = jsApk.entries();
while (entries.hasMoreElements()) {
JarEntry entry = entries.nextElement();
String name = entry.getName();
if (!entry.isDirectory() && !name.startsWith("META-INF/")) {
InputStream eis = jsApk.getInputStream(entry);
bcApk.addFileContents(name, IOUtils.toByteArray(eis));
eis.close();
}
}
jsApk.close();
bcApk.close();
it is possible to get installer file name which is stored on /sdcard/
download/ ? I want to get from app, apk file name which installed it.
There is a easy way to do it especially with non-market app?
The better way is definitely to include the version string in the manifest. This is really the only reliable (and professional) method. Android doesn't store the name of the file containing the APK anywhere, so there isn't a way that you can get it.
Theoretically you could probably build something using a FileObserver, that watched file creation in certain directories and every time a file was created with the extension .apk you could open the file, extract the manifest, find the package name of the APK and then store this along with the filename in some persistent storage. Then, when you need get the version information, you can look in the persisten storage to get the file name matching the package name you need.
Of course, this would only work if your app was installed on the device before the other APK files were downloaded/installed. This wouldn't work to find out the filename of your own application.
Hmm, I am not sure what you mean by sdcard or download folder, but you could get apk path in system /data directory:
command line:
$ adb shell pm list packages | grep mk.trelloapp
package:mk.trelloapp
$ adb shell pm path mk.trelloapp
package:/data/app/mk.trelloapp-1/base.apk
or from you android application code: (simply run process)
Process exec = Runtime.getRuntime().exec("pm path mk.trelloapp");
exec.waitFor();
InputStream inputStream = exec.getInputStream();
BufferedReader br = new BufferedReader(new InputStreamReader(inputStream));
StringBuilder builder = new StringBuilder();
String line = null;
while( ( line = br.readLine()) != null ) {
builder.append(line);
}
String commandOutput = builder.toString();
Code above should simply give you String containing "package:/data/app/mk.trelloapp-1/base.apk"
When you acquire path in /data directory, you might try to search for same (similar) file in other directories (assuming it was not deleted), since android package is copied to /data directory while instalation.