1 /* 2 * Copyright (C) 2011 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 import dalvik.system.PathClassLoader; 18 import dalvik.system.VMDebug; 19 import java.io.BufferedInputStream; 20 import java.io.BufferedOutputStream; 21 import java.io.FileInputStream; 22 import java.io.FileOutputStream; 23 import java.io.File; 24 import java.io.IOException; 25 26 public class Main { main(String[] args)27 public static void main(String[] args) throws Exception { 28 System.loadLibrary(args[0]); 29 System.out.println("Hello, world!"); 30 String agent = null; 31 // By default allow debugging 32 boolean debugging_allowed = true; 33 for(String a : args) { 34 if(a.startsWith("agent:")) { 35 agent = a.substring(6); 36 } else if (a.equals("disallow-debugging")) { 37 debugging_allowed = false; 38 } 39 } 40 if (agent == null) { 41 throw new Error("Could not find agent: argument!"); 42 } 43 setDebuggingAllowed(debugging_allowed); 44 // Setup is finished. Try to attach agent in 2 ways. 45 try { 46 VMDebug.attachAgent(agent); 47 } catch(SecurityException e) { 48 System.out.println(e.getMessage()); 49 } 50 attachWithClassLoader(args); 51 System.out.println("Goodbye!"); 52 } 53 setDebuggingAllowed(boolean val)54 private static native void setDebuggingAllowed(boolean val); 55 attachWithClassLoader(String[] args)56 private static void attachWithClassLoader(String[] args) throws Exception { 57 for(String a : args) { 58 if(a.startsWith("agent:")) { 59 String agentName = a.substring(6, a.indexOf('=')); 60 File tmp = null; 61 try { 62 tmp = File.createTempFile("lib", ".so"); 63 prepare(agentName, tmp); 64 65 String newAgentName = tmp.getName(); 66 String agent = a.substring(6).replace(agentName, newAgentName); 67 68 ClassLoader cl = new PathClassLoader("", tmp.getParentFile().getAbsolutePath(), 69 Main.class.getClassLoader()); 70 try { 71 VMDebug.attachAgent(agent, cl); 72 } catch(SecurityException e) { 73 System.out.println(e.getMessage()); 74 } 75 } catch (Exception e) { 76 e.printStackTrace(System.out); 77 } finally { 78 if (tmp != null) { 79 tmp.delete(); 80 } 81 } 82 } 83 } 84 } 85 prepare(String in, File tmp)86 private static void prepare(String in, File tmp) throws Exception { 87 // Find the original. 88 File orig = find(in); 89 if (orig == null) { 90 throw new RuntimeException("Could not find " + in); 91 } 92 // Copy the original. 93 { 94 BufferedInputStream bis = new BufferedInputStream(new FileInputStream(orig)); 95 BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream(tmp)); 96 byte[] buf = new byte[16 * 1024]; 97 for (;;) { 98 int r = bis.read(buf, 0, buf.length); 99 if (r < 0) { 100 break; 101 } else if (r > 0) { 102 bos.write(buf, 0, r); 103 } 104 } 105 bos.close(); 106 bis.close(); 107 } 108 } 109 find(String in)110 private static File find(String in) { 111 String libraryPath = System.getProperty("java.library.path"); 112 for (String path : libraryPath.split(":")) { 113 File f = new File(path + "/" + in); 114 if (f.exists()) { 115 return f; 116 } 117 } 118 return null; 119 } 120 } 121