1 /*
2 * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * This code is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License version 2 only, as
7 * published by the Free Software Foundation.
8 *
9 * This code is distributed in the hope that it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
12 * version 2 for more details (a copy is included in the LICENSE file that
13 * accompanied this code).
14 *
15 * You should have received a copy of the GNU General Public License version
16 * 2 along with this work; if not, write to the Free Software Foundation,
17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
18 *
19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
20 * or visit www.oracle.com if you need additional information or have any
21 * questions.
22 */
74
75 fprintf(stderr, "found class to be hooked: %s - rewriting ...\n", name);
76
77 while (d + n < end) {
78 if (memcmp(s, FROM, n) == 0) {
79 memcpy(d, TO, n);
80 s += n;
81 d += n;
82 count++;
83 } else {
84 *d++ = *s++;
85 }
86 }
87 while (d < end) {
88 *d++ = *s++;
89 }
90
91 *new_class_data_len = class_data_len;
92 *new_class_data = new_data;
93
94 fprintf(stderr, "Rewriting done. Replaced %d occurrence(s)\n", count);
95 }
96 }
97 }
98
99 static jint init_options(char *options) {
100 char* class_name;
101 char* from;
102 char* to;
103
104 fprintf(stderr, "Agent library loaded with options = %s\n", options);
105 if ((class_name = options) != NULL &&
106 (from = strchr(class_name, ',')) != NULL && (from[1] != 0)) {
107 *from = 0;
108 from++;
109 if ((to = strchr(from, ',')) != NULL && (to[1] != 0)) {
110 *to = 0;
111 to++;
112 if (strchr(to, ',') == NULL &&
113 strlen(to) == strlen(from) &&
114 strlen(class_name) > 0 &&
115 strlen(to) > 0) {
116 CLASS_NAME = strdup(class_name);
117 FROM = strdup(from);
118 TO = strdup(to);
119 fprintf(stderr, "CLASS_NAME = %s, FROM = %s, TO = %s\n",
120 CLASS_NAME, FROM, TO);
121 return JNI_OK;
122 }
123 }
124 }
125 fprintf(stderr,
126 "Incorrect options. You need to start the JVM with -agentlib:ClassFileLoadHook=<classname>,<from>,<to>\n"
127 "where <classname> is the class you want to hook, <from> is the string in the classfile to be replaced\n"
128 "with <to>. <from> and <to> must have the same length. Example:\n"
129 " @run main/native -agentlib:ClassFileLoadHook=Foo,XXX,YYY ClassFileLoadHookTest\n");
130 return JNI_ERR;
131 }
132
133 static jint Agent_Initialize(JavaVM *jvm, char *options, void *reserved) {
134 int rc;
135
136 if ((rc = (*jvm)->GetEnv(jvm, (void **)&jvmti, JVMTI_VERSION_1_1)) != JNI_OK) {
137 fprintf(stderr, "Unable to create jvmtiEnv, GetEnv failed, error = %d\n", rc);
138 return JNI_ERR;
139 }
140 if ((rc = init_options(options)) != JNI_OK) {
141 return JNI_ERR;
142 }
143
144 (void) memset(&callbacks, 0, sizeof(callbacks));
145 callbacks.ClassFileLoadHook = &ClassFileLoadHook;
146 if ((rc = (*jvmti)->SetEventCallbacks(jvmti, &callbacks, sizeof(callbacks))) != JNI_OK) {
147 fprintf(stderr, "SetEventCallbacks failed, error = %d\n", rc);
148 return JNI_ERR;
149 }
150
151 if ((rc = (*jvmti)->SetEventNotificationMode(jvmti, JVMTI_ENABLE,
152 JVMTI_EVENT_CLASS_FILE_LOAD_HOOK, NULL)) != JNI_OK) {
153 fprintf(stderr, "SetEventNotificationMode failed, error = %d\n", rc);
154 return JNI_ERR;
155 }
156
157 return JNI_OK;
158 }
159
160 JNIEXPORT jint JNICALL Agent_OnLoad(JavaVM *jvm, char *options, void *reserved) {
|
1 /*
2 * Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved.
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * This code is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License version 2 only, as
7 * published by the Free Software Foundation.
8 *
9 * This code is distributed in the hope that it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
12 * version 2 for more details (a copy is included in the LICENSE file that
13 * accompanied this code).
14 *
15 * You should have received a copy of the GNU General Public License version
16 * 2 along with this work; if not, write to the Free Software Foundation,
17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
18 *
19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
20 * or visit www.oracle.com if you need additional information or have any
21 * questions.
22 */
74
75 fprintf(stderr, "found class to be hooked: %s - rewriting ...\n", name);
76
77 while (d + n < end) {
78 if (memcmp(s, FROM, n) == 0) {
79 memcpy(d, TO, n);
80 s += n;
81 d += n;
82 count++;
83 } else {
84 *d++ = *s++;
85 }
86 }
87 while (d < end) {
88 *d++ = *s++;
89 }
90
91 *new_class_data_len = class_data_len;
92 *new_class_data = new_data;
93
94 fprintf(stderr, "Rewriting done. Replaced %d occurrence(s) of \"%s\" to \"%s\"\n", count, FROM, TO);
95 }
96 }
97 }
98
99 static int early = 0;
100
101 static jint init_options(char *options) {
102 char* class_name;
103 char* from;
104 char* to;
105
106 fprintf(stderr, "Agent library loaded with options = %s\n", options);
107 if (options != NULL && strncmp(options, "+early,", 7) == 0) {
108 early = 1;
109 options += 7;
110 }
111 if ((class_name = options) != NULL &&
112 (from = strchr(class_name, ',')) != NULL && (from[1] != 0)) {
113 *from = 0;
114 from++;
115 if ((to = strchr(from, ',')) != NULL && (to[1] != 0)) {
116 *to = 0;
117 to++;
118 if (strchr(to, ',') == NULL &&
119 strlen(to) == strlen(from) &&
120 strlen(class_name) > 0 &&
121 strlen(to) > 0) {
122 CLASS_NAME = strdup(class_name);
123 FROM = strdup(from);
124 TO = strdup(to);
125 fprintf(stderr, "CLASS_NAME = %s, FROM = %s, TO = %s\n",
126 CLASS_NAME, FROM, TO);
127 return JNI_OK;
128 }
129 }
130 }
131 fprintf(stderr,
132 "Incorrect options. You need to start the JVM with -agentlib:ClassFileLoadHook=<classname>,<from>,<to>\n"
133 "where <classname> is the class you want to hook, <from> is the string in the classfile to be replaced\n"
134 "with <to>. <from> and <to> must have the same length. Example:\n"
135 " @run main/native -agentlib:ClassFileLoadHook=Foo,XXX,YYY ClassFileLoadHookTest\n");
136 return JNI_ERR;
137 }
138
139 static jint Agent_Initialize(JavaVM *jvm, char *options, void *reserved) {
140 int rc;
141 jvmtiCapabilities caps;
142
143 if ((rc = (*jvm)->GetEnv(jvm, (void **)&jvmti, JVMTI_VERSION_1_1)) != JNI_OK) {
144 fprintf(stderr, "Unable to create jvmtiEnv, GetEnv failed, error = %d\n", rc);
145 return JNI_ERR;
146 }
147 if ((rc = init_options(options)) != JNI_OK) {
148 return JNI_ERR;
149 }
150
151 memset(&caps, 0, sizeof(caps));
152
153 caps.can_redefine_classes = 1;
154 if (early) {
155 fprintf(stderr, "can_generate_all_class_hook_events/can_generate_early_vmstart/can_generate_early_class_hook_events == 1\n");
156 caps.can_generate_all_class_hook_events = 1;
157 caps.can_generate_early_class_hook_events = 1;
158 }
159 if ((rc = (*jvmti)->AddCapabilities(jvmti, &caps)) != JNI_OK) {
160 fprintf(stderr, "AddCapabilities failed, error = %d\n", rc);
161 return JNI_ERR;
162 }
163
164 (void) memset(&callbacks, 0, sizeof(callbacks));
165 callbacks.ClassFileLoadHook = &ClassFileLoadHook;
166 if ((rc = (*jvmti)->SetEventCallbacks(jvmti, &callbacks, sizeof(callbacks))) != JNI_OK) {
167 fprintf(stderr, "SetEventCallbacks failed, error = %d\n", rc);
168 return JNI_ERR;
169 }
170
171 if ((rc = (*jvmti)->SetEventNotificationMode(jvmti, JVMTI_ENABLE,
172 JVMTI_EVENT_CLASS_FILE_LOAD_HOOK, NULL)) != JNI_OK) {
173 fprintf(stderr, "SetEventNotificationMode failed, error = %d\n", rc);
174 return JNI_ERR;
175 }
176
177 return JNI_OK;
178 }
179
180 JNIEXPORT jint JNICALL Agent_OnLoad(JavaVM *jvm, char *options, void *reserved) {
|