#1 楼
我建议使用Java代理从正在运行的JVM实例中提取类。代理是一种为应用程序提供检测功能的工具。说到代理,有两种广泛的开发方法:在纯Java中
在C / C ++中以本机代理的形式。
本机代理比纯Java代理具有更多功能,但就您的目的而言已经足够。在执行流程的某个时刻,类加载器必须加载和解密加密的类。
下面提供了示例代码。每次加载新类时,代理都会注册一个回调(
transform
方法),以通知该回调。在回调中,我们仅将类的内容转储到磁盘。import java.io.*;
import java.lang.instrument.*;
import java.security.*;
public class dumper
{
//A java agent must have a premain method which acts as the entry-point
public static void premain(String agentArgs, Instrumentation inst)
{
System.out.println("agent loaded");
// Register our transformer
inst.addTransformer(new transformer());
}
}
class transformer implements ClassFileTransformer
{
// The transform method is called for each non-system class as they are being loaded
public byte[] transform(ClassLoader loader, String className,
Class<?> classBeingRedefined, ProtectionDomain protectionDomain,
byte[] classfileBuffer) throws IllegalClassFormatException
{
if (className != null)
{
// Skip all system classes
if (!className.startsWith("java") &&
!className.startsWith("sun") &&
!className.startsWith("javax") &&
!className.startsWith ("com") &&
!className.startsWith("jdk") &&
!className.startsWith("org"))
{
System.out.println("Dumping: " + className);
// Replace all separator charactors
String newName = className.replaceAll("/", "#") + ".class";
try
{
FileOutputStream fos = new FileOutputStream(newName);
fos.write(classfileBuffer);
fos.close();
}
catch (Exception ex)
{
System.out.println("Exception while writing: " + newName);
}
}
}
// We are not modifying the bytecode in anyway, so return it as-is
return classfileBuffer;
}
}
我在这里对此过程进行了介绍:反转混淆的Java恶意软件
#2 楼
您可以在运行时使用HotSpot工具转储字节码,并使用反编译器反转字节码。我做了一个概念证明,在这里可用它需要3个依赖项:
JDK库(sa-jdi.jar,tools.jar)用于转储字节码
Fernflower将字节码反编译为Java代码
RSyntaxTextArea显示Java源代码
还可以看看HSDB实用程序
#3 楼
我认为最简单的方法是在加载类时转储类,假设您知道混淆的类加载器在哪里并且可以对其进行编辑。混淆的类加载器最终将不得不调用ClassLoader.defineClass在某一点。如果有类文件,则可以对其进行反汇编,找到对defineClass的所有调用(或可能会调用defineClass的反射方法),并在调用之前插入一个日志记录函数以转储结果。您可以为此使用Krakatau的反汇编程序/汇编程序。
最大的风险是,如果混淆的代码正在使用内省功能,则可能使事情变得混乱。例如,代码可能会计算其自身的校验和,在这种情况下,对其进行修改将导致问题。
如果有这种情况,您有两个选择:1)找到所有自省检查并删除/ modify / mock出来,或2)修改JVM本身。后一种方法对于混淆后的代码将是完全不可见的,但很难做到。
尝试尝试的另一件事是查看Java Agent接口。我本人还没有使用过它,所以我就不多说了,但这可能使您可以在运行时访问所有已加载的类,而无需进行代码修改。
评论
这正是我一直在寻找的东西,对于我想做的其他事情,代理商通常是极大的帮助。谢谢!
– Nickanallen
17-2-18在16:28
如果您无法停止JVM并挂接Java代理怎么办?
– Sajuuk
19年5月5日在9:36