全网最详细IDE插件开发之代码审计 – 作者:tolly

一、背景

代码审计,想必搞安全的同学再熟悉不过了,和标题中的IDE 插件有什么关系呢?莫不是标题党?
偶然挖洞闲暇时,发现了陌陌安全SRC的一个公告SAST开源,赶紧去撸一波源码,最终以看不懂为由挂机了。因此我决定从IDE插件开发学起,撸光它的码子。安全行业难能可贵的是开源精神,谢谢大厂。有请今天的主角momo-code-sec-inspector-java。大家可以先看着源码,看不懂了我们在来看看我下面的从0到1学开发插件。

二、开发环境搭建

像我这种小白,一般官方文档都是先不看,百度、bing、google一遍,看看有没有大神的教程系列,到最后基本上没有一个很全的文章。要么时间比较老,要么照着搭环境却起不来。后面我将带着大家一步一步的来,保证你能突破开发环境的这一步,并且弄懂momo安全开源SAST规则,让自己的代审功力提升。

2.1准备工作

序号 软件名 备注
1 idea 2020.1.4 community 下载页面
2 JDK 百度云链接密码:9k19
3 momo 开源代码 git clone地址

2.2 JDK安装

下一步大法,我就不详细截图了

2.3 IDEA安装配置

安装也是下一步到底就OK了

1. 新建项目
选择gradle创建项目,gradle创建项目便于插件开发依赖管理,关键它支持intellij platform plugin
如果JDK你安装没问题,这里的project SDK会自动选择1.8
image.png

2. 填好项目名,点击finish

image.png

3. 等待gradle创建项目框架
此时它在下载需要的IDEA的源码沙箱,以便于我们调试时,启动idea沙箱,网上有看到过教程离线导入这个IDEA的文件,不建议这样搞,非常麻烦且容易出错,为了避免后续bug存在,请等待10-30分钟

image.png

2.4 项目架构详解

│ build.gradle //**gradle配置文件**
│ gradlew      //gradle linux 下执行文件 (打包和编译运行)
│ gradlew.bat //gradle windows下执行文件(打包和编译运行)
│ settings.gradle
│
├─.gradle   //gradle组件文件夹
│ ├─6.1.1
│ │ │ gc.properties
│ │ │
│ │ ├─executionHistory
│ │ │ executionHistory.bin
│ │ │ executionHistory.lock
│ │ │
│ │ ├─fileChanges
│ │ │ last-build.bin
│ │ │
│ │ ├─fileHashes
│ │ │ fileHashes.bin
│ │ │ fileHashes.lock
│ │ │
│ │ └─vcsMetadata-1
│ ├─buildOutputCleanup
│ │ buildOutputCleanup.lock
│ │ cache.properties
│ │ outputFiles.bin
│ │
│ ├─checksums
│ │ checksums.lock
│ │ md5-checksums.bin
│ │ sha1-checksums.bin
│ │
│ └─vcs-1
│ gc.properties
│
├─.idea
│ .gitignore
│ compiler.xml
│ gradle.xml
│ jarRepositories.xml
│ misc.xml
│ workspace.xml
│
├─gradle
│ └─wrapper
│ gradle-wrapper.jar
│ gradle-wrapper.properties
│
└─src
├─main
│ ├─java   //代码文件夹
│ └─resources //资源库文件夹,插件图标,插件描述(html),插件配置文件等
│ └─META-INF
│ plugin.xml  //插件配置文件
│
└─test  //test文件夹
├─java
└─resources

项目结构图片

image.png

2.5 启动idea沙箱(IdeaIC)

点击启动后,可能还会下载一些依赖,请耐心等待。下载后的目录一般默认在用户目录下
image.png

通过gradle启动
image.png

通过快捷工具栏启动
image.pngimage.png

启动后会自动打开一个idea 这个是自动下载的沙箱版本和安装的是隔离的
image.png

三、编写人生第一个插件

组件类型 描述 接口 plugin.xml加载配置元素
ApplicationComponet 在idea启动时候初始化,整个IDEA只有一个实例 ApplicationComponet <application-components>
ProjectComponent idea会为每一个Project实例创建对应级别的Component ProjectComponent <project-components>
ModuleComponet idea会为每一个已经加载的Project中的每一个模块(module)创建Module级别的component ModuleComponet <module-componets>

先搞个和代码审计无关的插件,便于大家理解并提起你的兴趣,(#^.^#)

idea启动弹窗,人生鸡汤

1.在src/main/java下创建我们的pacage
image.png

2.新建一个applicationComponent的class文件
image.pngMyChickenSoul.java
这个文件是用来在启动时要做的事情,创建的类继承ApplicationComponent,然后重写initComponent方法

package com.tolly.security.action;

import com.intellij.openapi.application.Application;
import com.intellij.openapi.components.ApplicationComponent;
import io.netty.handler.ssl.ApplicationProtocolConfig;

public class MyChickenSoul implements ApplicationComponent {
    @Override
    public void initComponent() {
        //创建一个对话框对象,来装鸡汤
        DialogChickenSoul dialogChickenSoul = new DialogChickenSoul();
        dialogChickenSoul.show();
    }
}

3.创建一个对话框
image.png

package com.tolly.security.action;

import com.intellij.openapi.ui.DialogWrapper;
import org.jetbrains.annotations.Nullable;

import javax.swing.*;

public class DialogChickenSoul extends DialogWrapper {
    //继承后必须要搞一个构造方法,不然dialogwrapper上面提示会红的你难受。
    protected DialogChickenSoul() {
        super(true);
        //对话框的标题
        setTitle("哈哈");
        //别问我为啥要init,问了就是不知道
        init();
    }

    @Override
    protected @Nullable JComponent createCenterPanel() {
        //创建一个面板
        JPanel jPanel = new JPanel();
        //这个对象是去公网实时请求鸡汤的接口
        HttpRequest hrequest = new HttpRequest();
        String content = hrequest.httpclient();
        //将鸡汤塞进CenterPanel,其实还有northpanel和southpanel
        JLabel jLabel = new JLabel(content);
        jPanel.add(jLabel);
        return jPanel;
    }
}

4.创建httpUtils
作用:请求公网免费鸡汤接口,额外使用的模块为httpclient,fastjson

package com.tolly.security.action;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.fasterxml.jackson.databind.util.JSONPObject;
import com.google.gson.JsonObject;
import org.apache.http.HttpEntity;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.util.EntityUtils;

import java.io.IOException;

public class HttpRequest {
    public String httpclient(){
        String url = "https://data.zhai78.com/openOneGood.php";
        CloseableHttpClient httpClient = HttpClients.createDefault();
        HttpGet httpGet = new HttpGet(url);
        CloseableHttpResponse httpResponse = null;
        try {
            httpResponse = httpClient.execute(httpGet);
            HttpEntity httpEntity = httpResponse.getEntity();
            String response = EntityUtils.toString(httpEntity);
            JSONObject result = JSON.parseObject(response);
            String aaa = (String) result.get("txt");
            return aaa;
        } catch (ClientProtocolException e) {
            e.printStackTrace();
            return "又失败了";
        } catch (IOException e) {
            e.printStackTrace();
            return "nonono";
        }
    }



}

5.导入额外jar包依赖
在build.gradle添加依赖,如何找到gradle依赖的?在Maven仓库搜索
image.png发现没有生效?点一下reload即可自动下载
image.png

plugins {
    id 'java'
    id 'org.jetbrains.intellij' version '0.6.5'
}

group 'com.security.guy'
version '1.0-SNAPSHOT'

repositories {
    mavenCentral()
}

dependencies {
    testCompile group: 'junit', name: 'junit', version: '4.12'
    //httpclient
    compile group: 'org.apache.httpcomponents', name: 'httpclient', version: '4.5.13'
    //fastjson
    compile group: 'com.alibaba', name: 'fastjson', version: '1.2.75'
}

// See https://github.com/JetBrains/gradle-intellij-plugin/
intellij {
    version '2020.1.4'
}
patchPluginXml {
    changeNotes """
      Add change notes here.<br>









      <em>most HTML tags may be used</em>"""
}


tasks.withType(JavaCompile) {
    options.encoding = "UTF-8"
}

6.plugin.xml 配置
添加application-component,将MyChickenSoul添加到配置文件。

<idea-plugin>
    <id>com.security.guy.myfirstPlugin</id>
    <name>Plugin display name here</name>
    <vendor email="[email protected]" url="http://www.yourcompany.com">YourCompany</vendor>

    <description><![CDATA[
    Enter short description for your plugin here.<br>

    <em>most HTML tags may be used</em>
    ]]></description>

    <!-- please see https://www.jetbrains.org/intellij/sdk/docs/basics/getting_started/plugin_compatibility.html
         on how to target different products -->
    <depends>com.intellij.modules.platform</depends>

    <extensions defaultExtensionNs="com.intellij">
        <!-- Add your extensions here -->
    </extensions>

    <actions>
        <!-- Add your actions here -->
    </actions>

    <application-components>
        <component>
            <implementation-class>com.tolly.security.action.MyChickenSoul</implementation-class>
        </component>
    </application-components>
</idea-plugin>

7.启动插件
image.png有可能乱码的情况,我们可以在build.gradle配置文件最下方添加如下配置

tasks.withType(JavaCompile) {
    options.encoding = "UTF-8"
}

来源:freebuf.com 2021-02-08 12:35:32 by: tolly

© 版权声明
THE END
喜欢就支持一下吧
点赞0
分享
评论 抢沙发

请登录后发表评论