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

📄 appendix.tex

📁 一个用于对.class文件进行插桩的开源工具
💻 TEX
字号:
\section{Code examples for the BCEL API}\label{sec:apicg}\subsection{HelloWorldBuilder.java}The following Java program reads a name from the standard input andprints a friendly ``Hello''. Since the \texttt{readLine()} method maythrow an \texttt{IOException} it is enclosed by a \texttt{try-catch} block.{\small \verbatimtabinput{HelloWorld.java}\label{sec:hello}}\subsection{HelloWorldBuilder.java}We will sketch  here how the above Java class can  be created from thescratch  using the \jc API. For ease of reading we willuse textual signatures and not create them dynamically. For example,the signature\begin{verbatim}  "(Ljava/lang/String;)Ljava/lang/StringBuffer;"\end{verbatim}would actually be created with\begin{verbatim}  Type.getMethodSignature(Type.STRINGBUFFER, new Type[] { Type.STRING });\end{verbatim}\subsubsection{Initialization:}First we create an empty class and an instruction list:{\small\begin{verbatim}  ClassGen  cg = new ClassGen("HelloWorld", "java.lang.Object",                              "<generated>", ACC_PUBLIC | ACC_SUPER,                              null);  ConstantPoolGen cp = cg.getConstantPool(); // cg creates constant pool  InstructionList il = new InstructionList();\end{verbatim}}We then create the main method, supplying the method's name and thesymbolic type signature encoded with \texttt{Type} objects.{\small\begin{verbatim}  MethodGen  mg = new MethodGen(ACC_STATIC | ACC_PUBLIC,// access flags                                Type.VOID,              // return type                                new Type[] {            // argument types                                  new ArrayType(Type.STRING, 1) },                                new String[] { "argv" }, // arg names                                "main", "HelloWorld",    // method, class                                il, cp);  InstructionFactory factory = new InstructionFactory(cg);\end{verbatim}}We define some often used types:{\small\begin{verbatim}  ObjectType i_stream = new ObjectType("java.io.InputStream");  ObjectType p_stream = new ObjectType("java.io.PrintStream");\end{verbatim}}\subsubsection{Create variables \texttt{in} and \texttt{name}:}We call the           constructors,              i.e.              execute\texttt{BufferedReader(Input\-Stream\-Reader(System.in))}.  The  referenceto the \texttt{BufferedReader} object stays on top of the stack and isstored in the newly allocated \texttt{in} variable.{\small\begin{verbatim}  il.append(factory.createNew("java.io.BufferedReader"));  il.append(InstructionConstants.DUP); // Use predefined constant  il.append(factory.createNew("java.io.InputStreamReader"));  il.append(InstructionConstants.DUP);  il.append(factory.createFieldAccess("java.lang.System", "in", i_stream,                                      Constants.GETSTATIC));  il.append(factory.createInvoke("java.io.InputStreamReader", "<init>",                                 Type.VOID, new Type[] { i_stream },                                 Constants.INVOKESPECIAL));  il.append(factory.createInvoke("java.io.BufferedReader", "<init>", Type.VOID,                                 new Type[] {new ObjectType("java.io.Reader")},                                 Constants.INVOKESPECIAL));  LocalVariableGen lg =    mg.addLocalVariable("in",                        new ObjectType("java.io.BufferedReader"), null, null);  int in = lg.getIndex();  lg.setStart(il.append(new ASTORE(in))); // `i' valid from here\end{verbatim}}Create local variable \texttt{name} and  initialize it to \texttt{null}.{\small\begin{verbatim}  lg = mg.addLocalVariable("name", Type.STRING, null, null);  int name = lg.getIndex();  il.append(InstructionConstants.ACONST_NULL);  lg.setStart(il.append(new ASTORE(name))); // `name' valid from here\end{verbatim}}\subsubsection{Create try-catch block}We remember  the start  of the  block, read a  line from  the standardinput and store it into the variable \texttt{name}.{\small\begin{verbatim}  InstructionHandle try_start =    il.append(factory.createFieldAccess("java.lang.System", "out", p_stream,                                        Constants.GETSTATIC));  il.append(new PUSH(cp, "Please enter your name> "));  il.append(factory.createInvoke("java.io.PrintStream", "print", Type.VOID,                                  new Type[] { Type.STRING },                                 Constants.INVOKEVIRTUAL));  il.append(new ALOAD(in));  il.append(factory.createInvoke("java.io.BufferedReader", "readLine",                                 Type.STRING, Type.NO_ARGS,                                 Constants.INVOKEVIRTUAL));  il.append(new ASTORE(name));\end{verbatim}}Upon  normal execution we  jump behind  exception handler,  the targetaddress is not known yet.{\small\begin{verbatim}  GOTO g = new GOTO(null);  InstructionHandle try_end = il.append(g);\end{verbatim}}We add the exception handler which simply returns from the method.{\small\begin{verbatim}  InstructionHandle handler = il.append(InstructionConstants.RETURN);  mg.addExceptionHandler(try_start, try_end, handler, "java.io.IOException");\end{verbatim}}``Normal'' code continues, now we can set the branch target of the GOTO.{\small\begin{verbatim}  InstructionHandle ih =    il.append(factory.createFieldAccess("java.lang.System", "out", p_stream,                                        Constants.GETSTATIC));  g.setTarget(ih);\end{verbatim}}\subsubsection{Printing "Hello"}String concatenation compiles to \texttt{StringBuffer} operations.{\small\begin{verbatim}  il.append(factory.createNew(Type.STRINGBUFFER));  il.append(InstructionConstants.DUP);  il.append(new PUSH(cp, "Hello, "));  il.append(factory.createInvoke("java.lang.StringBuffer", "<init>",                                 Type.VOID, new Type[] { Type.STRING },                                 Constants.INVOKESPECIAL));  il.append(new ALOAD(name));  il.append(factory.createInvoke("java.lang.StringBuffer", "append",                                 Type.STRINGBUFFER, new Type[] { Type.STRING },                                 Constants.INVOKEVIRTUAL));  il.append(factory.createInvoke("java.lang.StringBuffer", "toString",                                 Type.STRING, Type.NO_ARGS,                                 Constants.INVOKEVIRTUAL));      il.append(factory.createInvoke("java.io.PrintStream", "println",                                 Type.VOID, new Type[] { Type.STRING },                                 Constants.INVOKEVIRTUAL));  il.append(InstructionConstants.RETURN);\end{verbatim}}\subsubsection{Finalization}Finally, we  have to  set  the stack  size,  which  normally would  becomputed on the fly and add a default constructor method to the class,which is empty in this case.{\small\begin{verbatim}  mg.setMaxStack(5);  cg.addMethod(mg.getMethod());  il.dispose(); // Allow instruction handles to be reused  cg.addEmptyConstructor(ACC_PUBLIC);\end{verbatim}}Last but not least we dump the \texttt{JavaClass} object to a file.{\small\begin{verbatim}  try {    cg.getJavaClass().dump("HelloWorld.class");  } catch(java.io.IOException e) { System.err.println(e); }\end{verbatim}}\subsection{Peephole.java}This class implements a simple peephole optimizer that removes any NOPinstructions from the given class.{\small\verbatimtabinput{Peephole.java}}\label{sec:nop}

⌨️ 快捷键说明

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