版权声明:欢迎关注新浪微博 @人生无NG https://blog.csdn.net/zihao2012/article/details/50379913
随着HTML5的普及,越来越多的APP客户端逻辑开始使用HTML5来构造。甚至有些APP不仅将展示页面使用HTML5布局,还将一些关键字符串的加密算法写在了JS脚本中。一些是客户端自定义的算法,可能一时难以完全读懂直接重写,如果能像smali代码中的方法那样直接调用就好了,所以下面分享几种Java代码直接调用JS方法的。
1.Java代码内写JS方法
简单示例:
// JSFuntion内嵌
public static void JSFunction() throws ScriptException {
// 获得一个JavaScript脚本引擎
ScriptEngineManager mgr = new ScriptEngineManager();
ScriptEngine engine = mgr.getEngineByName("JavaScript");
// 执行脚本
engine.eval("function test(p){return 'this is test js in java,'+p}");
// 转化成父类(Invocable),因为ScriptEngine中没有调用js的方法
Invocable inv = (Invocable) engine;
// 调用脚本得到返回值
String value = null;
try {
value = (String) inv.invokeFunction("test", "我是一个参数");
} catch (NoSuchMethodException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
System.out.println(value);
}
2.Java代码调用外部本地JS文件
实现原理:通过File文件得到js的文件流,然后放入engine.eval()方法中,其他的都和第一种原理一致;
// 调用外部本地JS文件
public static void outJSFuntion() throws FileNotFoundException, ScriptException, NoSuchMethodException {
ScriptEngineManager mgr = new ScriptEngineManager();
ScriptEngine engine = mgr.getEngineByName("JavaScript");
// 加载一个文件
File f = new File("<span style="color:#2A00FF;">./WebRoot/js/t.js</span>");
Reader r = new InputStreamReader(new FileInputStream(f));
// 把Reader放入eval中(读者可以去API看一下,重载了很多的eval()方法)
engine.eval(r);
Invocable inv = (Invocable) engine;
String value = (String) inv.invokeFunction("strEnc", "admin","1","2","3");
System.out.println(value);
}
外部
./WebRoot/js/t.js的内容为:
function test(p){
return '调用了外部js方法 '+p;
}
3.调用外网Internet上的JS文件
实现原理:通过解析HttpUrlConnection类得到JSP页面内容,然后通过正则表达式匹配js脚本路径,然后通过HttpUrlConnection访问js文件,得到Reader,其他原理同上
// 调用外网Internet上JS文件
public static void interJSFuntion() {
// 构造一个脚本器
ScriptEngineManager mgr = new ScriptEngineManager();
ScriptEngine engine = mgr.getEngineByName("JavaScript");
String url = "http://localhost/Test";
String html = UrlUtil.getHtml(url);
// 使用正则匹配js文件路径
String js = getTextZZ(html, "<script[\\s]*type=\"text/javascript\"[\\s]*src=[.&\\S]+>[\\s]*</script>");
js = url + UrlUtil.getTextZZ(js, "\\Q/\\E[.&\\S]+\\Q.js\\E");
// 得到流
Reader r = getReader(js, "utf-8");
// 把Reader放入eval中(读者可以去API看一下,重载了很多的eval()方法)
engine.eval(r);
Invocable inv = (Invocable) engine;
String value = (String) inv.invokeFunction("test", "我是一个参数");
System.out.println(value);
}
// 得到Reader(使用HttpURLConnection得到外部js文件的Reader流)
public static Reader getReader(String url, String code) {
URL URL = null;
HttpURLConnection conn = null;
InputStream in = null;
Reader br = null;
try {
URL = new URL(url);
conn = (HttpURLConnection) URL.openConnection();
// 设置get请求
conn.setRequestMethod("GET");
// 得到流
in = conn.getInputStream();
br = new InputStreamReader(in, code);
} catch (Exception ex) {
ex.printStackTrace();
}
return br;
}
// 根据内容得到匹配
public static String getTextZZ(String Text, String zz) {
Pattern p = Pattern.compile(zz);
Matcher m = p.matcher(Text);
String group = "";
while (m.find()) {
group = m.group();
}
return group;
}
// 得到HTML
public static String getHtml(String url) {
URL URL = null;
HttpURLConnection conn = null;
InputStream in = null;
BufferedReader br = null;
String html = null;
try {
URL = new URL(url);
conn = (HttpURLConnection) URL.openConnection();
conn.setRequestMethod("GET");
String code = getCode(conn.getContentType());
in = conn.getInputStream();
br = new BufferedReader(new InputStreamReader(in, code));
// 得到HTML文档
String data = "";
while ((data = br.readLine()) != null) {
html += data + "\n";
}
} catch (Exception ex) {
ex.printStackTrace();
} finally {
try {
br.close();
in.close();
conn.disconnect();
} catch (Exception ex) {
ex.printStackTrace();
}
}
return html;
}
4.后记
前几天在分析一个银行APP,它的密码加密函数就是在JS脚本里,其实就是一个简单的DES,当却有三个随机KEY..
所以有了上文。
知识点来源于:
百度文库:http://t.cn/R4b6eON
DES加密JS和Java保持一致:http://www.cnblogs.com/qiongmiaoer/p/3573474.html