Skip to content

Commit

Permalink
Merge pull request #1833 from nneonneo/rework-java-api
Browse files Browse the repository at this point in the history
Rework the Java bindings
  • Loading branch information
wtdcode authored Dec 25, 2023
2 parents d17810f + f55e783 commit 43597af
Show file tree
Hide file tree
Showing 97 changed files with 14,056 additions and 7,465 deletions.
1 change: 0 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,6 @@ _*.txt
_*.diff
tmp/

bindings/java/unicorn_Unicorn.h
bindings/python/build/
bindings/python/dist/
bindings/python/src/
Expand Down
24 changes: 19 additions & 5 deletions bindings/const_generator.py
Original file line number Diff line number Diff line change
Expand Up @@ -72,8 +72,8 @@
'java': {
'header': "// For Unicorn Engine. AUTO-GENERATED FILE, DO NOT EDIT\n\npackage unicorn;\n\npublic interface %sConst {\n",
'footer': "\n}\n",
'line_format': ' public static final int UC_%s = %s;\n',
'out_file': './java/unicorn/%sConst.java',
'line_format': ' public static final int UC_%s = %s;\n',
'out_file': './java/src/main/java/unicorn/%sConst.java',
# prefixes for constant filenames of all archs - case sensitive
'arm.h': 'Arm',
'arm64.h': 'Arm64',
Expand All @@ -86,7 +86,7 @@
's390x.h' : 'S390x',
'tricore.h' : 'TriCore',
'unicorn.h': 'Unicorn',
'comment_open': '//',
'comment_open': ' //',
'comment_close': '',
},
'dotnet': {
Expand Down Expand Up @@ -159,8 +159,9 @@ def gen(lang):
templ = template[lang]
for target in include:
prefix = templ[target]
outfile = open(templ['out_file'] %(prefix), 'wb') # open as binary prevents windows newlines
outfile.write((templ['header'] % (prefix)).encode("utf-8"))
outfn = templ['out_file'] % prefix
outfile = open(outfn + ".tmp", 'wb') # open as binary prevents windows newlines
outfile.write((templ['header'] % prefix).encode("utf-8"))
if target == 'unicorn.h':
prefix = ''
with open(os.path.join(INCL_DIR, target)) as f:
Expand Down Expand Up @@ -278,6 +279,19 @@ def gen(lang):
outfile.write((templ['footer']).encode("utf-8"))
outfile.close()

if os.path.isfile(outfn):
with open(outfn, "rb") as infile:
cur_data = infile.read()
with open(outfn + ".tmp", "rb") as infile:
new_data = infile.read()
if cur_data == new_data:
os.unlink(outfn + ".tmp")
else:
os.unlink(outfn)
os.rename(outfn + ".tmp", outfn)
else:
os.rename(outfn + ".tmp", outfn)

def main():
lang = sys.argv[1]
if lang == "all":
Expand Down
1 change: 1 addition & 0 deletions bindings/java/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
target/
54 changes: 34 additions & 20 deletions bindings/java/Makefile
Original file line number Diff line number Diff line change
@@ -1,29 +1,43 @@
.PHONY: gen_const clean jar all lib samples install
# Makefile for the native JNI library. Automatically called by Maven.

all: gen_const
$(MAKE) -f Makefile.build all
JAVA_HOME ?= $(shell java -XshowSettings:properties -version 2>&1 | sed -n 's/ *java.home = //p')

lib:
$(MAKE) -f Makefile.build lib
ifeq ($(JAVA_HOME),)
$(error JAVA_HOME could not be determined; please set it manually (make JAVA_HOME=...))
endif

samples:
$(MAKE) -f Makefile.build samples
JAVA_INC := $(JAVA_HOME)/include
JAVA_PLATFORM_INC := $(shell dirname `find $(JAVA_INC) -name jni_md.h`)
UNICORN_INC := ../../include

jar:
$(MAKE) -f Makefile.build jar
OS := $(shell uname)
ifeq ($(OS),Darwin)
LIB_EXT=.dylib
else ifeq ($(OS),Linux)
LIB_EXT=.so
else
LIB_EXT=.dll
endif

install: lib jar
$(MAKE) -f Makefile.build install
all: libunicorn_java$(LIB_EXT)

uninstall:
$(MAKE) -f Makefile.build uninstall
CC=gcc
CFLAGS=-fPIC
LDFLAGS=-shared -fPIC
# May also use -lunicorn to dynamically link against the installed unicorn
LIBS=../../build/libunicorn.a
INCS=-I target/headers -I$(JAVA_INC) -I$(JAVA_PLATFORM_INC) -I$(UNICORN_INC)

gen_const:
cd .. && python3 const_generator.py java
OBJS=unicorn_Unicorn.o

unicorn_Unicorn.o: unicorn_Unicorn.c target/headers/unicorn_Unicorn.h
$(CC) -O2 -Wall -Wextra -Wno-unused-parameter -c $(CFLAGS) $(INCS) $< -o $@

libunicorn_java$(LIB_EXT): $(OBJS)
$(CC) -o $@ $(LDFLAGS) $(OBJS) $(LIBS)

clean:
rm -f unicorn/*.class
rm -f samples/*.class
rm -f *.so
rm -f *.dylib
rm -f *.dll
rm -f libunicorn_java$(LIB_EXT)
rm -f $(OBJS)

.PHONY: all clean
82 changes: 0 additions & 82 deletions bindings/java/Makefile.build

This file was deleted.

37 changes: 0 additions & 37 deletions bindings/java/README.TXT

This file was deleted.

39 changes: 39 additions & 0 deletions bindings/java/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
This documentation explains how to install the Java binding for Unicorn
from source.

0. Follow `docs/COMPILE.md` in the root directory to compile the core to the `build` directory.

Note: by default, the Java binding native library will be built by statically linking to
`../../build/libunicorn.a`, thereby removing `libunicorn` as a runtime dependency, but
making the produced native library `libunicorn_java` bigger.

If you instead want to dynamically link against the installed `libunicorn`, change
`LIBS=../../build/libunicorn.a` to `LIBS=-lunicorn` in `Makefile`.

1. Install a JDK for your platform.

2. Install Maven: https://maven.apache.org/install.html.

3. Change directories into the java bindings and build the Maven package:

$ mvn package

This will automatically build and test the Unicorn Java bindings.

The bindings consist of the native JNI library (`libunicorn_java.{so,dylib,dll}`)
and the Java JAR (`target/unicorn-2.xx.jar`). You will need to have the native
library on `java.library.path` and the JAR on your classpath.

The `src/main/test/java` directory contains some sample code to show how to use Unicorn API.
`samples` is a set of sample classes showcasing the various features of the Unicorn API,
while `tests` is a set of JUnit tests for the API.

- `Sample_<arch>.java`:
These show how to access architecture-specific information for each
architecture.

- `Shellcode.java`:
This shows how to analyze a Linux shellcode.

- `SampleNetworkAuditing.java`:
Unicorn sample for auditing network connection and file handling in shellcode.
Loading

0 comments on commit 43597af

Please sign in to comment.