PE-Viewer Project

From no name for this wiki
Jump to: navigation, search

The PE-Viewer project is about a java library to read .net assembly files. Documentation about that library can be found in this article. The project itself is hosted at http://pe-file-reader.dev.java.net. Go there to check out the source code.

Installation

Java Web Start

The user interface can be started via JavaWebStart. Click JNLP File.

Starting from jar

You can download the jar here: http://pe-file-reader.dev.java.net/files/documents/8202/80983/pe-file-reader.jar. The command is java -jar pe-file-reader.jar. The main class to start the gui is: org.dotnetjava.tools.viewer.MainFrame


Getting the source

See CVS in http://pe-file-reader.dev.java.net


Code samples

List Types and Methods

The following code reads the assembly sudokusolver.exe and lists all types and methods within that assembly to the console.

import java.io.IOException;
import java.util.Collection;
import org.dotnetjava.AssemblyFactory;
import org.dotnetjava.AssemblyFile;
import org.dotnetjava.DotNetMethodDef;
import org.dotnetjava.DotNetModule;
import org.dotnetjava.DotNetTypeDef;
import org.dotnetjava.file.InvalidPEFileException;
public class ListTypesSample {    
   /** Creates a new instance of ListTypesSample */
   public ListTypesSample() {
   }    
   public static void main(String[] args) {
       try {
           AssemblyFile assemblyFile = AssemblyFactory.readPeFile("sudokusolver.exe");            
           if(assemblyFile.isAssembly()){
               System.out.println("This is an assembly, not only a module");
           }                        
           DotNetModule module = assemblyFile.getDotNetMainModule();
           Collection<DotNetTypeDef> types = module.getTypeDefs();
           for(DotNetTypeDef type : types){                
               String name = type.getName();
               Collection<DotNetMethodDef> methods = type.getMethods();                
               System.out.println("TypeName: " + name);
               for(DotNetMethodDef method: methods){
                   String methodName = method.getName();
                   System.out.println("  MethodName: " + methodName);
               }                                
           }
           
       } catch (InvalidPEFileException ex) {
           ex.printStackTrace();
       } catch (IOException ex) {
           ex.printStackTrace();
       }
   } 
}

List dependent assemblies

Assemblies depend on other assemblies. This sample prints the name of dependent assemblies:

try {
  AssemblyFile assemblyFile = AssemblyFactory.readPeFile("SilverlightApplication1.dll");                                    
  DotNetModule module = assemblyFile.getDotNetMainModule();        
  for(DotNetAssemblyRef ar : module.getAssemblyRefs()){
    String name = ar.getName();               
    System.out.println("name:" + name );
   }
 } catch (InvalidPEFileException ex) {
   ex.printStackTrace();
 } catch (IOException ex) {
   ex.printStackTrace();
 }

Disassemble the main method

The following example gets the main method and disassembles it.

AssemblyFile assemblyFile = AssemblyFactory.readPeFile("WPFRegularExpressionsTester.exe");                                    
DotNetModule module = assemblyFile.getDotNetMainModule();
DotNetMethodDef method = (DotNetMethodDef) module.getEntryPointMethod();
if(method == null){
   System.out.println("The assembly does not contain a main method. Is it a library?");
   return;
}
SortedMap<Long, OpCode>   opcodes = method.getOpcodes();
for(OpCode opcode : opcodes.values()){
 System.out.println(opcode);
}

Accessing a metadata table

.Net assemblies store meta-data information in a relational database. The following advanced example shows how you gain access to those tables. Table num 2 contains one row for each type defined in the assembly. Column 1 contains an index in the string heap. That is the name of the type. The index in the stringheap is then transformed to the string with the help of dao.getStringHeapEntry.

AssemblyFile assemblyFile = AssemblyFactory.readPeFile("SilverlightApplication1.dll");                                    
MDDao dao = assemblyFile.getMetadataTableAccess();     
MDTable table  = dao.getMetadataTable(2); //Table 2 contains TypeDefs
for(MDRow row  : table.getRows()){
 MDCell cell  = row.getCell(1); // Column 1 contains an address in the string heap
 MDCellStringHeapEntry stringHeapEntry = (MDCellStringHeapEntry) cell;
 String typename = dao.getStringHeapEntry(stringHeapEntry); //We gonna lookup the address in the stringheap
 System.out.println(typename);
}