Se ha denunciado esta presentación.
Utilizamos tu perfil de LinkedIn y tus datos de actividad para personalizar los anuncios y mostrarte publicidad más relevante. Puedes cambiar tus preferencias de publicidad en cualquier momento.

College Project - Java Disassembler - Description

110 visualizaciones

Publicado el

Many students reach out to me asking for project ideas they can do as a summer project for learning. Here is an interesting project idea - implement your own java disassembler (and expand it to a VM later).

Publicado en: Software
  • Sé el primero en comentar

  • Sé el primero en recomendar esto

College Project - Java Disassembler - Description

  1. 1. © 2015. Copyright Ganesh Samarthyam. All Rights Reserved. Disassembler  for  Java  (with  API)     Many students contact me asking for project ideas. If you are a Bachelor or Master’s student in computer science/IT and looking for a good summer project idea, this is for you. You can complete this very interesting project in 2 months.   javap  is  a  Java  “disassembler”  tool  that  reads  the  Java  class  files  and  dumps  in  the  info  in  a  human  readable  form.   The  javap  is  tool  is  available  as  part  of  the  JDK  (Java  Development  Kit)  in  the  bin  directory  –  the  same  directory  in   which  the  javac  –  the  Java  compiler  is  available.       Java  programs  are  compiled  into  intermediate  code  known  as  byte  codes  and  are  stored  as  ".class"  files.  These   ".class"  files  have  these  byte  codes  and  more  -­‐  this  "additional"  information  is  known  as  metadata.  JVM  uses  these   byte  codes  and  metadata  to  execute  the  program.       Here  is  how  you  execute  the  tool  in  command-­‐line.  Consider  this  simple  program:     C:>  type  Hello.java     class  Hello  {   public  static  void  main(String  []args)  {   System.out.println("hello  world");   }   }         C:>  javap  -­‐c  Hello.class   Compiled  from  "Hello.java"   class  Hello  {      Hello();          Code:                0:  aload_0                              1:  invokespecial  #1                                    //  Method  java/lang/Object."<init>":()V                4:  return                        public  static  void  main(java.lang.String[]);          Code:                0:  getstatic          #2                                    //  Field  java/lang/System.out:Ljava/io/PrintStream;                3:  ldc                      #3                                    //  String  hello  world                5:  invokevirtual  #4                                    //  Method  java/io/PrintStream.println:(Ljava/lang/String;)V                8:  return                   }     Here  is  a  quick  intro  on  bytecodes.  The  intermediate  language  for  Java  is  byte-­‐codes.  They  are  assembly  language   code  for  a  imaginary  stack  based  machine  (that  is  the  reason  why  the  Java  runtime  is  called  as  a  ‘virtual  machine’).   The  size  of  an  instruction  is  one  byte,  and  hence  the  name  ‘byte  code’.       Let  us  take  a  simple  example  and  understand  how  the  bytecodes  work.  Here  is  the  code  that  swaps  values  of  two   integer  variables  named  x  and  y:       int  x  =  10,  y  =  20;   int  temp  =  x;   x  =  y;  
  2. 2. © 2015. Copyright Ganesh Samarthyam. All Rights Reserved. y  =  temp;     Here  is  the  generated  bytecode,  obtained  by  using  javap  tool:                  0:  bipush                10                2:  istore_1                3:  bipush                20                5:  istore_2                6:  iload_1                7:  istore_3                8:  iload_2                9:  istore_1              10:  iload_3              11:  istore_2       There  are  only  a  few  instructions  that  we  need  to  understand  to  interpret  how  this  instruction  sequence  works.   The  instruction  bipush  loads  (or  pushes)  the  argument  to  the  stack.  The  instruction  prefized  with  i  –  as  in  iload  and   istore  –  indicates  that  the  instruction  is  meant  for  integers  (remember  that  x  and  y  are  integers).  The  instructions   iload  and  istore  loads  and  stores  an  integer  to  and  from  the  ‘runtime  execution  stack’  and  ‘local  memory  area  in   the  stack’.  Here  the  suffix  _1  and  _2  indicates  the  first  two  local  variables  x  and  x;  the  suffix  _3  indicates  the   emporary  variable  temp.         Now  let  us  simulate  the  execution  of  instructions.  In  top  is  the  execution  stack  and  its  state;  in  the  bottom  is  the   value  for  memory  locations  x,  y,  and  temp  and  are  indicated  by  ‘_1’,  ‘_2’,  and  ‘_3’.        
  3. 3. © 2015. Copyright Ganesh Samarthyam. All Rights Reserved.     The  basic  unit  of  input  to  it  is  a  .java  file.  The  Java  compiler  is  no  different  from  compilers  of  other  languages  that  it   is  firmly  based  on  the  conventional  compiler  techniques,  but  the  code  it  generates  in  not  the  conventional  object   code  for  that  particular  platform  but  platform  independent  .class  file  that  is  generated  for  each  and  every  class  or   interface  defined.       Bytecodes  -­‐  the  instructions  for  a  hypothetical  microprocessor  -­‐  are  platform  independent  codes  that  form  the   basis  of  the  platform  independence  by  Java.  They  are  targeted  at  the  stack-­‐oriented  approach.  All  the  evaluation  is   done  in  the  stack  by  execution  of  the  byte  codes.  For  example,  given  the  integer  values  a  and  b,  the  statement:       b  =  a  +  10;     may  be  converted  to  Java  bytecodes  as  follows,     iload_1       //  stands  for  integer  load  the  first  local     //  variable  into  the  operand  stack   bipush  10   //  bipush  stands  for  push  ‘byte  integer’  10  into     //  the  operand  stack.   iadd     //  add  the  topmost  two  arguments  in  the  stack   istore_2     //  store  the  result  in  top  of  the  stack  to  the     //  second  variable  b         A  Java  compiler,  irrespective  of  the  machine  it  is  compiled,  generates  the  same  code.  All  the  information  that  you   give  inside  the  class  definition  are  converted  to  some  form  and  get  stored  to  form  the  .class  file  for  that   corresponding  class.     This  Intermediate  Class  File  Format  is  a  specification  given  by  Sun.  It  is  a  well  documented  format.  This  file  format   is  understood  by  the  Java  virtual  machine  that  operates  on  and  executes  it.  This  holds  the  information  like  the   methods  declared  along  with  the  byte  codes,  the  class  variables  used  along  with  initializing  values  (if  any),  super   class  information,  signatures  of  variables  and  methods,  etc.  This  is  similar  to  the  .EXE  code  that  is  organized  in  a   particular  format  that  could  be  understood  by  the  underlying  operating  system.  It  also  has  a  constant  pool  -­‐  a  per   class  runtime  data  structure,  which  is  similar  to  the  symbol  table  created  by  the  compiler.  The  Java  class  file  format   is  very  compact  and  plays  very  important  role  in  making  Java  platform  independent.       The  contents  of  a  .class  file  are  written  in  a  specific  file  format,  described  in  the  specification  of  the  Java  Virtual   Machine.  Don’t  worry,  we’re  not  going  to  understand  this  complex  file  format,  but  we’ll  just  check  its  “magic  
  4. 4. © 2015. Copyright Ganesh Samarthyam. All Rights Reserved. number”.  Each  file  format  has  a  “magic  number”  used  for  quickly  checking  the  file  format.  For  example  “.MZ”  is   the  magic  number  (or  more  properly,  “magic  string”)  for  “.exe”  files  in  Windows.  Similarly,  the  .class  files  have  the   magic  number  “0xCAFEBABE”  written  as  a  hexa  decimal  value.  These  magic  numbers  are  typically  written  as  first   few  bytes  of  a  variable  length  file  format.  Let  us  just  check  if  the  given  file  starts  with  the  magic  number   “0xCAFEBABE”  –  if  so,  it  could  be  a  valid  .class  file,  or  else  it’s  certainly  not  a  .class  file.         import  java.io.FileInputStream;   import  java.io.FileNotFoundException;   import  java.io.IOException;   import  java.util.Arrays;     //  check  if  the  passed  file  is  a  valid  .class  file  or  not.     //  note  that  this  is  an  elementary  version  of  a  checker  that  checks  if  the  given  file     //  is  a  valid  file  that  is  written  according  to  the  JVM  specification   //  it  checks  only  the  magic  number       class  ClassFileMagicNumberChecker  {     public  static  void  main(String  []args)  {       if(args.length  !=  1)  {         System.err.println("Pass  a  valid  file  name  as  argument");         System.exit(-­‐1);       }       String  fileName  =  args[0];       //  create  a  magicNumber  byte  array  with  values  for  four  bytes  in  0xCAFEBABE         //  you  need  to  have  an  explicit  down  cast  to  byte  since         //  the  hex  values  like  0xCA  are  of  type  int         byte  []magicNumber  =  {(byte)  0xCA,  (byte)0xFE,  (byte)0xBA,  (byte)0xBE};         try  (FileInputStream  fis  =  new  FileInputStream(fileName))  {         //  magic  number  is  of  4  bytes  –     //  use  a  temporary  buffer  to  read  first  four  bytes           byte[]  u4buffer  =  new  byte[4];           //  read  a  buffer  full  (4  bytes  here)  of  data  from  the  file           if(fis.read(u4buffer)  !=  -­‐1)  {  //  if  read  was  successful               //  the  overloaded  method  equals  for  two  byte  arrays     //  checks  for  equality  of  contents               if(Arrays.equals(magicNumber,  u4buffer))  {   System.out.printf("The  magic  number  for  passed  file  %s  matches  that   of  a  .class  file",  fileName);           }           else  {   System.out.printf("The  magic  number  for  passed  file  %s  does  not   match  that  of  a  .class  file",  fileName);           }         }       }  catch(FileNotFoundException  fnfe)  {         System.err.println("file  does  not  exist  with  the  given  file  name  ");       }  catch(IOException  ioe)  {   System.err.println("an  I/O  error  occurred  while  processing  the  file");       }     }   }     Let’s  first  see  if  it  works  by  passing  the  source  (.java)  file  and  the  .class  file  for  the  same  program:        
  5. 5. © 2015. Copyright Ganesh Samarthyam. All Rights Reserved.   D:>  java  ClassFileMagicNumberChecker  ClassFileMagicNumberChecker.java   The  magic  number  for  passed  file  ClassFileMagicNumberChecker.java  does  not  match  that  of  a  .class  file   D:>  java  ClassFileMagicNumberChecker  ClassFile   MagicNumberChecker.class   The  magic  number  for  passed  file  ClassFileMagicNumberChecker.class  matches  that  of  a  .class  file       You  need  to  extend  this  program  by  reading  the  file  format  and  print  the  content  in  a  readable  format.  The  output   should  be  same  as  the  javap  output.       Testcases:  Test  your  tool  implementation  by  disassembling  the  class  files  that  are  provided  as  part  of  the  Java   runtime  library  (i.e.,  test  your  tool  for  the  class  files  provided  within  “rt.jar”  file  that  is  available  as  part  of  the   JDK/JRE  folder).       Resources  for  the  project:     • Wikipedia  overview  page  for  the  Java  class  file  format:  http://en.wikipedia.org/wiki/Java_class_file   • Wikipedia  overview  page  for  Java  bytecodes:  http://en.wikipedia.org/wiki/Java_bytecode   • The  Java  class  file  format  is  documented  here:  http://docs.oracle.com/javase/specs/jvms/se7/html/jvms-­‐ 4.html#jvms-­‐4.4   • The  Java  Virtual  Machine  specification  book  is  available  for  download  for  free(!)  here:   http://docs.oracle.com/javase/specs/jvms/se7/jvms7.pdf  .  This  book  includes  the  specification  for  the   class  file  format.     Resources  for  learning  Java:     • If  you  are  new  to  Java,  you  can  get  started  from  here:   http://www.oracle.com/technetwork/topics/newtojava/overview/index.html • The  free  online  Oracle  Java  tutorial  is  an  excellent  resource  to  learn  Java:   http://docs.oracle.com/javase/tutorial/.  It  is  a  also  available  as  a  free  book  as  part  of  the  tutorial  bundle;   download  it  here:  http://download.oracle.com/javase/tutorial/   • When  you  are  learning  Java  and  writing  code,  you’ll  need  to  consult  the  API  of  the  Java  standard  library.   The  documentation  is  available  here:  http://download.oracle.com/javase/7/docs/api/   • “Head  first  Java”  by  Kathy  Sierra  and  Bert  Bates  is  a  fun  and  easy  book  to  learn  Java;  download  the  free  e-­‐ book  version  here:  http://it-­‐ebooks.info/book/255/.   • “Thinking  in  Java”  by  Bruce  Eckel  is  a  very  good  book  to  learn  Java  well.  Download  it  here:    http://www.mindviewinc.com/Books/downloads.html           • If  you  have  queries  or  doubts,  you  can  get  them  clarified  in  “Beginning  Java”  CodeRanch  forum:   http://www.coderanch.com/forums/f-­‐33/java  

×