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

Friday, February 17, 2017

Reading text from Images using Java

This post will help read texts from your images. It makes use of tessaract library.
You can also use the below module to check if the captcha on your site is strong enough and cannot be broken simply.

Reference:
https://github.com/tesseract-ocr/tessdata
http://stackoverflow.com/questions/18095708/tess4j-doesnt-use-its-tessdata-folder

Language Used:
Java

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

POM Dependency:
 <!-- https://mvnrepository.com/artifact/net.sourceforge.tess4j/tess4j -->  
 <dependency>  
   <groupId>net.sourceforge.tess4j</groupId>  
   <artifactId>tess4j</artifactId>  
   <version>3.2.1</version>  
 </dependency>  

Pre-requisite:
1) Assume you are running this program from c:\myprogram. Now you can follow either of 2 methods based on your requirements.

Space saving method: (You only download the language data which you need. Only require 30MB for a english dataset)
2) Create a folder named tessdata inside c:\myprogram\
3) Navigate to https://github.com/tesseract-ocr/tessdata
4) Download eng.traineddata for breaking captcha with english language (trained data are available for other languages as well)
5) Place the eng.traineddata inside tessdata folder.
6) Finally your folder structure should look like c:\myprogram\tessdata\eng.traineddata

Time saving method: (Download trained data from several languages and atleast cosumes 1GB space)
7) You can also skip Step 2 to Step 5 and simply download the tessdata-master folder from https://github.com/tesseract-ocr/tessdata
8) Unzip the content of tessdata-master.zip file in your main project folder (for eg here it is c:\myprogram\)
9) Rename tessdata-master to tessdata
10) Finally your folder structure should look like c:\myprogram\tessdata\<Trained data from several language>

Program:

ImageCracker class, crackImage method:
 public static String crackImage(String filePath) {  
     File imageFile = new File(filePath);  
     ITesseract instance = new Tesseract();  
     try {  
       String result = instance.doOCR(imageFile);  
       return result;  
     } catch (TesseractException e) {  
       System.err.println(e.getMessage());  
       return "Error while reading image";  
     }  
   }  

How it works:
1) crackImage takes the image which need to be read
2) We point a file object to that image
3) We make a Tessaract object named instance
4) We call the predefined method doOCR of Tessaract library passing the file object from step2
5) the doOCR method returns the text read from the image and returns the same.
6) In case of failure it prints the error message and returns a error string.

Driver class, main method:
 public static void main(String[] args) {  
           // TODO Auto-generated method stub  
           System.out.println(ImageCracker.crackImage("testImage.PNG"));  
      }  

How it works:
1) We call the crackImage method passing the image to be read from.
2) We print the text read from the method on the console.

Input Image (testImage.PNG):
Output:
Create a Youtube metadata crawler using Java

Full Program:

ImageCracker class
 package com.cooltrickshome;  
 import java.io.File;  
 import net.sourceforge.tess4j.*;  
 public class ImageCracker {  
   public static String crackImage(String filePath) {  
     File imageFile = new File(filePath);  
     ITesseract instance = new Tesseract();   
     try {  
       String result = instance.doOCR(imageFile);  
       return result;  
     } catch (TesseractException e) {  
       System.err.println(e.getMessage());  
       return "Error while reading image";  
     }  
   }  
 }  

Driver class:
 package com.cooltrickshome;  
 public class Driver {  
      /**  
       * @param args  
       */  
      public static void main(String[] args) {  
           // TODO Auto-generated method stub  
           System.out.println(ImageCracker.crackImage("testImage.PNG"));  
      }  
 }  

Hope it helps :)