Java注入学习总结

最近看到Android手机上金山毒霸实现了一个过滤广告的功能(也不确认是不是最早的),在注入过程中还包括JAR和dex注入,这让我产生了兴趣。

有关金山的注入在看雪论坛上有简要的分析:

http://bbs.pediy.com/showthread.php?t=166151

 

这里主要是被JAR注入吸引到了,不知道JAVA原来也能玩注入。不过替换的本质我却产生了个误解:难道JAVA的方法能够被动态替换?当然后来问了达人,得到一个结论,C#和JAVA初始化的过程不是一样的,方法的动态替换。据说C#可以,但是JAVA不行

 

首先在网上搜索了一些有关JAVA注入的资料,有2套资料比较有帮助:

1、xantorohara:http://xantorohara.blogspot.tw/2007/09/java-code-injection-via-winapis.html

2、vmattach:http://www.blogjava.net/javacap/default.html?page=5

 

一、在资料1中,按照作者提供的代码,(最好是XP环境下)编译完成之后,在我运行Notepad.jar之后,再注入JAR运行得到了如下图所示结果:

 

这的确实现了在对方的JAR(或者说java.exe)中运行了注入的JAR代码(Insider.java实现):

public class Insider implements Runnable {
    static {
        Thread t = new Thread(new Insider());
        t.setPriority(Thread.MIN_PRIORITY);
        t.setDaemon(true);
        t.start();
    }

    public void run() {
        int i = 0;
        while (true) {
            System.out.println(i++);
            try {
                Thread.sleep(300);
            } catch (InterruptedException e) {
                break;
            }
        }
    }
}

Xantorohara在实现过程中包含了一共5个重要的代码文件:

Injector.java —— 用于实现注入的JAVA代码,PID值由用户输入

Injector.cpp —— 用于实现注入的JNI代码,就是利用了Win32下的CreateRemoteThread函数,在远程进程中实现了LoadLibraryA("Insider.dll"),用于加载Insider.dll

Insider.java —— 构造了一个Insider类创建线程不断的输出数字,就是图示的情况

Insider.cpp —— Insider.dll的代码,它利用了Bin2H.java将Insider.java生成了class字节码存入Insider.h的jbyte clazz[]数组,在Insider.cpp中利用DefineClass创建新类,并且激活了这个类的代码:

C语言中的env->FindClass(className)类比JAVA下的Class.forName(className)

Bin2H.java —— 主要用于将javac Insider.java得到的Insider.class的字节码存入Insider.h的jbyte clazz[]数组

 

这里我们可以看得出来,要实现一个JAVA的注入,我们至少需要2个DLL:一个是用于主要负责原生工作的注入代码(主要调用CreateRemoteThread);另外一个DLL主要是在注入远程进程调用LoadLibraryA后启动,用于加载或者初始化类从而完成JAR的工作。

 

二、资料2中,作者没有提供相对完整的原生部分代码,但是展现的代码更为注入的意义

作者的VMAttach包中包含了2个DLL,VMAttach.dll和VMattach.jar配合主要是实现在JAVA(VMAttach.jar)下调用JNI(VMAttach.dll),像远程的JAVA进程注入了worker.dll,而worker.dll中通过IDA分析其通过JNI下实现的类似于如下JAVA代码:

loader = new URLClassLoader(new URL ("jar:file:/C:/AttachDemo.jar!/AttachDemo"))

 

来加载了AttchDemo.jar(入口为AttachDemo)并且调用FindClass、CallStaticVoidMethod函数运行了AttachDemo.jar中的main方法。

在main方法中,远程进程通过反射的方式,获得了UseSingletonApp中 private   volatile   int  stateNum; 的当前值,测试效果如下所示:

 

后记:

最后,我google了很久也没找到一个关于JAVA动态时候替换方法的办法,有一些比如说热替换的思路,但是是在特殊构造的代码情况下能够实现;除此之外就是利用开源的ASM类修改字节码实现,不过这不属于“运行时替换”吧。虽然能够注入JAVA代码,但是如果想实现类似API HOOK的方式,必须找到一种替换其方法的办法,只是可惜最后没有找到,仅仅只是实现了一个可用于部分访问成员的代码注入而已。

posted on 2013-10-03 03:15  堕落华为人  阅读(3200)  评论(0编辑  收藏  举报

导航