⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 _chapter 9.htm

📁 Core Java 2(中文名称:JAVA 2 核心技术 卷二:高级特性)这是英文版的。
💻 HTM
📖 第 1 页 / 共 5 页
字号:
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(&quot;USAGE: java Caesar in out key&quot;);
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>
&nbsp;</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>
&nbsp;</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>&nbsp;</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">&nbsp;</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">&nbsp;</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">&nbsp;</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>
&nbsp;</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>
&nbsp;</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>
&nbsp;</p>
</center>

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -