JAVAFX整合代码高亮
前言
最近一直在写一款工具,用于移动安全测试辅助。它是为了降低使用者的技术门槛并无需记忆很多操作命令才开发的,已经实现了自动化的微信小程序反编译(无需操作手机)与Jadx的联动使用。插件化的开发使得项目实现了解耦,拓展了工具的使用范围。
此前,某个模块是用于保存hook脚本代码,在Frida注入时会调用框内的js代码,方便用户直接编辑无需操作其他文件。并且通过上下文菜单插件,还能使得用户快速获取常用脚本:P。
原先的样子是这样的,用textarea组件保存resources下的hook.js
非常报看,代码一多就难受,所以我想着高亮代码去支持一下。
实现
某天看到冰蝎作者的新工具,是一个高度可定制化的JNDI和Java反序列化利用工具。在演示的视频里看到作者对于gadget的编辑实现了代码高亮,于是想去看看是怎么实现的。
很可惜,项目代码是闭源的。只能够用jadx去反编译一下代码,祈祷没有做混淆。通过定位关键字:依赖库格式错误,找到部分代码如下
发现是用webview实现的,找到对应的html代码
发现用了第三方的库,ace编辑器。查阅文档和相关examples后也知道怎么用了,首先在源码目录中,ace.js是必须的文件。
此外,设置主题,就需要用到主题的相关文件,以mode开头,
挑选自己喜欢的就行,我们还需要根据高亮语言的类型选择snippets下的文件。例如我们的脚本是javascript,那么就找这个就行了。
定义一个webview的组件,在maincontroller中对他进行初始化。在resources目录下放你的这些资源文件,定义一个html代码。
Editor
我自己添加了对代码的换行和设置mode为javascript,注意一下资源引用即可。之后就可以初始化webview了
WebEngine webEngine = this.codeview.getEngine();
webEngine.load(getClass().getResource("/ace/code.html").toExternalForm());
webEngine.documentProperty().addListener((observable, oldValue, newValue) -> {
if (newValue != null) {
String sourcecode = ""
this.editor = (JSObject) webEngine.executeScript("window.editor");
editor.call("setValue", new Object[]{sourceCode});
}
});
这里需要注意,由于webview的初始化需要一定时间。所以如果不放在对webview的监听事件内,会出现this.editor赋值为空的错误
代码通过call setvalue来注入内容到框内,保存的相关代码略过。通过jsbridge调用java层的代码就行了。
这样就可以愉快的使用了。
整合一下上下文菜单
由于webview没有类似其他node一样的setcontextmenu这个方法 只能够通过contextmenu.show来产生
需要注意的是 必须是右键点击、必须在鼠标的位置,所以我们只需要监听webview的右键点击事件并且点左键的时候隐藏上下文菜单即可
代码如下
codeview.addEventHandler(MouseEvent.MOUSE_PRESSED, new EventHandler() {
@Override
public void handle(MouseEvent e) {
MouseButton button = e.getButton();
codeview.setContextMenuEnabled(false);
//右键点击
if(button == MouseButton.SECONDARY){
System.out.println("right click"); //在你鼠标所处屏幕的xy处显示
contextMenu.show(codeview, e.getScreenX(), e.getScreenY());
}else{
if (contextMenu != null) {
contextMenu.hide();
}
}
}
});