📄 _chapter 9.htm
字号:
172. }
173.
174. private Map classes = new HashMap();
175. private int key;
176. }
</pre>
<h5 id="ch09list02" class="docExampleTitle">Example 9-2 Caesar.java</h5>
<pre> 1. import java.io.*;
2.
3. /**
4. Encrypts a file using the Caesar cipher.
5. */
6. public class Caesar
7. {
8. public static void main(String[] args)
9. {
10. if (args.length != 3)
11. {
12. System.out.println("USAGE: java Caesar in out key");
13. return;
14. }
15.
16. try
17. {
18. FileInputStream in = new FileInputStream(args[0]);
19. FileOutputStream out = new FileOutputStream(args[1]);
20. int key = Integer.parseInt(args[2]);
21. int ch;
22. while ((ch = in.read()) != -1)
23. {
24. byte c = (byte)(ch + key);
25. out.write(c);
26. }
27. in.close();
28. out.close();
29. }
30. catch(IOException exception)
31. {
32. exception.printStackTrace();
33. }
34. }
35. }
</pre>
<h5 class="docSection3Title" id="ch09lev3sec1"><tt>java.lang.Class</tt></h5>
<p><img alt="graphics/api.gif" src="api.gif" border="0" width="46" height="45"><br>
</p>
<ul>
<li>
<p class="docList"><tt>ClassLoader getClassLoader()</tt></p>
<p class="docList">gets the class loader that loaded this class.</li>
</ul>
<h5 class="docSection3Title" id="ch09lev3sec2"><tt>java.lang.ClassLoader</tt></h5>
<p><img alt="graphics/api.gif" src="api.gif" border="0" width="46" height="45"><br>
</p>
<ul>
<li>
<p class="docList"><tt>ClassLoader getParent()</tt></p>
<p class="docList">returns the parent class loader, or <tt>null</tt> if the
parent class loader is the bootstrap class loader.</li>
<li>
<p class="docList"><tt>static ClassLoader getSystemClassLoader()</tt></p>
<p class="docList">gets the system class loader, that is, the class loader
that was used to load the first application class.</li>
<li>
<p class="docList"><tt>protected Class findClass(String name)</tt></p>
<p class="docList">A class loader should override this method to find the
bytecodes for a class and present them to the virtual machine by calling the
<tt>defineClass</tt> method.</p>
<table cellSpacing="0" cellPadding="1" width="93%" border="1">
<colgroup span="3" align="left">
</colgroup>
<tr>
<td class="docTableCell" vAlign="top"><span class="docEmphasis">
Parameters:</span></td>
<td class="docTableCell" vAlign="top"><tt>name</tt></td>
<td class="docTableCell" vAlign="top">the name of the class. Use . as
package name separator, and don't use a <tt>.class</tt> suffix</td>
</tr>
</table>
<p> </li>
<li>
<p class="docList"><tt>Class defineClass(String name, byte[] data, int offset,
int length)</tt></p>
<p class="docList">adds a new class to the virtual machine.</p>
<table cellSpacing="0" cellPadding="1" width="93%" border="1">
<colgroup span="3" align="left">
</colgroup>
<tr>
<td class="docTableCell" vAlign="top"><span class="docEmphasis">
Parameters:</span></td>
<td class="docTableCell" vAlign="top"><tt>name</tt></td>
<td class="docTableCell" vAlign="top">the name of the class. Use . as
package name separator, and don't use a <tt>.class</tt> suffix</td>
</tr>
<tr>
<td class="docTableCell" vAlign="top"> </td>
<td class="docTableCell" vAlign="top"><tt>data</tt></td>
<td class="docTableCell" vAlign="top">an array holding the bytecodes of
the class</td>
</tr>
<tr>
<td class="docTableCell" vAlign="top"> </td>
<td class="docTableCell" vAlign="top"><tt>offset</tt></td>
<td class="docTableCell" vAlign="top">the start of the bytecodes in the
array</td>
</tr>
<tr>
<td class="docTableCell" vAlign="top"> </td>
<td class="docTableCell" vAlign="top"><tt>length</tt></td>
<td class="docTableCell" vAlign="top">the length of the bytecodes in the
array</td>
</tr>
</table>
</li>
</ul>
<h5 class="docSection3Title" id="ch09lev3sec3"><tt>java.lang.Thread</tt></h5>
<p><img alt="graphics/api.gif" src="api.gif" border="0" width="46" height="45"><br>
</p>
<ul>
<li>
<p class="docList"><tt>ClassLoader getContextClassLoader()</tt></p>
<p class="docList">gets the class loader that the creator of this thread has
designated as the most reasonable class loader to use when executing this
thread.</li>
<li>
<p class="docList"><tt>void setContextClassLoader(ClassLoader loader)</tt></p>
<p class="docList">sets a class loader for code in this thread to retrieve for
loading classes. If no context class loader is set explicitly when starting a
thread, the parent's context class loader is used.</li>
</ul>
<h3 class="docSection1Title" id="c9s2">Bytecode Verification</h3>
<p class="docText">When a class loader presents the bytecodes of a newly loaded
Java platform class to the virtual machine, these bytecodes are first inspected
by a <span class="docEmphasis">verifier.</span> The verifier checks that the
instructions cannot perform actions that are obviously damaging. All classes
except for system classes are verified. However, you can deactivate verification
with the undocumented <tt>-noverify</tt> option.</p>
<p class="docText">For example,</p>
<pre>java -noverify Hello
</pre>
<p class="docText">Here are some of the checks that the verifier carries out:</p>
<ul>
<li>
<p class="docList">That variables are initialized before they are used;</li>
<li>
<p class="docList">That method calls match the types of object references;</li>
<li>
<p class="docList">That rules for accessing private data and methods are not
violated;</li>
<li>
<p class="docList">That local variable accesses fall within the runtime stack;</li>
<li>
<p class="docList">That the runtime stack does not overflow.</li>
</ul>
<p class="docText">If any of these checks fail, then the class is considered
corrupted and will not be loaded.</p>
<div class="docNote">
<p class="docNoteTitle">NOTE</p>
<table cellSpacing="0" cellPadding="1" width="90%" border="0">
<tr>
<td vAlign="top" width="60">
<img alt="graphics/note.gif" src="note.gif" align="left" border="0" width="54" height="53"><br>
</td>
<td vAlign="top">
<p class="docText">If you are familiar with G鰀el's theorem, you may
wonder how the verifier can prove that a class file is free from type
mismatches, uninitialized variables, and stack overflows. G鰀el's theorem
states that it is impossible to design algorithms whose inputs are program
files and whose output is a Boolean value that states whether the input
program has a particular property (such as being free from stack
overflows). Is this a conflict between the public relations department at
Sun Microsystems and the laws of logic? No梚n fact, the verifier is
<span class="docEmphasis">not</span> a decision algorithm in the sense of
G鰀el. If the verifier accepts a program, it is indeed safe. However,
there may be many programs that the verifier rejects even though they
would actually be safe.</td>
</tr>
</table>
</div>
<p class="docText">This strict verification is an important security
consideration. Accidental errors, such as uninitialized variables, can easily
wreak havoc if they are not caught. More importantly, in the wide open world of
the Internet, you must be protected against malicious programmers who create
evil effects on purpose. For example, by modifying values on the runtime stack
or by writing to the private data fields of system objects, a program can break
through the security system of a browser.</p>
<p class="docText">However, you may wonder why there is a special verifier to
check all these features. After all, the compiler would never allow you to
generate a class file in which an uninitialized variable is used or in which a
private data field is accessed from another class. Indeed, a class file
generated by a compiler for the Java programming language always passes
verification. However, the bytecode format used in the class files is well
documented, and it is an easy matter for someone with some experience in
assembly programming and a hex editor to manually produce a class file that
contains valid but unsafe instructions for the Java virtual machine. Once again,
keep in mind that the verifier is always guarding against maliciously altered
class files, not just checking the class files produced by a compiler.</p>
<p class="docText">Here's an example of how to construct such an altered class
file. We start with the program <tt>VerifierTest.java</tt> of
<a class="docLink" href="#ch09list03">Example 9-3</a>. This is a simple program
that calls a method and displays the method result. The program can be run both
as a console program and as an applet. The <tt>fun</tt> method itself just
computes 1 + 2.</p>
<pre>static int fun()
{
int m;
int n;
m = 1;
n = 2;
int r = m + n;
return r;
}
</pre>
<p class="docText">As an experiment, try to compile the following modification
of this program:</p>
<pre>static int fun()
{
int m = 1;
int n;
m = 1;
<span class="docEmphStrong">m</span> = 2;
int r = m + n;
return r;
}
</pre>
<p class="docText">In this case, <tt>n</tt> is not initialized, and it could
have any random value. Of course, the compiler detects that problem and refuses
to compile the program. To create a bad class file, we have to work a little
harder. First, run the <tt>javap</tt> program to find out how the compiler
translates the <tt>fun</tt> method. The command</p>
<pre>javap -c VerifierTest
</pre>
<p class="docText">shows the bytecodes in the class file in mnemonic form.</p>
<pre>Method int fun()
0 iconst_1
1 istore_0
2 iconst_2
3 istore_1
4 iload_0
5 iload_1
6 iadd
7 istore_2
8 iload_2
9 ireturn
</pre>
<p class="docText">We will use a hex editor to change instruction 3 from <tt>
istore_1</tt> to <tt>istore_0</tt>. That is, local variable 0 (which is <tt>m</tt>)
is initialized twice, and local variable 1 (which is <tt>n</tt>) is not
initialized at all. We need to know the hexadecimal values for these
instructions. These values are readily available from <i>The Java Virtual
Machine Specification</i> by Tim Lindholm and Frank Yellin [Addison-Wesley,
1999].</p>
<pre>0 iconst_1 04
1 istore_0 3B
2 iconst_2 05
3 istore_1 3C
4 iload_0 1A
5 iload_1 1B
6 iadd 60
7 istore_2 3D
8 iload_2 1C
9 ireturn AC
</pre>
<p class="docText">You can use a hex editor (such as Hex Workshop, which you can
down-load from <a class="docLink" href="http://www.bpsoft.com" target="_blank">
http://www.bpsoft.com</a>) to carry out the modification. Or, of course, you can
use emacs in <tt>hexl-mode</tt>. In <a class="docLink" href="#ch09fig02">Figure
9-2</a>, you see the class file <tt>VerifierTest.class</tt> loaded into Hex
Workshop, with the bytecodes of the <tt>fun</tt> method highlighted.</p>
<center>
<h5 id="ch09fig02" class="docFigureTitle">Figure 9-2. Modifying bytecodes with a hex editor</h5>
<p>
<img alt="graphics/09fig02.gif" src="09fig02.gif" border="0" width="500" height="282"><br>
</p>
</center>
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -