How can I programmatically decompile dex files within Android? - java

I know how to extract apk files to classes using a windows based system as below:
Step 1:Renaming .apk file
Rename the .apk file with the extension .zip (for example let the file
be "demofile.apk" then after renaming it becomes "demofile.apk.zip")
Step 2:Getting java files from apk
Now extract the renamed zip file in specific folder, for example let
that folder be "demofolder". Now Download dex2jar from the link for
windows and extract that zip file in folder "demofolder".
Now open command prompt and go to the folder created in previous step
and type the command "dex2jar classes.dex" and press enter.This will
generate "classes.dex.dex2jar" file in the same folder.
Now Download java decompiler from the link and extract it and
start(double click) jd-gui.exe
From jd-gui window browse the generated "classes.dex.dex2jar" file in
demofolder, this will give all the class files by src name.
Now from the File menu select "save all sources" this will generate a
zip file named "classes_dex2jar.src.zip" consisting of all packages
and java files.
Extract that zip file (classes_dex2jar.src.zip) and you will get all
java files of the application.
Above steps will generate java files but to get xml files perform
following steps.
Step 3:Getting xml files from apk
Download apktool and apktool install from the link and extract both
files and place it in the same folder (for example "demoxmlfolder").
Place the .apk file in same folder (i.e demoxmlfolder)
Now open command prompt and goto the directory where apktool is stored
(here "demoxmlfolder") and type the command "apktool if
framework-res.apk" Above command should result in "Framework installed
..." Now in command prompt type the command "apktool d filename.apk"
(where filename is name of apk file) This will generate a folder of
name filename in current directory (here demoxmlfolder) where all xml
files would be stored in res\layout folder.
But I would like to know how to accomplish the above programatically within Android. So my android application can simply extract another app's dex file. I don't mind if the dex file is copied elsewhere on the phone, then decompiled (it is simply the decompilation I'm stuck on)
On the principle as below, that I have access to each app's dex, just not the knowledge of how to decompile it within Android.
Any help would be fantastic.
final PackageManager pm = getPackageManager();
PackageInfo packageInfo = null;
try {
packageInfo = pm.getPackageInfo("PACKAGE NAME HERE", PackageManager.GET_META_DATA);
} catch (NameNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
File file = new File(packageInfo.applicationInfo.sourceDir);
Uri uri = Uri.fromFile(file);

You can browse the sourcecode of the ShowJava application here. It looks like he is using the the Dex2Jar tool. The decompilation starts in a BackgroundService and all the magic happens in some special Jar classes. I do not know if this code comes from a library or if all this code is created by him. Look at the ExtractJar and the DecompileJar method than it shouldn't be to hard to understand what's going on.

You need to follow some steps in order to get it working:
Got to the dex2jar bitbucket site and download the files. Add the jar files to your project.
Via the DexFileFactory, you can load the apk, convert it to dex (loadDexFile) and save it to a file (writeDexFile).
With another library that converts jars to java-files, you can finally read the content. I found Procyon, which seems really simple. Load the class file with an InputTypeLoader and then call Decompiler.decompile().
Of course you can use other libraries in step 3, but for step 1 and 2, I haven't found any alternatives.

Related

How to create correct resource file path in a java jar file

Sitting here with a bigger java project (for a first year software student) having some troubles creating the correct file path to resources.
I right now have files in the form of .txt, .png, .jpg, and a .gif.
Right now i use paths like this to find a text file:
File userFile = new File("Source Code/files/users.txt");
Or paths like this to create an image loaded in my FX code:
File logoPath = new File("Source code/files/graphics/Streamy_logo.png");
Image logoImage = new Image(logoPath.toURI().toString());
logo.setImage(logoImage);
This works fine in my IDE (IntelliJ), however it doesn't work when i create the project as a Jar file.
I think is has to do with the "source code" directory not created in the jar-file, which makes sense now.
Tried to read different subjects, but it seems a bit different if i should use a getResources-method, set a resourceStream or something else.
Can anybody please help me with this.
Thank you!
You can't load files like that in .jar files here's an example on how to read BufferedImages.
But first, make sure you have marked the resource folder as a resource folder in IntelliJ by right-clicking the folder in the project view and going down to "Mark directory as" and checking resource root.
BufferedImage exampleBlock = null;
try {
exampleBlock = ImageIO.read(ClassLoader.getSystemResource("exampleBlock.png"));
} catch (IOException e) {
e.printStackTrace();
}
By using this method of getting files all your files will be implemented into the .jar file and you can use them by calling their file name + extension
For maven or gradle projects, that respects maven directories convention you can simply use
getClass().getResource("/your_file_located_in_src_main_resources.extension").getPath()

Extraction APK : what are .png# files?

I would like to extract the images from an android game.
Firstly, I took the APK on my windows 10 laptop then I extracted the files (rename files.apk to files.apk.zip and extracted it with 7zip).
Inside my folders I got many .png files but I get an error when I try to open one. Each .png file has another file with the same name but with .png#. Some even have 2 otherfiles with them : one with .skel (can't open this one too) and .atlas (I can open it with notepad):
Did I make mistakes? What can I do to "repair" all these png files?
Thank you for you help!
If you are authorised to do so then you can apktool.
Its easy to use and may that #png files will be converted to some meaningful resource.
Installation for Apktool
Windows:
Download Windows wrapper script (Right click, Save Link As apktool.bat)
Download apktool-2 (find newest here)
Rename downloaded jar to apktool.jar
Move both files (apktool.jar & apktool.bat) to your Windows directory (Usually C://Windows)
If you do not have access to C://Windows, you may place the two files anywhere then add that directory to your Environment Variables System PATH variable.
Try running apktool via command prompt
Link

Writing to text file created manually inside app

Is it possible in Android, to manually add a file inside a project and then, modify it? Example:
"I have a test.txt file in the following path: "app/src/data". I would like to make a method to write a given String in the test.txt file."
Is that possible? I been looking everywhere, but can't seen to do such an easy task.
If you mean modifying files inside the APK itself then it's not possible. Besides, the folder structure you see in the project is not the final structure on the APK (just unzip your APK, it's a .ZIP really): Fpr example, the source directory is all compiled into a classes.dex. The res/ directory is compiled and fully copied ...
Take a look at How to write files to assets folder or raw folder in android?
and https://developer.android.com/training/basics/data-storage/files.html
You can read raw files stored in /res/raw, or assets stored in assets/ , but you cannot modify stuff inside the APK itself.
What you can do is create and modify as many files as you wish from the different places Android gives to any app, such as:
CACHE directory (context.getCacheDir() -> /sdcard/Android/data/your.package/cache
External files (context.getExternalFilesDir() -> /sdcard/Android/data/your.package/files
Arbitrary directories in the SDCARD.

error while opening pdf files from jar folder

I am making a Software in whihch I have to display the pdf files. I have stored the pdf files in my project folder. The software runs perfectly fine.
But when I cleand and build the project and then i run my jar exe file the pdf files doesnt open.
After some experiments I included my pdf files in SRC folder and then clean and build the project. The difference i found is that now the jar file is bigger in size ( it equals to sum of all the pdf files) , I thought that this time it would work . But it didnt work.
Then After more experiments I included all the files in the Dist folder.
Then The jar files can open the pdf files :) , I was happy but not satisfied, Since I only have to create a jar file and seeing all the pdf files in the project folder with one jar files looks really awkard and senseless, is thier anyway i can open the pdf files using only the jar file without copying the pdf files in the folder where my jar file is stored, . This is the code i used to open a file named "aleemullah resume".
try{
Runtime.getRuntime().exec("rundll32 url.dll,FileProtocolHandler " + "aleemullah resume.pdf");
}
catch (Exception e) {
JOptionPane.showMessageDialog(null, "Error");
}
It looks as if you are reading the PDF file from your current working directory (that is, the folder that your program is launched from). By that logic, you should be able to open a PDF stored anywhere by entering it's full path, rather than just the file name. For instance:
String filePath = "C:\Users\you\Desktop\aleemullah resume.pdf"
Runtime.getRuntime().exec("rundll32 url.dll,FileProtocolHandler " + filePath);
Change the filePath variable to wherever you are storing the PDF file.
You might also consider using a JFileChooser to select the file if you want the user to choose the PDF during runtime. Check out this example of how to open a dialog box from Java to pick a PDF file and retrieve its path.

Android FileNotFound Exception with a plist file that will be built in

I am trying to open a file for an Android app I am making. I tested the code that opens this file on a regular Java project, and it opens fine. However when I use this code in an Android Java project I get an java.io.FileNotFoundException error.
File file = new File ("list.plist");
Now the list.plist file is in the parent directory of the project. This file will be included in the app as its the only one it will be using.
I guess I am used to Xcode where I can just place the file anywhere in the project and I can access it without a problem.
How am I supposed to structure this path?
Thanks :-)
I've used this but it also did not work.
File file = new File(context.getFilesDir().getAbsoluteFile(), "list.plist");
Firstly, you need to ensure the file you are using is packaged within your app - such as in the assets directory.
Secondly, Android automatically compresses plist files based on the extension. As a workaround, change the extension to something Android will not compress. These extensions include:
".jpg", ".jpeg", ".png", ".gif",
".wav", ".mp2", ".mp3", ".ogg", ".aac",
".mpg", ".mpeg", ".mid", ".midi", ".smf", ".jet",
".rtttl", ".imy", ".xmf", ".mp4", ".m4a",
".m4v", ".3gp", ".3gpp", ".3g2", ".3gpp2",
".amr", ".awb", ".wma", ".wmv"
(for full article, see dealing-with-asset-compression-in-android-apps)
You need to put this file in the assets dir and not in the parent folder. Any files in the parent folder need not be packaged with the app. Moreover, the structure of your files on a phone is not the same as you see in eclipse.
You should use "res/raw" or "assets" directory to include a raw file in your Android project.
see: http://developer.android.com/guide/topics/data/data-storage.html
I added the list.plist to the assets folder and renamed it list.mp3 to avoid compression issues.
AssetManager assetManager = getAssets();
InputStream inputStream = assetManager.open("list.mp3");
This successfully opened the file without problems, which now allows me to parse the inputStream.
Thanks to Phil for giving sending me in the right direction.

Categories