Thursday, March 30, 2017

APKRepatcher - Now Decompile & Recompile APK with easy GUI

APKRepatcher helps you to modify an existing apk using a simple user friendly GUI. It lets you edit java/smali code from an APK and rewrite the changes back to the modified signed APK. Additionally, it provides you option to convert Dex, Jar, Class, Smali, Class from one format to another. APKRepatcher makes use of dex2jar, jadx, rsyantaxtextarea, zip4j, apktool

Features:
  1. Decompiles/Recompiles the APK.
  2. Provides an editor to change the decompiled java code.
  3. Compiles the code using javac and saves the updated class.
  4. Allows you to view smali version of your modified java code.
  5. Allows you to edit smali from the original apk or from your modified java code
  6. Smali changes once saved would be reflected back in updated apk after building project.
  7. Build features re-creates new apk with all code changes and lastly it would resign the apk.
  8. Basic features like find/replace/increase or decrease font are also provided.
  9. It also allows you to convert from Dex to Jar/Class/Smali/Java, Jar to Dex/Java, Class to Dex/Smali, Smali to Class/Java/Dex. Also allows to extract and sign any apk.
  10. Allows you to change the amount of memory utilized by APKRepatcher.
  11. Patch Module
  12. APKRepatcher is created using Java with no os dependency (as far as i think) so you can run it with various OS
  13. 100% Free
How to run:
 java -jar APKRepatcher.jar  

File
  1. Open apk (CTRL+O)- Takes the input apk which need to be modified and extracts it inside <APKRepatcher_Software_Dir>/Projects/<APK_NAME_FOLDER>/
  2. Open Project (CTRL+P)– You can reopen the project created from open apk anytime using this feature. Just point it to <APK_NAME_FOLDER> inside Projects directory.
  3. Compile & Save (CTRL+S) – Saves & Compile the java code which is currently shown on the GUI editor.
  4. Build APK (CTRL+B) – Recreates a newly signed apk with the changed code.
Edit
  1. Increase Code FontSize (CTRL+I) – Allows you to increase font size of shown code.
  2. Decrease Code FontSize (CTRL+D) – Allows you to decrease the font size of shown code.
  3. Remove all tabs – Removes all currently shown tabs.
Extra
  1. Extract APK-APKTool – User can provide any apk for extraction using this option
  2. Convert Dex to Jar – User can convert any of dex file to jar format using this option
  3. Convert Dex to Class – User can convert any of dex file to class file using this option
  4. Convert Jar/Class to Dex – User can convert any of jar/class file to dex format using this option
  5. Convert Class to Smali – User can convert any of class file to smali format using this option
  6. Convert Smali to Class – User can convert any of smali file to class format using this option
  7. Convert Smali to Java – User can convert any of smali file to java format using this option
  8. Convert Dex to Smali – User can convert any of dex file to smali format using this option
  9. Convert Smali to Dex – User can convert any of smali file to dex format using this option
  10. Convert Dex/Jar to Java – User can convert any of dex/jar file to java format using this option
  11. Sign your apk – User can resign any apk using this option

Advanced
  1. Edit Smali using current code – Rewrite the smali version of the currently visible java code. This features requires the java code to be compilable in order to convert to smali.
  2. Edit Smali using original APK – This features opens the smali version of the java class from the original apk. Since it is extracted from original apk so no need of current java code to be compilable
  3. Save and apply smali changes – After you have edited smali code, you need to save it so that it gets reflected in modified apk.

Settings
  1. Change Memory Allocation – User is allowed to change the amount of memory reserved by APKRepatcher. Default is 1500mb or 1.5 GB

Help
  1. Update Software – Helps you to update the current software if any update is available
  2. How to use APKRepatcher – Contains the documentation of APKRepatcher.

Toolbar
  1. Allows you to find in current code/replace/replaceAll/find all class


Extra Software Content:

APKRepatcher_lib Folder
  1. It comes along with the software
  2. Contains the helper jars used by program
  3. APKRepatcher_lib\userLibrary is automatically added in classpath while compiling code. If you wish to compile your code using external jars then place those external jars inside APKRepatcher_lib\userLibrary

Settings.txt File
  1. Contains the memory utilized by APKRepatcher.

Software Screenshot:


Things to Remember:
  1. The default memory allocated to APKRepatcher is 1500mb which can be changed simply using Settings -> Change Memory Allocation
  2. You can add external library while compiling your code by simply placing them under APKRepatcher_lib\userLibrary folder
  3. You can also use APKRepatcher for converting dex/jar/class/smali/java from one format to another.
  4. Patch a module - Assume a class is non compilable because of certain modules used, but you wish to change one of methods which does not have any issue. In this case you can remove the non compilable methods, keeping only your changed method. Now select edit smali for current code under Advanced. You will obtain the smali version for your java module. Now choose Advanced -> edit smali using original apk. Replace your modified module in the original apk smali and then click on Advanced -> save and apply changes. When you build the project, it would patch the module. So you are saved from the errors :)
  5. You can always increase or decrease the font size of the code using hotkeys or from Edit section
  6. Don't forget to build the apk after you made your changes. It will create the new apk.
  7. All projects are stored in the Projects directory which comes along with the software.
Tutorial:
  1. Open APKRepatcher using java -jar APKRepatcher.jar
  2. Click on File -> Open APK
  3. Choose the apk you wish to change
  4. Open the package from the left pane and double click on the java file you want to edit.
  5. Once java file opens in editor, just make the required changes.
  6. After you made the changes, click on File -> Compile & Save
  7. If compilation fails, you will see the errors in the console view.
  8. Fix them and compile again
  9. Once compilation succeeds, you click on File -> Build APK
  10. If build succeeds, you would see the new apk created.
  11. If you are unable to compile your class, and want to make changes directly to smali then you can click on Advanced -> edit smali using original apk (which will open the current code smali from the original apk) and make the edits and then click on Advanced -> save and apply. After that you can click on File -> Build APK
  12. Assume a class is non compilable because of certain modules used, but you wish to change one of methods which does not have any issue. In this case you can remove the non compilable methods, keeping only your changed method. Now select edit smali for current code under Advanced. You will obtain the smali version for your java module. Now choose Advanced -> edit smali using original apk. Replace your modified module in the original apk smali and then click on Advanced -> save and apply changes. When you build the project, it would patch the module. So you are saved from the errors
Note: This software is meant for educational purpose only. Don't use it for any illegal activity.

Saturday, March 18, 2017

Image to PDF using Java

This blog post will allow you to convert your images from either your local system or from URL into pdf format using java code. This will make use of itextpdf library.

Language Used:
Java

Git Location:
https://github.com/csanuragjain/extra/tree/master/Image2PDF

POM Dependency:
  <dependency>  
       <groupId>com.itextpdf</groupId>  
       <artifactId>itextpdf</artifactId>  
       <version>5.0.6</version>  
       <scope>test</scope>  
  </dependency>  

Program:
main method:
      public static void main(String[] args) {  
           Scanner s =new Scanner(System.in);  
           System.out.println("Please provide the path of image");  
           String imgPath=s.nextLine();  
           System.out.println("Please provide the path of pdf");  
           String pdfPath=s.nextLine();  
           boolean isValidURL=false;  
           URL url;  
           try {  
             url = new URL(imgPath);  
             isValidURL=true;  
           } catch (MalformedURLException e) {  
           }  
           new ImageToPDF().imageToPdf(imgPath, pdfPath, isValidURL);  
           s.close();  
           System.out.println("PDF created...");
      }  

How it works:
  1. We create a scanner object to get user input.
  2. We obtain the source path of image and pdf to be created.
  3. We check if the source path of image is a url or is coming from user local computer. We do this by making a URL class object with the image path passed. If the URL is valid then we update isValidURL to true else false.
  4. Now we call the imagetoPDF method which actually converts the image to pdf.
  5. First argument is the path of image. Second one is the path of pdf. Third argument tell if the image is coming from a URL or from user local computer.
imageToPdf method:
      public void imageToPdf(String imgPath, String pdfPath, boolean isValidURL)  
      {  
           Document document= new Document(PageSize.A4);  
           FileOutputStream fos;  
           try {  
                fos = new FileOutputStream(new File(pdfPath));  
                PdfWriter writer = PdfWriter.getInstance(document, fos);  
                writer.open();  
             document.open();  
             if(isValidURL)  
             {  
                  Image img=Image.getInstance(new java.net.URL(imgPath));  
                  float scaler = ((document.getPageSize().getWidth() - document.leftMargin()  
                   - document.rightMargin()) / img.getWidth()) * 100;  
                  img.scalePercent(scaler);  
                  document.add(img);  
             }  
             else  
             {  
                  Image img=Image.getInstance(imgPath);  
                  float scaler = ((document.getPageSize().getWidth() - document.leftMargin()  
                   - document.rightMargin()) / img.getWidth()) * 100;  
                  img.scalePercent(scaler);  
                  document.add(img);  
             }  
             document.close();  
             writer.close();  
           } catch (FileNotFoundException e) {  
                System.out.println("File not found "+e.getMessage());  
           } catch (DocumentException e) {  
                System.out.println("Document exception "+e.getMessage());  
           } catch (MalformedURLException e) {  
                System.out.println("Incorrect path given "+e.getMessage());  
           } catch (IOException e) {  
                System.out.println("Issue while accessing the input file "+e.getMessage());  
           }  
      }  


How it works:
  1. We make a document object and pass PageSize.A4 which simply tells that resulting pdf has A4 size page.
  2. We create a PDFWriter object passing the document we created in step1 and a FileOutputStream object pointing to the pdf file to be created as argument. PDFWriter will be responsible of actually writing on the pdf.
  3. We open the writer object and document object.
  4. Now we prepare the document by adding the image to it. For this we use the add function on document. 
  5. We resized the image using scalePercent so that image does not become larger than pdf.
  6. We close the document and writer which ultimately completes the process and pdf is created.
Output:
 #1  
 Please provide the path of image  
 screen1.jpg  
 Please provide the path of pdf  
 screen1.pdf  
 PDF created...  
 #2  
 Please provide the path of image  
 https://ul-a.akamaihd.net/images/products/94427/product/Apollo_Infinite_FNSF51APMI30000SAAAA.jpg?1467964020  
 Please provide the path of pdf  
 abc.pdf  
 PDF created...  

Full Program:
 package com.cooltrickshome;  
 import java.io.File;  
 import java.io.FileNotFoundException;  
 import java.io.FileOutputStream;  
 import java.io.IOException;  
 import java.net.MalformedURLException;  
 import java.net.URL;  
 import java.util.Scanner;  
 import com.itextpdf.text.Document;  
 import com.itextpdf.text.DocumentException;  
 import com.itextpdf.text.Image;  
 import com.itextpdf.text.PageSize;  
 import com.itextpdf.text.pdf.PdfWriter;  
 public class ImageToPDF {  
      /**  
       * @param args  
       */  
      public static void main(String[] args) {  
           Scanner s =new Scanner(System.in);  
           System.out.println("Please provide the path of image");  
           String imgPath=s.nextLine();  
           System.out.println("Please provide the path of pdf");  
           String pdfPath=s.nextLine();  
           boolean isValidURL=false;  
           URL url;  
           try {  
             url = new URL(imgPath);  
             isValidURL=true;  
           } catch (MalformedURLException e) {  
           }  
           new ImageToPDF().imageToPdf(imgPath, pdfPath, isValidURL);  
           s.close();  
           System.out.println("PDF created...");  
      }  
      public void imageToPdf(String imgPath, String pdfPath, boolean isValidURL)  
      {  
           Document document= new Document(PageSize.A4);  
           FileOutputStream fos;  
           try {  
                fos = new FileOutputStream(new File(pdfPath));  
                PdfWriter writer = PdfWriter.getInstance(document, fos);  
                writer.open();  
             document.open();  
             if(isValidURL)  
             {  
                  Image img=Image.getInstance(new java.net.URL(imgPath));  
                  float scaler = ((document.getPageSize().getWidth() - document.leftMargin()  
                   - document.rightMargin()) / img.getWidth()) * 100;  
                  img.scalePercent(scaler);  
                  document.add(img);  
             }  
             else  
             {  
                  Image img=Image.getInstance(imgPath);  
                  float scaler = ((document.getPageSize().getWidth() - document.leftMargin()  
                   - document.rightMargin()) / img.getWidth()) * 100;  
                  img.scalePercent(scaler);  
                  document.add(img);  
             }  
             document.close();  
             writer.close();  
           } catch (FileNotFoundException e) {  
                System.out.println("File not found "+e.getMessage());  
           } catch (DocumentException e) {  
                System.out.println("Document exception "+e.getMessage());  
           } catch (MalformedURLException e) {  
                System.out.println("Incorrect path given "+e.getMessage());  
           } catch (IOException e) {  
                System.out.println("Issue while accessing the input file "+e.getMessage());  
           }  
      }  
 }  

Hope it helps :)

Saturday, March 4, 2017

URL Encoding and Decoding using Java

It is common requirement to implement URL encoding and decoding in Java while creating crawlers or downloaders. This post focus on creating modules for encoding and decoding of the passed url using Java.

Language Used:
Java

Git Location:
https://github.com/csanuragjain/extra/tree/master/EncodeDecodeURL

Program:
main method:
 public static void main(String[] args) {  
           // TODO Auto-generated method stub  
           String url="https%3A%2F%2Fr1---sn-ci5gup-cags.googlevideo.com%2Fvideoplayback%3Fpcm2cms%3Dyes%26mime%3Dvideo%252Fmp4%26pl%3D21%26itag%3D22%26\u0026itag=43\u0026type=video%2Fwebm%3B+codecs%3D%22vp8.0%2C+vorbis%22\u0026quality=medium";  
           String url2="https://r1---sn-ci5gup-cags.googlevideo.com/videoplayback?pcm2cms=yes&mime=video/mp4&pl=21&itag=22&&itag=43&type=video/webm; codecs=\"vp8.0, vorbis\"&quality=medium";  
           String decodeURL = decode(url);  
           System.out.println("Decoded URL: "+decodeURL);  
           String encodeURL = encode(url2);  
           System.out.println("Encoded URL2: "+encodeURL);  
      }  

How it works:
1) url is the variable having encoded url which we want to decode
2) url2 is the variable having an url which we want to encode
3) We call the decode method which decodes the url and then print the same.
4) We call the encode method which encodes the url2 and then print the same.

encode method:
      public static String encode(String url)  
      {  
                try {  
                     String encodeURL=URLEncoder.encode( url, "UTF-8" );  
                     return encodeURL;  
                } catch (UnsupportedEncodingException e) {  
                     return "Issue while encoding" +e.getMessage();  
                }  
      }  

How it works:
1) We use the encode method of a predefined java class named URLEncoder
2) encode method of URLEncoder takes 2 arguments
3) 1st argument defines the url to be encoded
4) 2nd argument defines the encoding scheme to be used
5) After encoding the resulting encoded url is returned

decode method:
      public static String decode(String url)  
      {  
                try {  
                     String prevURL="";  
                     String decodeURL=url;  
                     while(!prevURL.equals(decodeURL))  
                     {  
                          prevURL=decodeURL;  
                          decodeURL=URLDecoder.decode( decodeURL, "UTF-8" );  
                     }  
                     return decodeURL;  
                } catch (UnsupportedEncodingException e) {  
                     return "Issue while decoding" +e.getMessage();  
                }  
      }  

How it works:
1) Since same url can be encoded multiple times so we need to decode until url cannnot be decoded further.
2) For eg: "video%252Fmp4" is result of 2 encoding. On decoding it once we get "video%2Fmp4". Now url need to be further decoded so when we apply decoding again we get "video/mp4", which is the result.
3) We use the decode method of a predefined java class named URLDecoder
4) decode method of URLDecoder takes 2 arguments
5) 1st argument defines the url to be decoded
6) 2nd argument defines the decoding scheme to be used
7) After decoding the resulting decoded url is returned
8) We create 2 variables prevURL which is empty and decodeURL which contain the url to be decoded.
 Variable State:  
 prevURL = ""  
 decodeURL ="somethingvideo%252Fmp4"  
9) We create an iteration which runs until prevURL!=decodeURL
10) Now we update prevURL to decodeURL and update decodeURL with the decoded value of the url passed.
 Variable State:  
 prevURL = "somethingvideo%252Fmp4"  
 decodeURL ="somethingvideo%2Fmp4"  
11) Since prevURL!=decodeURL so Step 10 runs again
 Variable State:  
 prevURL = "somethingvideo%2Fmp4"  
 decodeURL ="somethingvideo/mp4"  
12) Since prevURL!=decodeURL so Step 10 runs again
 Variable State:  
 prevURL = "somethingvideo/mp4"  
 decodeURL ="somethingvideo/mp4"  
13) Since prevURL=decodeURL so the decoded url is returned.

Output:
 Decoded URL: https://r1---sn-ci5gup-cags.googlevideo.com/videoplayback?pcm2cms=yes&mime=video/mp4&pl=21&itag=22&&itag=43&type=video/webm; codecs="vp8.0, vorbis"&quality=medium  
 Encoded URL2: https%3A%2F%2Fr1---sn-ci5gup-cags.googlevideo.com%2Fvideoplayback%3Fpcm2cms%3Dyes%26mime%3Dvideo%2Fmp4%26pl%3D21%26itag%3D22%26%26itag%3D43%26type%3Dvideo%2Fwebm%3B+codecs%3D%22vp8.0%2C+vorbis%22%26quality%3Dmedium  

Full Program:
 package com.cooltrickshome;  
 import java.io.UnsupportedEncodingException;  
 import java.net.URLDecoder;  
 import java.net.URLEncoder;  
 public class URLEncodeDecode {  
      public static void main(String[] args) {  
           // TODO Auto-generated method stub  
           String url="https%3A%2F%2Fr1---sn-ci5gup-cags.googlevideo.com%2Fvideoplayback%3Fpcm2cms%3Dyes%26mime%3Dvideo%252Fmp4%26pl%3D21%26itag%3D22%26\u0026itag=43\u0026type=video%2Fwebm%3B+codecs%3D%22vp8.0%2C+vorbis%22\u0026quality=medium";  
           String url2="https://r1---sn-ci5gup-cags.googlevideo.com/videoplayback?pcm2cms=yes&mime=video/mp4&pl=21&itag=22&&itag=43&type=video/webm; codecs=\"vp8.0, vorbis\"&quality=medium";  
           String decodeURL = decode(url);  
           System.out.println("Decoded URL: "+decodeURL);  
           String encodeURL = encode(url2);  
           System.out.println("Encoded URL2: "+encodeURL);  
      }  
      public static String decode(String url)  
      {  
                try {  
                     String prevURL="";  
                     String decodeURL=url;  
                     while(!prevURL.equals(decodeURL))  
                     {  
                          prevURL=decodeURL;  
                          decodeURL=URLDecoder.decode( decodeURL, "UTF-8" );  
                     }  
                     return decodeURL;  
                } catch (UnsupportedEncodingException e) {  
                     return "Issue while decoding" +e.getMessage();  
                }  
      }  
      public static String encode(String url)  
      {  
                try {  
                     String encodeURL=URLEncoder.encode( url, "UTF-8" );  
                     return encodeURL;  
                } catch (UnsupportedEncodingException e) {  
                     return "Issue while encoding" +e.getMessage();  
                }  
      }  
 }  

Hope it helps :)