![]() |
|||
![]() ![]() |
![]() |
|
![]() |
Listing 4-36 The CodeAttribute class import java.io.*; public class CodeAttribute { int nameIndex; int maxStack; int maxLocals; byte[] code; int startpc; int endpc; int handlerpc; ExceptionTable[] exceptions; AttributeInfo[] attributes; public CodeAttribute(AttributeInfo ai) throws IOException { nameIndex = ai.nameIndex(); ByteArrayInputStream bis = new ByteArrayInputStream(ai.data); DataInputStream dis = new DataInputStream(bis); maxStack = dis.readUnsignedShort(); maxLocals = dis.readUnsignedShort(); code = new byte[dis.readInt()]; dis.read(code); exceptions = new ExceptionTable[dis.readUnsignedShort()]; for (int i = 0; i < exceptions.length; i++) { exceptions[i] = new ExceptionTable(dis.readUnsignedShort(), dis.readUnsignedShort(), dis.readUnsignedShort(), dis.readUnsignedShort()); } attributes = new AttributeInfo[dis.readUnsignedShort()]; for (int i = 0; i < exceptions.length; i++) { attributes[i] = new AttributeInfo(dis); } } public int nameIndex() { return nameIndex; } // just print the code array public String toString() { String result = ; for (int i = 0; i < code.length; i++) { int thisByte; thisByte = code[i] < 0 ? 256 + code[i] : code[i]; result += + thisByte + \n; } return result; } } This class makes reference to another class called ExceptionTable. Listing 4-37 shows this class. It provides information to the virtual machine about where exception handlers begin and end. You wont actually need it until the next chapter. However, this information is included in the .class file, so you have to read it now. Listing 4-37 The ExceptionTable class public class ExceptionTable { int start_pc; int end_pc; int handler_pc; int catch_type; public ExceptionTable (int start_pc, int end_pc, int handler_pc, int catch_type) { this.start_pc = start_pc; this.end_pc = end_pc; this.handler_pc = handler_pc; this.catch_type = catch_type; } } The getCode() method in the Disassembler class is particularly simple. It just needs to find the Code attribute of the method and call its toString() method. Listing 4-38 demonstrates. Listing 4-38 The getCode() method public String getCode(MethodInfo mi) { CodeAttribute theCode = null; // find the exceptions attribute AttributeInfo[] mAttributes = mi.getAttributes(); for (int i = 0; i < mAttributes.length; i++) { String name = thePool.readUTF8(mAttributes[i].nameIndex()); if (name.equals(Code)) { try{ theCode = new CodeAttribute(mAttributes[i]); } catch (IOException e) { } break; } } if (theCode != null) { return theCode.toString(); } return ; } Legal IssuesMany software companies want to tell you that it is illegal to disassemble, decompile, or reverse-engineer code. This is flatly wrong. The courts in the United States have decided more than once that this is permissible. (Laws outside the United States may be different. Consult a local attorney if this is a matter of concern.) Because the sort of reverse engineering described here is permitted by law, many companies try to prevent it through copyright, patent, or licensing restrictions. Copyright protects the expression of an idea, not the idea itself. Copyright does not prevent you from reusing an idea. Thus, if you discover a neat algorithm by investigating the byte codes for SuperDuperApplet.class, just because SuperDuperApplet is copyrighted does not mean you cannot reuse the algorithm in your own programs. Although it is illegal to copy the byte code verbatim and paste it into your own files, it is perfectly legal to rewrite and recompile the algorithm. A patent is a more serious level of protection. Software patents protect ideas, not merely the expression of ideas. If an organization or individual owns a patent on an algorithm RSA encryption, for example then, you are legally required to license the patent from the patent owner before using the algorithm in your own software.
|
![]() |
|