当前位置: 代码网 > it编程>编程语言>Java > java调用js文件的两种常用方法示例(支持V8引擎)

java调用js文件的两种常用方法示例(支持V8引擎)

2024年07月03日 Java 我要评论
前言对java逆向感兴趣的盆友可以关注我以前的文章,有图片验证码识别、aes、sha256等各种加密的java实现,不定时更新常用算法和加密,欢迎一起交流讨论!在日常逆向中,一些前端的加密代码用jav

前言

对java逆向感兴趣的盆友可以关注我以前的文章,有图片验证码识别、aes、sha256等各种加密的java实现,不定时更新常用算法和加密,欢迎一起交流讨论!

在日常逆向中,一些前端的加密代码用java复现出来比较难,所以经常需要调用js文件来实现加密操作,接下来将介绍两种常用调用js的思路,第一种适用于普通js文件,第二种则适用于比较新的v8引擎。在实现的过程中,也会展示可能遇到的问题以及解决办法,废话不多话,正文开始!

方法一

本方法用的是jdk自带的scriptengine来实现,大概流程是:加载引擎->绑定环境->预编译js文件->调用文件内方法,具体实现代码:

import javax.script.*;
import java.io.inputstreamreader;

    //因为js文件读取一次就行,因此用静态代码块来读取
    private static scriptengine engine;

    static {
        try {
            scriptenginemanager manager = new scriptenginemanager();
            engine = manager.getenginebyname("javascript");
            bindings enginescope = engine.getbindings(scriptcontext.engine_scope);
            enginescope.put("window", enginescope);
            enginescope.put("navigator", enginescope);
            inputstreamreader jsencryptfilereader = new inputstreamreader(encjs.class.getclassloader().getresourceasstream("enc.js"));
            engine.eval(jsencryptfilereader);
            jsencryptfilereader.close();
        } catch (exception e) {
            e.printstacktrace();
        }

    }

读取完js后,就可以使用js引擎来直接用invokefunction方法来调用文件内函数,代码如下

    public static string enc(string data, string key) {
        invocable invoke = (invocable) engine;
        try {
            string result = (string) invoke.invokefunction("enc", data, key);
            return result.touppercase();
        } catch (exception e) {
            e.printstacktrace();
            return null;
        }
    }

在上边代码invoke.invokefunction("enc", data, key)中,enc为js文件内的函数名,datakey是需要方法需要传递的参数,如果方法只有一个参数,则传入一个,如果是多个参数,则按顺序排列在后边即可。

上边代码在执行普通js时比较方便使用,但是如果是比较新的开发版本,有些语法会不支持,像lambda表达式等,如下图:

此处再介绍一种方法,使用的是v8引擎,可以支持最新语法

方法二

使用到的maven依赖,以下依赖根据自己环境任选其一即可。

		<!-- linux系统 -->
		 <dependency>
            <groupid>com.eclipsesource.j2v8</groupid>
            <artifactid>j2v8_linux_x86_64</artifactid>
            <version>3.1.6</version>
        </dependency>
        <!-- mac系统 -->
        <dependency>
            <groupid>com.eclipsesource.j2v8</groupid>
            <artifactid>j2v8_macosx_x86_64</artifactid>
            <version>4.6.0</version>
        </dependency>
        <!-- windows系统 -->
        <dependency>
            <groupid>com.eclipsesource.j2v8</groupid>
            <artifactid>j2v8_win32_x86_64</artifactid>
            <version>4.6.0</version>
        </dependency>

这个的实现流程和上边稍微有些不同,也是:预读取js文件>加载引擎->编译js文件->调用文件内方法,具体实现代码如下:

import com.eclipsesource.v8.v8;
import org.apache.commons.io.ioutils;

import java.io.ioexception;
import java.nio.charset.standardcharsets;

public class v8jsutils {

    private static string filestr;

    static {
        try {
            filestr = ioutils.tostring(v8jsutils.class.getclassloader().getresourceasstream("enc.js"), standardcharsets.utf_8);
        } catch (ioexception e) {
            e.printstacktrace();
        }
    }

    public static string dec(string data, string key) {
        v8 runtime = v8.createv8runtime();

        try {
            runtime.executevoidscript(filestr);
            return (string) runtime.executejsfunction("dec", data, key);
        } catch (exception e) {
            e.printstacktrace();
        } finally {
            runtime.release();
        }
        return null;
    }
}

代码写完了,调用一下结果还是遇到了错误

这个错误的大概意思就是:严格模式外不能使用let,const之类的es6的命令,也就是说版本太低了,怎么办,更新版本?no no no,找到js文件出错的代码位置,在方法前加上一句:'use strict';注意!引号不能省略,必须全部复制,如图

现在再运行就正常了。

附:在java中绑定js变量

在调用engine.get(key);时,如果key没有定义,则返回null

package com.sinaapp.manjushri;   
import javax.script.bindings; 
import javax.script.scriptcontext; 
import javax.script.scriptengine; 
import javax.script.scriptenginemanager; 
import javax.script.scriptexception;   
public class scriptenginetest2 {  
public static void main(string[] args) {   
scriptenginemanager manager = new scriptenginemanager();   
scriptengine engine = manager.getenginebyname("javascript");   
engine.put("a", 4);   
engine.put("b", 3);   
bindings bindings = engine.getbindings(scriptcontext.engine_scope);  
try {                        
 // 只能为double,使用float和integer会抛出异常    
double result = (double) engine.eval("a+b");       
system.out.println("result = " + result);    
engine.eval("c=a+b");    
double c = (double)engine.get("c");    
system.out.println("c = " + c);   
    } catch (scriptexception e) { 
   e.printstacktrace();   
    }  
  } 
}

输出:

result = 7.0
c = 7.0

总结

到此这篇关于java调用js文件的两种常用方法的文章就介绍到这了,更多相关java调用js文件的方法内容请搜索代码网以前的文章或继续浏览下面的相关文章希望大家以后多多支持代码网!

(0)

相关文章:

版权声明:本文内容由互联网用户贡献,该文观点仅代表作者本人。本站仅提供信息存储服务,不拥有所有权,不承担相关法律责任。 如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 2386932994@qq.com 举报,一经查实将立刻删除。

发表评论

验证码:
Copyright © 2017-2025  代码网 保留所有权利. 粤ICP备2024248653号
站长QQ:2386932994 | 联系邮箱:2386932994@qq.com