Monday, September 18, 2017

Authorization bug which I discovered in Prezi

Prezi allows you to create cool presentation, which you can later share with your audience. It also allows you to add collaborator who can assist in your presentation creation
I started testing Prezi for security vulnerabilities (bugbounty.prezi.com) and found an Authorization bug which allowed me to Add/Delete/Modify Collaborator for any public prezi which were not even mine.

Vulnerable Request:
While adding collaborator to your prezi presentation, below PUT request is fired
PUT /api/v1/share/<presentation_id>/permissions/ HTTP/1.1
Host: prezi.com
Connection: close
Content-Length: 60
User-Agent: <User agent string>
Origin: https://prezi.com
x-csrftoken: <csrf_token>
content-type: application/json
Accept: */*
Referer: https://prezi.com/dashboard/next/
Accept-Language: en-US,en;q=0.8
Cookie: <Cookie for attacker@gmail.com>

{"email":"attackerNewIdOrRealCollaborator@gmail.com","permission":"viewer"}

Explanation of above request:
1) <presentation_id> is Victim’s presentation
2) attacker@gmail.com: Attacker who is firing the above request
3) attackerNewIdOrRealCollaborator@gmail.com: It can be either Attacker id or a genuine collaborator of this presentation with editor rights.

What happens:
1) If Attacker used his own id in the body parameter, then he would become part of the presentation <presentation_id> without victim permission.
2) If Attacker used a genuine collaborator id having editor rights, then after firing this request, the collaborator permission would lower from editor to viewer only
3) If Attacker, simply changes the above request header from PUT to delete then any collaborator (except owner) passed within body parameter would get deleted from that presentation
4) This attack worked only for public prezis (and not for private prezis) because they are somewhat special - everyone has view permissions by default, although they are not collaborators of it (people who are explicitly added to view/edit the prezi). The vulnerable endpoint unfortunately considered this "default view permission" as a "collaborator permission", which allowed you to add anyone else as a view collaborator. This "collaborator privilege" enabled you to lower the existing collaborators' permission to view level by re-adding them.



I reported the same to Prezi which was fixed fast and Prezi rewarded a nice bounty :)

Sunday, July 23, 2017

Facial Detection using Java

In this post, we will learn how to extract faces out of an image from webcam. We will make use of 2 library which are sarxos and openimaj

Language Used:
Java

Git Repo:
https://github.com/csanuragjain/extra/tree/master/FaceRecognition

Website:
https://cooltrickshome.blogspot.com/2017/07/facial-recognition-using-java.html

Pom Dependency:
 <dependency>  
   <groupId>org.openimaj</groupId>  
   <artifactId>image-feature-extraction</artifactId>  
   <version>1.3.5</version>  
 </dependency>  
 <dependency>  
      <artifactId>faces</artifactId>  
      <groupId>org.openimaj</groupId>  
      <version>1.3.5</version>  
      <scope>compile</scope>  
 </dependency>  
 <dependency>  
        <groupId>com.github.sarxos</groupId>  
        <artifactId>webcam-capture</artifactId>  
        <version>0.3.11</version>  
        <scope>test</scope>  
   </dependency>  

Reference:
https://cooltrickshome.blogspot.com/2016/11/take-snapshot-from-webcam-using-java-in.html
http://openimaj.org/

Program:

FaceDetector.java

Variables:
      private static final long serialVersionUID = 1L;  
      private static final HaarCascadeDetector detector = new HaarCascadeDetector();  
      private Webcam webcam = null;  
      private BufferedImage img= null;  
      private List<DetectedFace> faces = null;  


main method:
 public static void main(String[] args) throws IOException {  
           new FaceDetector().detectFace();  
      }  

How it works:
1) We create an object of FaceDetector class which class the default constructor and then we call the detectFace method of this class.

FaceDetector constructor:
      public FaceDetector() throws IOException {  
           webcam = Webcam.getDefault();  
           webcam.setViewSize(WebcamResolution.VGA.getSize());  
           webcam.open(true);  
           img=webcam.getImage();  
           webcam.close();  
           ImagePanel panel=new ImagePanel(img);  
           panel.setPreferredSize(WebcamResolution.VGA.getSize());  
           add(panel);  
           setTitle("Face Recognizer");  
           setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);  
           pack();  
           setLocationRelativeTo(null);  
           setVisible(true);  
      }  

How it works:
1) We use the sarxos library for webcam here
2) We create a webcam object and set the viewsize
3) We open the webcam using the open method
4) We take the image from webcam and store it into a BufferedImage object named img
5) Now we close the webcam and pass the image obtained in ImagePanel class which would then be added to Frame.
6) Now we show the frame to user with the webcam image which will be processed.

detectFace method:
      public void detectFace(){  
           JFrame fr=new JFrame("Discovered Faces");  
           faces = detector.detectFaces(ImageUtilities.createFImage(img));  
           if (faces == null) {  
                System.out.println("No faces found in the captured image");  
                return;  
           }  
           Iterator<DetectedFace> dfi = faces.iterator();  
           while (dfi.hasNext()) {  
                DetectedFace face = dfi.next();  
                FImage image1 = face.getFacePatch();  
                ImagePanel p=new ImagePanel(ImageUtilities.createBufferedImage(image1));  
                fr.add(p);  
           }  
           fr.setLayout(new FlowLayout(0));  
           fr.setSize(500,500);  
           fr.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);  
           fr.setVisible(true);  
      }  

How it works:
1) We use the openimaj library for face detection
2) We create a new Frame which would be showing up the results.
3) We make use of detectFaces method of HaarCascadeDetector class object detector, passing the image to be processed. ImageUtilities is used to create FImage out of BufferedImage.
4) If no face is found on image then an error message is returned.
5) Otherwise, we iterate through each face and retrieve the faces using getFacePatch method.
6) Again we use the createBufferedImage method of ImageUtilities class to get a BufferedImage out of FImage.
7) We add all the faces to the resulting frame.

ImagePanel Class:
 package com.cooltrickshome;  
 import java.awt.Dimension;  
 import java.awt.Graphics;  
 import java.awt.Image;  
 import javax.swing.ImageIcon;  
 import javax.swing.JPanel;  
 class ImagePanel  
  extends JPanel  
 {  
  private Image img;  
  public ImagePanel(String img)  
  {  
   this(new ImageIcon(img).getImage());  
  }  
  public ImagePanel(Image img)  
  {  
   this.img = img;  
   Dimension size = new Dimension(img.getWidth(null), img.getHeight(null));  
   setPreferredSize(size);  
   setMinimumSize(size);  
   setMaximumSize(size);  
   setSize(size);  
   setLayout(null);  
  }  
  public void paintComponent(Graphics g)  
  {  
   g.drawImage(this.img, 0, 0, null);  
  }  
 }  

How it works:
1) This is used to show the image over a panel

Output:


Full Program:


FaceDetector.java
 package com.cooltrickshome;  
 /**  
  * Reference:  
  * https://github.com/sarxos/webcam-capture/tree/master/webcam-capture-examples/webcam-capture-detect-face  
  * http://openimaj.org/  
  */  
 import java.awt.FlowLayout;  
 import java.awt.image.BufferedImage;  
 import java.io.IOException;  
 import java.util.Iterator;  
 import java.util.List;  
 import javax.swing.JFrame;  
 import org.openimaj.image.FImage;  
 import org.openimaj.image.ImageUtilities;  
 import org.openimaj.image.processing.face.detection.DetectedFace;  
 import org.openimaj.image.processing.face.detection.HaarCascadeDetector;  
 import com.github.sarxos.webcam.Webcam;  
 import com.github.sarxos.webcam.WebcamResolution;  
 public class FaceDetector extends JFrame {  
      private static final long serialVersionUID = 1L;  
      private static final HaarCascadeDetector detector = new HaarCascadeDetector();  
      private Webcam webcam = null;  
      private BufferedImage img= null;  
      private List<DetectedFace> faces = null;  
      public FaceDetector() throws IOException {  
           webcam = Webcam.getDefault();  
           webcam.setViewSize(WebcamResolution.VGA.getSize());  
           webcam.open(true);  
           img=webcam.getImage();  
           webcam.close();  
           ImagePanel panel=new ImagePanel(img);  
           panel.setPreferredSize(WebcamResolution.VGA.getSize());  
           add(panel);  
           setTitle("Face Recognizer");  
           setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);  
           pack();  
           setLocationRelativeTo(null);  
           setVisible(true);  
      }  
      public void detectFace(){  
           JFrame fr=new JFrame("Discovered Faces");  
           faces = detector.detectFaces(ImageUtilities.createFImage(img));  
           if (faces == null) {  
                System.out.println("No faces found in the captured image");  
                return;  
           }  
           Iterator<DetectedFace> dfi = faces.iterator();  
           while (dfi.hasNext()) {  
                DetectedFace face = dfi.next();  
                FImage image1 = face.getFacePatch();  
                ImagePanel p=new ImagePanel(ImageUtilities.createBufferedImage(image1));  
                fr.add(p);  
           }  
           fr.setLayout(new FlowLayout(0));  
           fr.setSize(500,500);  
           fr.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);  
           fr.setVisible(true);  
      }  
      public static void main(String[] args) throws IOException {  
           new FaceDetector().detectFace();  
      }  
 }  

ImagePanel.java
 package com.cooltrickshome;  
 import java.awt.Dimension;  
 import java.awt.Graphics;  
 import java.awt.Image;  
 import javax.swing.ImageIcon;  
 import javax.swing.JPanel;  
 class ImagePanel  
  extends JPanel  
 {  
  private Image img;  
  public ImagePanel(String img)  
  {  
   this(new ImageIcon(img).getImage());  
  }  
  public ImagePanel(Image img)  
  {  
   this.img = img;  
   Dimension size = new Dimension(img.getWidth(null), img.getHeight(null));  
   setPreferredSize(size);  
   setMinimumSize(size);  
   setMaximumSize(size);  
   setSize(size);  
   setLayout(null);  
  }  
  public void paintComponent(Graphics g)  
  {  
   g.drawImage(this.img, 0, 0, null);  
  }  
 }  

Hope it helps :)

Friday, July 21, 2017

Some Image Based Exploits with their Prevention

Images can be used to run malicious scripts over browser and can also be used to download Trojans if not handled carefully by your website. Too much trust on user input can cause damage to your clients.

In this post, we will run malicious scripts using a simple image viewer functionality and lastly we will discuss on how we can resolve this.

Programming Language
HTML, PHP

Git Repository
https://github.com/csanuragjain/extra/tree/master/ImageExploit

Website
https://cooltrickshome.blogspot.in/2017/07/some-image-based-exploits-with-their.html

One of Image Vulnerability I reported:
https://hackerone.com/reports/221928

Scenario #1:
In this scenario, we will show how lacking Content-Type while displaying images can run malicious scripts.
 Malicious Image




















Description
1)  Right Click on above Image and then Choose Save Image As
2) Name it as exifxss.jpg and Save it.
3) Otherwise you can also get it from the git location.

showImage.php
 <?php  
 include('exifxss.jpg');  
 ?>  


Description
A simple php file which would be showing the above jpg file.

Output:
  1. When you access showImage.php on your browser, you will expect to see the image but instead you will see several pop up coming up.
  2. This happens since the php page is not setting the Content-Type which makes php show image as an HTML. Since Image has several alert messages so they start popping up.
  3. showImage.php need to make sure that it sets the correct Content-Type and also make sure that it does not set the user provided Content-Type.


Scenario #2:
In this scenario, we will show how simple looking image when downloaded can become an exploit.
Caution: This will run notepad, calc, msconfig, services.msc on your computer, although it won't perform anything malicious.

Malicious Image











Description
1)  Right Click on above Image and then Choose Save Image As
2) Name it as exifxss.bat and Save it.
3) Otherwise you can also get it from the git location.

showImage2.html
 <img src="image.bat" width=500 height=500/>  

Description
A simple HTML file showing the image image.bat

Output:

  1. On accessing the above HTML, you would see the bugs bunny image (nothing suspicious)
  2. Now right click on Image and save the image. It would be saved as image.bat
  3. On opening it the malicious payload gets executed opening up notepad, services.msc, msconfig, calc.
  4. To prevent it, make sure that users are never allowed to store any non image extension file.
Please let me know your suggestions and comments.
Hope it helps :)

Saturday, July 8, 2017

Create Image Thumbnails using Java

In this post we will learn how we can utilize java to automatically creates thumbnails for existing images with desired thumbnail scaling.

Programming Language:
Java

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

Tutorial Location:
https://cooltrickshome.blogspot.in/2017/07/create-image-thumbnails-using-java.html

Program:

main method:

1
2
3
4
5
6
7
8
 public static void main(String[] args) {
  // TODO Auto-generated method stub
  Scanner s =new Scanner(System.in);
  System.out.println("Enter the path of image whose thumbnail need to be generated");
  String imgPath=s.nextLine();
  File thumnailImg=createThumbnail(new File(imgPath), 400, 400);
  System.out.println("Thumbnail generated at "+thumnailImg.getAbsolutePath());
 }

How it works:
1) A scanner object is created to take user input.
2) Image location for which thumbnail need to be generated is taken using the scanner object
3) We call the createThumbnail function (will create this) passing the image and the required thumbnail width and height.
4) createThumbnail returns the File object pointing to the generated thumbnail which is now shown to user.

createThumbnail method:
 /**
  * Creates a thumnail of provided image
  * @param inputImgFile The input image file
  * @param thumnail_width Desired width of the output thumbnail
  * @param thumbnail_height Desired height of thr output thumnail
  */
 public static File createThumbnail(File inputImgFile, int thumnail_width, int thumbnail_height){
  File outputFile=null;
  try {
  BufferedImage img = new BufferedImage(thumnail_width, thumbnail_height, BufferedImage.TYPE_INT_RGB);
  img.createGraphics().drawImage(ImageIO.read(inputImgFile).getScaledInstance(thumnail_width, thumbnail_height, Image.SCALE_SMOOTH),0,0,null);
  outputFile=new File(inputImgFile.getParentFile()+File.separator+"thumnail_"+inputImgFile.getName());
   ImageIO.write(img, "jpg", outputFile);
   return outputFile;
  } catch (IOException e) {
   System.out.println("Exception while generating thumbnail "+e.getMessage());
   return null;
  }
 }

How it works:
1) We use the ImageIO class to create a scaled version of the input image using the predefined getScaledInstance method passing the desired thumbnail width and height
2) We pass the Image from Step1 into a BufferedImage object
3) Now we simply use the write method of ImageIO class to write the BufferedImage from Step2 into a jpg file and return a File object pointing to same.

Output:
 Enter the path of image whose thumbnail need to be generated  
 C:\images\extra\7.jpg  
 Thumbnail generated at C:\images\extra\thumnail_7.jpg  

Full Program:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
package com.cooltrickshome;

import java.awt.Image;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import java.util.Scanner;

import javax.imageio.ImageIO;

public class ThumbnailGenerator {

 /**
  * @param args
  */
 public static void main(String[] args) {
  // TODO Auto-generated method stub
  Scanner s =new Scanner(System.in);
  System.out.println("Enter the path of image whose thumbnail need to be generated");
  String imgPath=s.nextLine();
  File thumnailImg=createThumbnail(new File(imgPath), 400, 400);
  System.out.println("Thumbnail generated at "+thumnailImg.getAbsolutePath());
 }

 /**
  * Creates a thumnail of provided image
  * @param inputImgFile The input image file
  * @param thumnail_width Desired width of the output thumbnail
  * @param thumbnail_height Desired height of thr output thumnail
  */
 public static File createThumbnail(File inputImgFile, int thumnail_width, int thumbnail_height){
  File outputFile=null;
  try {
  BufferedImage img = new BufferedImage(thumnail_width, thumbnail_height, BufferedImage.TYPE_INT_RGB);
  img.createGraphics().drawImage(ImageIO.read(inputImgFile).getScaledInstance(thumnail_width, thumbnail_height, Image.SCALE_SMOOTH),0,0,null);
  outputFile=new File(inputImgFile.getParentFile()+File.separator+"thumnail_"+inputImgFile.getName());
   ImageIO.write(img, "jpg", outputFile);
   return outputFile;
  } catch (IOException e) {
   System.out.println("Exception while generating thumbnail "+e.getMessage());
   return null;
  }
 }
}

Hope it helps :)

Saturday, May 27, 2017

Convert JSON to XML using Java

This post will discuss on how you can convert json to xml using Java.

Language Used:
Java

Pom Dependency:
 <!-- https://mvnrepository.com/artifact/org.json/json -->  
 <dependency>  
   <groupId>org.json</groupId>  
   <artifactId>json</artifactId>  
   <version>20170516</version>  
 </dependency>  

Git Repo:
https://github.com/csanuragjain/extra/tree/master/convertJson2XML

Program:

main method:
      public static void main(String[] args) {  
           // TODO Auto-generated method stub  
           String jsonString="{\"name\":\"Virat\",\"sport\":\"cricket\",\"age\":25,\"id\":121,\"lastScores\":[72,23,57,54,36,74,17]}";  
           System.out.println(new Json2XML().json2XML(jsonString));  
      }  

How it works:
1) We call the method json2XML which we created passing the json to be converted
2) The return value of function contains the resulting xml

json2XML method:
      public String json2XML(String jsonString){  
           JSONObject json = new JSONObject(jsonString);  
           String xml = XML.toString(json);  
           return xml;  
      }  

How it works:
1) We pass the Json String to be converted into the JSONObject
2) We use the toString method of XML class passing the json object created in Step1
3) Step2 gives the resulting xml which is then returned.
4) If you want to give a root node for resulting xml then you can provide the root xml node as second argument in toString method from Step2

Full Program:
 package com.cooltrickshome;  
 import org.json.JSONObject;  
 import org.json.XML;  
 public class Json2XML {  
      /**  
       * @param args  
       */  
      public static void main(String[] args) {  
           // TODO Auto-generated method stub  
           String jsonString="{\"name\":\"Virat\",\"sport\":\"cricket\",\"age\":25,\"id\":121,\"lastScores\":[72,23,57,54,36,74,17]}";  
           System.out.println(new Json2XML().json2XML(jsonString));  
      }  
      public String json2XML(String jsonString){  
           JSONObject json = new JSONObject(jsonString);  
           String xml = XML.toString(json);  
           return xml;  
      }  
 }  

Input:
{"name":"Virat","sport":"cricket","age":25,"id":121,"lastScores":[77,72,23,57,54,36,74,17]}

Output:

<name>Virat</name><lastScores>77</lastScores><lastScores>72</lastScores><lastScores>23</lastScores><lastScores>57</lastScores><lastScores>54</lastScores><lastScores>36</lastScores><lastScores>74</lastScores><lastScores>17</lastScores><id>121</id><sport>cricket</sport><age>25</age>

Hope it helps :)

Friday, May 26, 2017

Convert Json to POJO using Java

If you have a json which you want to map into POJO without writing the full POJO class then you can make use of jsonschema2pojo library. This is an excellent library which would create Java classes using your input JSON

Program Language
Java

Pom Dependency
     <dependency>  
       <groupId>org.jsonschema2pojo</groupId>  
       <artifactId>jsonschema2pojo-core</artifactId>  
       <version>0.4.35</version>  
     </dependency>  

Git Repo:
https://github.com/csanuragjain/extra/tree/master/convertJson2Pojo

Program

main method:
      public static void main(String[] args) {  
           String packageName="com.cooltrickshome";  
           File inputJson= new File("."+File.separator+"input.json");  
           File outputPojoDirectory=new File("."+File.separator+"convertedPojo");  
           outputPojoDirectory.mkdirs();  
           try {  
                new JsonToPojo().convert2JSON(inputJson.toURI().toURL(), outputPojoDirectory, packageName, inputJson.getName().replace(".json", ""));  
           } catch (IOException e) {  
                // TODO Auto-generated catch block  
                System.out.println("Encountered issue while converting to pojo: "+e.getMessage());  
                e.printStackTrace();  
           }  
      }  


How it works:
1)  packageName defines the package name of the output pojo class
2) inputJson defines the json which need to be converted to POJO
3) outputPojoDirectory is the local path where pojo files would be created
4) We call the convert2JSON method which we created passing the input json, output path, packageName and the output pojo class name

convert2JSON method:
      public void convert2JSON(URL inputJson, File outputPojoDirectory, String packageName, String className) throws IOException{  
           JCodeModel codeModel = new JCodeModel();  
           URL source = inputJson;  
           GenerationConfig config = new DefaultGenerationConfig() {  
           @Override  
           public boolean isGenerateBuilders() { // set config option by overriding method  
           return true;  
           }  
           public SourceType getSourceType(){  
       return SourceType.JSON;  
     }  
           };  
           SchemaMapper mapper = new SchemaMapper(new RuleFactory(config, new Jackson2Annotator(config), new SchemaStore()), new SchemaGenerator());  
           mapper.generate(codeModel, className, packageName, source);  
           codeModel.build(outputPojoDirectory);  
      }  

How it works:
1)  We make object of JCodeModel which will be used to generate Java class
2) We define the configuration for jsonschema2pojo which lets the program know get input source file is JSON (getSourceType method)
3)  Now we pass the config to Schemamapper along with the codeModel created in Step1 which creates the JavaType from provided Json
4) Finally we call the build method to create the output class

Full Program:
 package com.cooltrickshome;  
 import java.io.File;  
 import java.io.IOException;  
 import java.net.MalformedURLException;  
 import java.net.URL;  
 import org.jsonschema2pojo.DefaultGenerationConfig;  
 import org.jsonschema2pojo.GenerationConfig;  
 import org.jsonschema2pojo.Jackson2Annotator;  
 import org.jsonschema2pojo.SchemaGenerator;  
 import org.jsonschema2pojo.SchemaMapper;  
 import org.jsonschema2pojo.SchemaStore;  
 import org.jsonschema2pojo.SourceType;  
 import org.jsonschema2pojo.rules.RuleFactory;  
 import com.sun.codemodel.JCodeModel;  
 public class JsonToPojo {  
      /**  
       * @param args  
       */  
      public static void main(String[] args) {  
           String packageName="com.cooltrickshome";  
           File inputJson= new File("."+File.separator+"input.json");  
           File outputPojoDirectory=new File("."+File.separator+"convertedPojo");  
           outputPojoDirectory.mkdirs();  
           try {  
                new JsonToPojo().convert2JSON(inputJson.toURI().toURL(), outputPojoDirectory, packageName, inputJson.getName().replace(".json", ""));  
           } catch (IOException e) {  
                // TODO Auto-generated catch block  
                System.out.println("Encountered issue while converting to pojo: "+e.getMessage());  
                e.printStackTrace();  
           }  
      }  
      public void convert2JSON(URL inputJson, File outputPojoDirectory, String packageName, String className) throws IOException{  
           JCodeModel codeModel = new JCodeModel();  
           URL source = inputJson;  
           GenerationConfig config = new DefaultGenerationConfig() {  
           @Override  
           public boolean isGenerateBuilders() { // set config option by overriding method  
           return true;  
           }  
           public SourceType getSourceType(){  
       return SourceType.JSON;  
     }  
           };  
           SchemaMapper mapper = new SchemaMapper(new RuleFactory(config, new Jackson2Annotator(config), new SchemaStore()), new SchemaGenerator());  
           mapper.generate(codeModel, className, packageName, source);  
           codeModel.build(outputPojoDirectory);  
      }  
 }  

Input Json:
 {"name":"Virat","sport":"cricket","age":25,"id":121,"lastScores":[77,72,23,57,54,36,74,17]}  

Output Class generated:
 package com.cooltrickshome;  
 import java.util.ArrayList;  
 import java.util.HashMap;  
 import java.util.List;  
 import java.util.Map;  
 import com.fasterxml.jackson.annotation.JsonAnyGetter;  
 import com.fasterxml.jackson.annotation.JsonAnySetter;  
 import com.fasterxml.jackson.annotation.JsonIgnore;  
 import com.fasterxml.jackson.annotation.JsonInclude;  
 import com.fasterxml.jackson.annotation.JsonProperty;  
 import com.fasterxml.jackson.annotation.JsonPropertyOrder;  
 import org.apache.commons.lang.builder.EqualsBuilder;  
 import org.apache.commons.lang.builder.HashCodeBuilder;  
 import org.apache.commons.lang.builder.ToStringBuilder;  
 @JsonInclude(JsonInclude.Include.NON_NULL)  
 @JsonPropertyOrder({  
   "name",  
   "sport",  
   "age",  
   "id",  
   "lastScores"  
 })  
 public class Input {  
   @JsonProperty("name")  
   private String name;  
   @JsonProperty("sport")  
   private String sport;  
   @JsonProperty("age")  
   private Integer age;  
   @JsonProperty("id")  
   private Integer id;  
   @JsonProperty("lastScores")  
   private List<Integer> lastScores = new ArrayList<Integer>();  
   @JsonIgnore  
   private Map<String, Object> additionalProperties = new HashMap<String, Object>();  
   @JsonProperty("name")  
   public String getName() {  
     return name;  
   }  
   @JsonProperty("name")  
   public void setName(String name) {  
     this.name = name;  
   }  
   public Input withName(String name) {  
     this.name = name;  
     return this;  
   }  
   @JsonProperty("sport")  
   public String getSport() {  
     return sport;  
   }  
   @JsonProperty("sport")  
   public void setSport(String sport) {  
     this.sport = sport;  
   }  
   public Input withSport(String sport) {  
     this.sport = sport;  
     return this;  
   }  
   @JsonProperty("age")  
   public Integer getAge() {  
     return age;  
   }  
   @JsonProperty("age")  
   public void setAge(Integer age) {  
     this.age = age;  
   }  
   public Input withAge(Integer age) {  
     this.age = age;  
     return this;  
   }  
   @JsonProperty("id")  
   public Integer getId() {  
     return id;  
   }  
   @JsonProperty("id")  
   public void setId(Integer id) {  
     this.id = id;  
   }  
   public Input withId(Integer id) {  
     this.id = id;  
     return this;  
   }  
   @JsonProperty("lastScores")  
   public List<Integer> getLastScores() {  
     return lastScores;  
   }  
   @JsonProperty("lastScores")  
   public void setLastScores(List<Integer> lastScores) {  
     this.lastScores = lastScores;  
   }  
   public Input withLastScores(List<Integer> lastScores) {  
     this.lastScores = lastScores;  
     return this;  
   }  
   @Override  
   public String toString() {  
     return ToStringBuilder.reflectionToString(this);  
   }  
   @JsonAnyGetter  
   public Map<String, Object> getAdditionalProperties() {  
     return this.additionalProperties;  
   }  
   @JsonAnySetter  
   public void setAdditionalProperty(String name, Object value) {  
     this.additionalProperties.put(name, value);  
   }  
   public Input withAdditionalProperty(String name, Object value) {  
     this.additionalProperties.put(name, value);  
     return this;  
   }  
   @Override  
   public int hashCode() {  
     return new HashCodeBuilder().append(name).append(sport).append(age).append(id).append(lastScores).append(additionalProperties).toHashCode();  
   }  
   @Override  
   public boolean equals(Object other) {  
     if (other == this) {  
       return true;  
     }  
     if ((other instanceof Input) == false) {  
       return false;  
     }  
     Input rhs = ((Input) other);  
     return new EqualsBuilder().append(name, rhs.name).append(sport, rhs.sport).append(age, rhs.age).append(id, rhs.id).append(lastScores, rhs.lastScores).append(additionalProperties, rhs.additionalProperties).isEquals();  
   }  
 }  

Hope it helps :)

Tuesday, April 4, 2017

Java Reflection- Accessing/Modifying private methods/fields

In this post we would access and modify private methods and fields from a class using Java Reflection. This operation wont be possible normally with Java.

Language Used:
Java

Focus Area:
  1. Access a method from a class having private constructor.
  2. Access a private method
  3. Access/Modify a private variable
Git Repo:
https://github.com/csanuragjain/extra/tree/master/ReflectionAccessModifyPrivateData

Related:
https://cooltrickshome.blogspot.in/2017/02/java-reflection-reading-unknown-class.html

Program:

Unknown2.java:
 package com.cooltrickshome;  
 public class Unknown2 {  
      private final String msg="This is final string from private variable";  
      private Unknown2(){  
      }  
      private String privateWelcome(String message)  
      {  
           message=message+" processed by private method";  
           return message;  
      }  
      public void showMessage(){  
           System.out.println("I should not be called since this class constructor is private");  
      }  
 }  

Explanation:
  1. This class has a private variable which is also final. So any other class should not ideally be able to access or modify it.
  2. The constructor of this class is private so you should not be able to create an instance of this class. Because of this we should not be able to call showMessage function.
  3. Method privateWelcome is private so another class should not be able to call this method.

AccessPrivateData.java
 package com.cooltrickshome;  
 import java.lang.reflect.Constructor;  
 import java.lang.reflect.Field;  
 import java.lang.reflect.Method;  
 public class AccessPrivateData {  
      public static void main(String[] args) throws Exception {  
           Class c=Class.forName("com.cooltrickshome.Unknown2");  
           //Class<Unknown2> c=Unknown2.class;  
           Constructor<Unknown2> constr=c.getDeclaredConstructor();  
           constr.setAccessible(true);  
           Unknown2 s=(Unknown2)constr.newInstance();   
           System.out.println("Calling method from class with private constructor:");  
           s.showMessage();   
           System.out.println();  
           Field field = c.getDeclaredField("msg");  
           field.setAccessible(true);  
           System.out.println("Calling private field:");  
           System.out.println(field.get(s));  
           System.out.println();  
           System.out.println("Changing a final variable value:");  
           field.set(s, "I have change a private final variable");  
           System.out.println(field.get(s));  
           System.out.println();  
           Method m= c.getDeclaredMethod("privateWelcome", String.class);  
           m.setAccessible(true);  
           Object o=m.invoke(s, "Calling private method");  
           System.out.println("Calling private method:");  
           System.out.println(o);  
      }  
 }  

Explanation:
  1. We will bypass all the constraint and access all the private data from Unknown2 class
  2. First we reference our Unknown2 class by using Class.forName passing the class to be accessed along with package name.
  3. Now we obtain the constructor of Unknown2 class by callling the getDeclaredConstructor method
  4. Since this contructor is private, so we remove the constraint by setting setAccessible as true
  5. Now we can create a new instance using newInstance method.
  6. Since an instance is ready so we can simply call the showMessage method
  7. Now lets access the private variable
  8. We obtain the private variable of Unknown2 class by calling getDeclaredField passing the field name.
  9. We call setAccessible to true on this field so that we can access this field even though it is private.
  10. Now we can retrieve this field value by simply calling get method passing the class instance object.
  11. Now lets change the final field value.
  12. Since this field setAccessible is already set to true earlier, we simply call the set method passing the Unknown2 class object and the new field value.
  13. Now lets access the private method.
  14. We obtain the private method by calling the getDeclaredMethod passing the private method name nd the type of argument it accepts (in our case the method needs a String)
  15. We call setAccessible to true on this method so that we can access this method even though it is private.
  16. We call the method by using invoke method, passing an instance of this class and the argument value.


Output:
 Calling method from class with private constructor:  
 I should not be called since this class constructor is private  
 Calling private field:  
 This is final string from private variable  
 Changing a final variable value:  
 I have change a private final variable  
 Calling private method:  
 Calling private method processed by private method  


Hope it helps :)

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 :)

Sunday, February 26, 2017

Java Reflection- Reading unknown class file

Java Reflection allows you to inspect interfaces, fields and methods from a known or an unknown class. It also allows you to call methods from these unknown class which otherwise wont be possible.
This post is for inspecting class , methods, constructors, fields from an unknown class. In the next post, I would be sharing on how you could utilize and execute those retrieved methods.

Reference:
http://stackoverflow.com/questions/37628/what-is-reflection-and-why-is-it-useful
http://www.javatpoint.com/java-reflection
http://tutorials.jenkov.com/java-reflection/index.html
http://www.oracle.com/technetwork/articles/java/javareflection-1536171.html

Language Used:
Java

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

Related:
https://cooltrickshome.blogspot.in/2017/04/java-reflection-accessingmodifying.html

Pre-requisite:

1) We have a class file named Unknown.class.
2) Unknown.class is the compiled class file and contains the byte code
3) You cannot check the methods and fields from this class unless you deobfuscate the java file
4) You cannot directly call the methods from this class in Eclipse unless and until you copy the java source code which you obtained by deobfuscating this class into a new java file in eclipse. (Or you use Reflection, which we will see :) )

Program:

Obtaining the real class name from Unknown.class:
      public static void main(String[] args) {  
           ClassLoader cl;  
           Class c;  
           try {  
           File file = new File(".");  
           URL url = file.toURL();  
        URL[] urls = new URL[]{url};  
        cl = new URLClassLoader(urls);  
        c = cl.loadClass("Unknown");  
        System.out.println(c.isInterface());   
           } catch (ClassNotFoundException e) {  
                System.out.println("Requested class was not found "+e.getMessage());  
           } catch (MalformedURLException e) {  
                System.out.println("Given class file url was not found "+e.getMessage());  
           }  
      }  

Output:

How it works:
1) We place the Unknown.class in the current project directory.
2) We make a File object which points to the directory where Unknown.class is present. Since it is present in current directory we keep path as '.'
3) We make a URL object using the above File object and then pass this object in a URL array.
4) We use URLClassLoader to load the class from the URL we created.
5) We retrieve the class instance using loadClass
6) isInterface method tells if Unknown.class is an interface
7) When we run this class we get an error wrong name: com/cooltrickshome/completed/RunExternalProgram
8) This tells that real name of Unknown.class is RunExternalProgram.class and its part of package com.cooltrickshome.completed.RunExternalProgram
9) After knowing this, we create folders com/cooltrickshome/completed inside the current project directory (why: refer step 2)
10) We rename Unknown.class to RunExternalProgram.class and place it inside com/cooltrickshome/completed folder
11) Finally we change loadClass to cl.loadClass("com.cooltrickshome.completed.RunExternalProgram");
12) Folder structure finally becomes ./com/cooltrickshome/completed/RunExternalProgram.class

Obtaining the method name from this class file:
      public void printMethods(Class c) {  
           // Getting all the methods  
           System.out.println("\nMethods of this class");  
           Method methlist[] = c.getDeclaredMethods();  
           for (int i = 0; i < methlist.length; i++) {  
                Method m = methlist[i];  
                System.out.println(m.toString());  
                System.out.println("Method Name: " + m.getName());  
                System.out.println("Declaring Class: " + m.getDeclaringClass());  
                Class param[] = m.getParameterTypes();  
                for (int j = 0; j < param.length; j++)  
                     System.out.println("Param #" + j + ": " + param[j]);  
                Class exec[] = m.getExceptionTypes();  
                for (int j = 0; j < exec.length; j++)  
                     System.out.println("Exception thrown by method #" + j + ": "  
                               + exec[j]);  
                System.out.println("Method Return type: " + m.getReturnType());  
                System.out  
                          .println("--------------------------------------------------\n");  
           }  
      }  

Output:
 Methods of this class  
 public static void com.cooltrickshome.completed.RunExternalProgram.main(java.lang.String[]) throws java.lang.InterruptedException,java.io.IOException  
 Method Name: main  
 Declaring Class: class com.cooltrickshome.completed.RunExternalProgram  
 Param #0: class [Ljava.lang.String;  
 Exception thrown by method #0: class java.lang.InterruptedException  
 Exception thrown by method #1: class java.io.IOException  
 Method Return type: void  
 --------------------------------------------------  
 public int com.cooltrickshome.completed.RunExternalProgram.getCounter(int)  
 Method Name: getCounter  
 Declaring Class: class com.cooltrickshome.completed.RunExternalProgram  
 Param #0: int  
 Method Return type: int  
 --------------------------------------------------  
 public void com.cooltrickshome.completed.RunExternalProgram.runProgram(java.lang.String[]) throws java.lang.InterruptedException,java.io.IOException  
 Method Name: runProgram  
 Declaring Class: class com.cooltrickshome.completed.RunExternalProgram  
 Param #0: class [Ljava.lang.String;  
 Exception thrown by method #0: class java.lang.InterruptedException  
 Exception thrown by method #1: class java.io.IOException  
 Method Return type: void  
 --------------------------------------------------  
 public void com.cooltrickshome.completed.RunExternalProgram.incrementCounter(int)  
 Method Name: incrementCounter  
 Declaring Class: class com.cooltrickshome.completed.RunExternalProgram  
 Param #0: int  
 Method Return type: void  
 --------------------------------------------------  

How it works:
1) getDeclaredMethods is used to retrieve the methods from the class passed in argument
2) We iterate through each method in a for loop
3) toString method of this method will print the full function prototype
4) getName is used to print the method name
5) getDeclaringClass is used to print the declaring class
6) getParameterTypes is used to retrieve the parameters type used by this method
7) getExceptionTypes is used to find the exception which this method throws
8) getReturnType is used to retrieve the return type of this method.

Obtaining the Constructors from the class file:
      public void printConstructor(Class c) {  
           // Getting all the constructor  
           System.out.println("Constructor of this class");  
           Constructor[] constlist = c.getDeclaredConstructors();  
           for (int i = 0; i < constlist.length; i++) {  
                Constructor m = constlist[i];  
                System.out.println(m.toString());  
                System.out.println("Method Name: " + m.getName());  
                System.out.println("Declaring Class: " + m.getDeclaringClass());  
                Class param[] = m.getParameterTypes();  
                for (int j = 0; j < param.length; j++)  
                     System.out.println("Param #" + j + ": " + param[j]);  
                Class exec[] = m.getExceptionTypes();  
                for (int j = 0; j < exec.length; j++)  
                     System.out.println("Exception thrown by method #" + j + ": "  
                               + exec[j]);  
                System.out  
                          .println("--------------------------------------------------\n");  
           }  
      }  

Output:
 Constructor of this class  
 public com.cooltrickshome.completed.RunExternalProgram()  
 Method Name: com.cooltrickshome.completed.RunExternalProgram  
 Declaring Class: class com.cooltrickshome.completed.RunExternalProgram  
 --------------------------------------------------  
 public com.cooltrickshome.completed.RunExternalProgram(int)  
 Method Name: com.cooltrickshome.completed.RunExternalProgram  
 Declaring Class: class com.cooltrickshome.completed.RunExternalProgram  
 Param #0: int  
 --------------------------------------------------  

How it works:
1) getDeclaredConstructors is used to retrieve the constructors from the class passed in argument
2) We iterate through each constructor in a for loop
3) toString method will print the full constructor prototype
4) getName is used to print the constructor name
5) getDeclaringClass is used to print the declaring class
6) getParameterTypes is used to retrieve the parameters type used by this constructor 
7) getExceptionTypes is used to find the exception which this constructor throws

Obtaining the variables from the class file:
 public void printFields(Class c)  
      {  System.out.println("Variables of this class");
           Field fieldlist[]   
             = c.getDeclaredFields();  
            for (int i   
             = 0; i < fieldlist.length; i++) {  
              Field fld = fieldlist[i];  
              System.out.println("Variable name: " + fld.getName());  
              System.out.println("Declaring class: " +fld.getDeclaringClass());  
              System.out.println("Variable type: " + fld.getType());  
              int mod = fld.getModifiers();  
              System.out.println("Modifiers = " +Modifier.toString(mod));  
              System.out.println("--------------------------------");  
            }  
      }  

Output:
 Variables of this class  
 Variable name: counter  
 Declaring class: class com.cooltrickshome.completed.RunExternalProgram  
 Variable type: int  
 Modifiers = private  
 --------------------------------------------------  

How it works:
1) getDeclaredFields is used to retrieve the variables from the class passed in argument
2) We iterate through each variable in a for loop
3) getName is used to print the variable name
4) getDeclaringClass is used to print the declaring class
5) getParameterTypes is used to retrieve the variable type used by this variable 
7) getModifiers() retrieve the modifier of this variable.

Full Program : (Available from git location)

RunExternalProgram.class:
Placed at <current project directory>/cooltrickshome/completed/RunExternalProgram.class

ReflectionReadApi.java:
 package com.cooltrickshome;  
 import java.io.File;  
 import java.lang.reflect.Constructor;  
 import java.lang.reflect.Field;  
 import java.lang.reflect.Method;  
 import java.lang.reflect.Modifier;  
 import java.net.MalformedURLException;  
 import java.net.URL;  
 import java.net.URLClassLoader;  
 public class ReflectionReadApi {  
      /**  
       * @param args  
       * @throws ClassNotFoundException  
       */  
      public static void main(String[] args) {  
           ClassLoader cl;  
           Class c;  
           try {  
                File file = new File(".");  
                URL url = file.toURL();  
                URL[] urls = new URL[] { url };  
                cl = new URLClassLoader(urls);  
                c = cl.loadClass("com.cooltrickshome.completed.RunExternalProgram");  
                System.out.println("\nName of class is " + c.getName());  
                ReflectionReadApi ra = new ReflectionReadApi();  
                ra.printMethods(c);  
                ra.printConstructor(c);  
                ra.printFields(c);  
           } catch (ClassNotFoundException e) {  
                System.out.println("Requested class was not found "  
                          + e.getMessage());  
           } catch (MalformedURLException e) {  
                System.out.println("Given class file url was not found "  
                          + e.getMessage());  
           }  
      }  
      public void printMethods(Class c) {  
           // Getting all the methods  
           System.out.println("\nMethods of this class");  
           Method methlist[] = c.getDeclaredMethods();  
           for (int i = 0; i < methlist.length; i++) {  
                Method m = methlist[i];  
                System.out.println(m.toString());  
                System.out.println("Method Name: " + m.getName());  
                System.out.println("Declaring Class: " + m.getDeclaringClass());  
                Class param[] = m.getParameterTypes();  
                for (int j = 0; j < param.length; j++)  
                     System.out.println("Param #" + j + ": " + param[j]);  
                Class exec[] = m.getExceptionTypes();  
                for (int j = 0; j < exec.length; j++)  
                     System.out.println("Exception thrown by method #" + j + ": "  
                               + exec[j]);  
                System.out.println("Method Return type: " + m.getReturnType());  
                System.out  
                          .println("--------------------------------------------------\n");  
           }  
      }  
      public void printConstructor(Class c) {  
           // Getting all the constructor  
           System.out.println("Constructor of this class");  
           Constructor[] constlist = c.getDeclaredConstructors();  
           for (int i = 0; i < constlist.length; i++) {  
                Constructor m = constlist[i];  
                System.out.println(m.toString());  
                System.out.println("Method Name: " + m.getName());  
                System.out.println("Declaring Class: " + m.getDeclaringClass());  
                Class param[] = m.getParameterTypes();  
                for (int j = 0; j < param.length; j++)  
                     System.out.println("Param #" + j + ": " + param[j]);  
                Class exec[] = m.getExceptionTypes();  
                for (int j = 0; j < exec.length; j++)  
                     System.out.println("Exception thrown by method #" + j + ": "  
                               + exec[j]);  
                System.out  
                          .println("--------------------------------------------------\n");  
           }  
      }  
      public void printFields(Class c)  
      {  
           System.out.println("Variables of this class");  
           Field fieldlist[]   
             = c.getDeclaredFields();  
            for (int i   
             = 0; i < fieldlist.length; i++) {  
              Field fld = fieldlist[i];  
              System.out.println("Variable name: " + fld.getName());  
              System.out.println("Declaring class: " +fld.getDeclaringClass());  
              System.out.println("Variable type: " + fld.getType());  
              int mod = fld.getModifiers();  
              System.out.println("Modifiers = " +Modifier.toString(mod));  
              System.out.println("--------------------------------------------------\n");  
            }  
      }  
 }  

Output:
 Name of class is com.cooltrickshome.completed.RunExternalProgram  
 Methods of this class  
 public static void com.cooltrickshome.completed.RunExternalProgram.main(java.lang.String[]) throws java.lang.InterruptedException,java.io.IOException  
 Method Name: main  
 Declaring Class: class com.cooltrickshome.completed.RunExternalProgram  
 Param #0: class [Ljava.lang.String;  
 Exception thrown by method #0: class java.lang.InterruptedException  
 Exception thrown by method #1: class java.io.IOException  
 Method Return type: void  
 --------------------------------------------------  
 public void com.cooltrickshome.completed.RunExternalProgram.runProgram(java.lang.String[]) throws java.lang.InterruptedException,java.io.IOException  
 Method Name: runProgram  
 Declaring Class: class com.cooltrickshome.completed.RunExternalProgram  
 Param #0: class [Ljava.lang.String;  
 Exception thrown by method #0: class java.lang.InterruptedException  
 Exception thrown by method #1: class java.io.IOException  
 Method Return type: void  
 --------------------------------------------------  
 public int com.cooltrickshome.completed.RunExternalProgram.getCounter(int)  
 Method Name: getCounter  
 Declaring Class: class com.cooltrickshome.completed.RunExternalProgram  
 Param #0: int  
 Method Return type: int  
 --------------------------------------------------  
 public void com.cooltrickshome.completed.RunExternalProgram.incrementCounter(int)  
 Method Name: incrementCounter  
 Declaring Class: class com.cooltrickshome.completed.RunExternalProgram  
 Param #0: int  
 Method Return type: void  
 --------------------------------------------------  
 Constructor of this class  
 public com.cooltrickshome.completed.RunExternalProgram()  
 Method Name: com.cooltrickshome.completed.RunExternalProgram  
 Declaring Class: class com.cooltrickshome.completed.RunExternalProgram  
 --------------------------------------------------  
 public com.cooltrickshome.completed.RunExternalProgram(int)  
 Method Name: com.cooltrickshome.completed.RunExternalProgram  
 Declaring Class: class com.cooltrickshome.completed.RunExternalProgram  
 Param #0: int  
 --------------------------------------------------  
 Variables of this class  
 Variable name: counter  
 Declaring class: class com.cooltrickshome.completed.RunExternalProgram  
 Variable type: int  
 Modifiers = private  
 --------------------------------------------------  


Hope it helps :)