Reverse Engineering of an APK - java

For my master thesis I'm studying and improving the security of an application. The code is obfuscated and my goal now is to see how easily I can exploit the application. However, I'm having some problems; I think I may have found a piece of code that, when removed, will allow me to override some fundamental step of the application logic. As such, I want to recompile the single class that contains that piece of code and replace the one on the application with this new version. I used dex2jar to obtain a jar with all the classes and have already obtained the .java file with the class I want to alter. My exact problem is how I can recompile the file. I already downloaded the Android API jars and I'm using javac with the classpath pointing to the jar having the remaining classes of the application and to the Android API, but I still can't compile as javac complains about some Android literals being ambiguous. Can you please help? Thanks!

Related

Create API jar like Android does with stubbed methods?

I'm looking to distribute a custom API and know the classes will be available at run time. I would like my public and protected methods / classes to be included in a jar I can distribute but I don't want any other source code and I would like to throw an exception if that jars code is actually executed.
This is the exact behaviour the Android framework jar has when you attempt to execute the jar directly.
My question is how to I create the same jar from my source without manually going through and creating each stubbed method. I would like this to scale as my API grows.
I believe you can use for that purpose the mkstubs tool: https://github.com/android/platform_development/tree/master/tools/mkstubs
As #CommonsWare mentioned stubs in AOSP are generated by javadoc DroidDoc script, read here: How are .java files in android_stubs_current_intermediates directory generated?
One possibility is to write a Java compiler which outputs a copy of your source code with empty method bodies or a body work a single statement which throws an exception. Then you can use normal dev tools to compile the generated classes.

How to fix sealing violation from a library? sealing violation: package org.lwjgl.opengl is sealed

While setting up a project as a template for Slick2d based projects following the instructions here:Slick2d wiki using the provided code for testing setup here at run-time I keep getting a giant block of sealing errors. My thought is that this problem stems from the version of ljgwl.jar in both libraries, however Slick requires both in order to function properly. How can I resolve this?
Package sealing is a Java feature implemented in part in the JAR file format. It is discussed in several places, including in Oracle's Java Tutorial, but the bottom line is that when package sealing is enabled in a Jar's manifest, no classes belonging to that package can appear in any other JAR file.
My thought is that this problem stems from the version of ljgwl.jar in both libraries, however Slick requires both in order to function properly.
I'm not sure what you mean by "library", as that is not a Java concept. I suspect, however, that you're trying to say that you somehow have ljgwl.jar files from two separate sources, and you've put both into your project classpath. That would indeed be a problem, and more than just for package sealing. You can, in fact, be thankful for the sealing errors, for they may have saved you from subtler, more difficult to diagnose runtime errors.
How can I resolve this?
You should have only one copy of LWJGL in your classpath, regardless of any requirements enforced by package sealing, and regardless of how the classes are packaged in jar files. It looks like the Slick2D distribution may come with a copy of LWJGL -- in that case, it's probably wisest to use that one. As long as it's in your classpath (as it must be anyway for Slick2D to use it), any class anywhere in your application can use it.
It gets tricky if you need to contend with a inconsistent requirements for LWJGL version, or if you have obtained a JAR that incorporates the LWJGL classes along with something else, but that doesn't change the bottom line: you must choose one version of LWJGL, use that version exclusively within your application, and include only one copy of it in your classpath.

Why is Java RunTime has reported a java.lang.NoSuchMethodError on Hex.encodeHex() method call?

I had to include some bittorrent java library to my Android project. My workspace: Android Studio 1.0.2 (osx) and jdk8. I've connected its maven-repository (ttorrent:1.4) with Gradle and after starting using main classes and features i've got an error:
java.lang.NoSuchMethodError: No static method encodeHex([BZ)[C in class Lorg/apache/commons/codec/binary/Hex; or its super classes (declaration of 'org.apache.commons.codec.binary.Hex' appears in /system/framework/ext.jar).
I went to library's code and find out that it's using org.apache.commons.codec from where ttorrent is importing encodeHex and calling it. Looks like binaryHex method is gone! Or it never been. But I went to commons.codec's code and found binaryHex in its place and with arguments that I was looking for. How come? Why? My Android Studio found it. But java runtime not.
In fact, the decision was more difficult than I thought. Let's start with the fact that I came across an article by Dieser Beitrag'a, from which it is clear that not one I had similar problems. The whole thing turned out that within the Android operating system already has some libraries that have a higher priority use, rather than loaded with dependencies along with the application. Among them there and my org.apache.commons.codec.
Yes, such things.
To solve the problem in two ways, either you need to pump source code library and using some tool to rename the project (i.e. org.apache.commons.codec to org.apache.commons.codec.android), collected it to a .jar file, include .jar in a project and at code use imports of the necessary classes only "our" library, or just get the required class to your project and do not pull a megabytes of unneeded code. However, I did just that.
Thanks for help!

How should I deal with dependencies with identically named but distinct classes?

I have an android project that relies on two jar files. Each jar file contains org.slf4j.impl.StaticLoggerBinder. The implementation of this class is different in each file. When I try to build this is causing the following exception:
com.android.dex.DexException: Multiple dex files define Lorg/slf4j/impl/StaticLoggerBinder;
One of these libraries is logback-android, the other is closed source.
Is there any way to get these both working?
Having two jars with the same class inside is not forbidden in Java, but is dangerous and that's why Android is being conservative and raising an error.
What could happen is that having two different versions of the class (say 1.0 and 1.1), when loading the class, one or the other gets loaded in no really predictable way. So, if the compiler let you call a given method on version 1.1, the JVM will not find that method cause it loaded version 1.0 which didn't have it. Replace method with everything else (constructor, field etc..), and consider that usually this happens with full packages and not single classes, so you'll have a lot of classes of version 1.1 not finding methods on other classes of version 1.0 and so on.
Java itself does not have a standard solution to this. However, jar files are nothing more than zip files, and unless they are signed they can be opened and modified and re-jarred.
You could open the closed source .jar, remove it's org/slf4j folder, re-jar it, and try if it works with the other version of org.slf4j.
Or better yet, tell those guys that having a "single jar" with every kind of stuff inside is not cooler than having the jars separated.

Java - how to get dependencies to ignore each other?

We are developing a fairly large project and have many dependencies. Recently, we ran into an issue with a conflict between two of them, agileAPI.jar and axis.jar. Both are 3rd party libraries.
The code in question depends directly on agileAPI.jar. If I build it with just that in the build path, everything that depends on it works correctly.
As soon as I add axis.jar to the build path (just adding it, not writing code that depends on it), everything goes wrong. Some of the code that depended on the first library is now throwing exceptions from the 2nd library. It is as if the first library is picking and choosing methods to call from the 2nd library, instead of whereever it was calling them from prior.
I have code in the project that needs axis.jar directly, so I can't just remove it from the build path. I need to find a way to have these two exist in the same build path, but ignore each other.
It should be noted that both libraries coexisted prior to a recent upgrade with agile. I have been working with Oracle's support team to try and resolve this. After two weeks, though, I am looking for other sources of help.
Our environment is Windows and Eclipse, although in testing this, it also occurs when running java from a command line. Our JDK is 1.5.0_22.
Any help would be appreciated.
Thank you,
David
EDIT:
As requested, here are the stack traces that we see. The first stack trace is printed in the code beyond my control:
java.lang.NoSuchMethodError: org.apache.axis.description.OperationDesc.setStyle(Lorg/apache/axis/constants/Style;)V
at com.agile.webfs.components.fileserver.client.FileServerSoapBindingStub._initOperationDesc1(FileServerSoapBindingStub.java:37)
at com.agile.webfs.components.fileserver.client.FileServerSoapBindingStub.<clinit>(FileServerSoapBindingStub.java:20)
at com.agile.webfs.components.fileserver.client.FileServerWSServiceLocator.getFileServer(FileServerWSServiceLocator.java:43)
at com.agile.webfs.client.IFSLocator.getRemoteFileServer(IFSLocator.java:128)
at com.agile.webfs.client.IFSLocator.getConnection(IFSLocator.java:101)
at com.agile.api.pc.EJBLookup.createFileSession(EJBLookup.java:444)
at com.agile.api.pc.EJBLookup.getFileSession(EJBLookup.java:432)
at com.agile.api.pc.attachment.IFSOutputStream.getFileSession(IFSOutputStream.java:133)
at com.agile.api.pc.attachment.IFSOutputStream.copyFrom(IFSOutputStream.java:87)
at com.agile.api.pc.attachment.IFSOutputStream.copyFrom(IFSOutputStream.java:115)
at com.agile.api.pc.TableAttachment.uploadFile(TableAttachment.java:886)
at com.agile.api.pc.TableAttachment$AddFiles2Action.doSdkAction(TableAttachment.java:724)
at com.agile.api.common.SDKAction.run(SDKAction.java:23)
at com.agile.api.common.OracleAuthenticator.doAs(OracleAuthenticator.java:131)
at com.agile.api.common.Security.doAs(Security.java:54)
at com.agile.api.common.Security.doAs(Security.java:109)
at com.agile.api.pc.TableAttachment.addFiles2(TableAttachment.java:483)
at com.agile.api.pc.TableAttachment.createNewBlob2(TableAttachment.java:459)
at com.agile.api.pc.TableAttachment.doCreateServerRowWithParam(TableAttachment.java:363)
at com.agile.api.pc.Table.createTableRow(Table.java:238)
at com.agile.api.pc.TableAttachment.createTableRow(TableAttachment.java:169)
at com.agile.api.pc.Table.createRow(Table.java:202)
at com.[snip].updateAttachments(VaultImportService.java:3068)
at com.[snip].processIncorporatedFile(VaultImportService.java:926)
at com.[snip].processPdxFile(VaultImportService.java:532)
at com.[snip].processPdxRequest(VaultImportService.java:388)
at com.[snip].<init>(VaultImportService.java:299)
at com.[snip].main(VaultImportService.java:3660)
After the exception bubbles up and we catch it, the stacktrace that we print looks like:
at com.agile.api.pc.Session.createError(Session.java:1772)
at com.agile.api.pc.EJBLookup.createFileSession(EJBLookup.java:454)
at com.agile.api.pc.EJBLookup.getFileSession(EJBLookup.java:432)
at com.agile.api.pc.attachment.IFSOutputStream.getFileSession(IFSOutputStream.java:133)
at com.agile.api.pc.attachment.IFSOutputStream.copyFrom(IFSOutputStream.java:87)
at com.agile.api.pc.attachment.IFSOutputStream.copyFrom(IFSOutputStream.java:115)
at com.agile.api.pc.TableAttachment.uploadFile(TableAttachment.java:886)
at com.agile.api.pc.TableAttachment$AddFiles2Action.doSdkAction(TableAttachment.java:724)
at com.agile.api.common.SDKAction.run(SDKAction.java:23)
at com.agile.api.common.OracleAuthenticator.doAs(OracleAuthenticator.java:131)
at com.agile.api.common.Security.doAs(Security.java:54)
at com.agile.api.common.Security.doAs(Security.java:109)
at com.agile.api.pc.TableAttachment.addFiles2(TableAttachment.java:483)
at com.agile.api.pc.TableAttachment.createNewBlob2(TableAttachment.java:459)
at com.agile.api.pc.TableAttachment.doCreateServerRowWithParam(TableAttachment.java:363)
at com.agile.api.pc.Table.createTableRow(Table.java:238)
at com.agile.api.pc.TableAttachment.createTableRow(TableAttachment.java:169)
at com.agile.api.pc.Table.createRow(Table.java:202)
at com.[snip].updateAttachments(VaultImportService.java:3068)
at com.[snip].processIncorporatedFile(VaultImportService.java:926)
at com.[snip].processPdxFile(VaultImportService.java:532)
at com.[snip].processPdxRequest(VaultImportService.java:388)
at com.[snip].<init>(VaultImportService.java:299)
at com.[snip].main(VaultImportService.java:3660)
In both cases, the line "at com.agile.api.pc.Table.createRow(Table.java:202)" is the agileAPI call that I am making. I have removed our package structure, as it identifies the company that I work for. They value privacy and security.
I'd advise you to check these two things first:
Open the axis.jar file with some zip utility, like 7-Zip or WinRar. See if there's a folder called "services" in the META-INF folder in the jar. If there is, it's possible that the axis.jar file specifies implementations for specific interfaces that somehow don't interoperate with agileAPI. Also do the same for agileAPI.jar, since it might itself declare an interface implementation that axis doesn't like.
Open both agileAPI.jar and axis.jar with a zip utility, then check if there's packages with the same name. If there's none, it won't be a naming conflict. If there's one or more, open the corresponding folders and do the same check recursively. If you end up with at least one class with the same name in the same package across the two jars, it's probably a naming conflict.
That should catch the most obvious issues. If none of this is the case, we'll need to look deeper.
A way to solve such classpath issues is to use a module system such as OSGi or the NetBeans Platform module system where each module has its own classloader.

Categories