1. 程式人生 > >prevent jar from decompiling by golang solution

prevent jar from decompiling by golang solution

Our application is built on Spring Boot, we would like to protect it, it should not be decompiled. I found Golang can do some work on this case.

As golang only packages executable code, we should make any files as static ones, package them all into a **.go file, then go build recognizes it and package it. There are some tools can do this work, I select 

mjibson/esc . 

1. make sure your GOPATH/bin is in your os path

2. use "go get github.com/mjibson/esc.git" to install esc project to your GOPATH

3. go to golang project root, new a folder say "static", put your **.jar under this folder

4. open a terminal or dos window, change directory to golang project root directory, type "esc -o bindata.go static", it will take long time to embed them to a go file.

5. by default, golang would occupy port 8080, so the spring boot project should have a different port

The golang code is as simple as as following:

import (
	"log"
	"net/http"
	"os/exec"
	"io/ioutil"
	"path/filepath"
	"time"
	"os"
)

func main() {
	// As main goroutine would be held by listenAndServe to listen HTTP request, so need a new goroutine to handle jar
	go func(){
		log.Println("start to read jar content from binary data")
		resp, err := http.Get("http://localhost:8080/static/eurekaserver.jar")
		check(err)
		defer resp.Body.Close()
		body, err := ioutil.ReadAll(resp.Body)
		check(err)
		log.Println("start to write stream to jar file")
		err = ioutil.WriteFile("demo3.abc", body, 0666)
		check(err)

		jarPath, jarErr := filepath.Abs("demo3.abc")
		if jarErr == nil {
			log.Println("jarPath is :: ", jarPath)
		} else {
			log.Println("jarErr is :: ", jarErr)
		}

		go func(){
			time.Sleep(time.Second * 20)
			log.Println("delete jar file", jarPath)
			delErr := os.Remove(jarPath)
			if delErr != nil {
				log.Println("error on deletion", delErr)
			}
		}()

		log.Println("start to run java application.")
		cmd := exec.Command("java", "-jar", jarPath)
		cmd.Run()
	}()

	// FS() is created by esc and returns a http.Filesystem.
	// FS() is strange, initially it cannot be recognized, but some time it can anyway!
	http.Handle("/static/", http.FileServer(FS(false)))
	log.Println("start listenandserver...")
	log.Fatal(http.ListenAndServe(":8080", nil))
}

Golang project is so simple, bindata.go embeds everything under static folder, hence it would be packaged to an embedassets.exe by "go build".



However, there is 2 problems:

1. embedded jar seems to be requested only through HTTP, thus I should read it out and write to disk named "demo3.abc" here.

2. once this real jar file gets up and run, in windows, it prevents this file from deleting. Somebody say yes on Linux.

----------------------------------------------

Still this solution is not good, maybe we can hide this jar file in some temp folder with strange name, and better to deploy it to Linux so the jar file can be deleted once java process is up to make jar file safe relatively. But the jar file leaves its traces on disk for some time, it is risky.

If there is a way to run java app by consuming byte[] directly, or write byte[] to an in-memory jar file for "java -jar" command to consume, then it is safe to protect our jar file.