如何将类加载到正在运行的Java程序中

时间:2018-12-23 20:12:09

标签: java code-injection agent java-bytecode-asm

这是我的Agent.jar的代码

public class Agent
{

    public static void agentmain(String s, Instrumentation instrumentation)
    {
        try
        {
            ClassLoader classLoader = null;
            for (Class clazz : instrumentation.getAllLoadedClasses())
            {
                String className = clazz.getName();
                if (className.equalsIgnoreCase("ave")) /* Just a class from the running Programm */
                {
                    classLoader = clazz.getClassLoader();
                }
            }

            /* In the Cheat.jar are Classes which im trying to load */
            ClassLoader loader = URLClassLoader.newInstance(new URL[]{new URL("C:\\Users\\michi\\Desktop\\Injection\\Cheat.jar")}, classLoader);
            Class.forName("de.simplyblack.client.client.module.Category", true, loader);
            Class.forName("de.simplyblack.client.client.module.Module", true, loader);
            Class.forName("de.simplyblack.client.client.module.ModuleManager", true, loader);
        } catch (Throwable t)
        {
            t.printStackTrace();
        }
    }
}

我正在用一个额外的程序加载它。

 VirtualMachine virtualMachine = VirtualMachine.attach(id);
 virtualMachine.loadAgent(new File("C:\\Users\\michi\\Desktop\\Injection\\Client.jar").getAbsolutePath());
 virtualMachine.detach();

但这不起作用。

Later I visit an Class, and make an call for the ModuleManager class.

如果我注射它,我会得到一个

Class not found: de.simplyblack.client.client.module.ModuleManager

错误。

能否请您告诉我该如何解决? 这对我有很大帮助! 谢谢。

1 个答案:

答案 0 :(得分:1)

当解析一个类中的引用时,将使用其定义的类加载器。您的代码标识了要检测的类的定义类加载器,但随后使用它作为父加载器创建了一个新的类加载器。

当您要求新的加载器加载类时,很可能会加载 类,但是只能通过新创建的URLClassLoader才能访问它们。它们不适用于其他类加载器。

使用包含对其他类的新依赖关系的代码来插入类可能非常棘手。如果检测到的类已由应用程序类加载器加载,则可以使用Instrumentation.appendToSystemClassLoaderSearch(JarFile)Cheat.jar添加到搜索路径,以使这些类可用。

对于其他加载器加载的类,情况变得更加复杂。如果它们遵循标准的父委派模型,则可以使用appendToBootstrapClassLoaderSearch(JarFile)使您的类可用于所有这些类加载器。

对于不遵循委托模型的加载器,您必须进行更深入的研究,例如结合使用带有访问覆盖功能的反射,对其调用defineClass,以使该类在该范围内可用。