JNI
0x01 What Is JNI

0x02 Best Pratice

Dynamic Register
JNI Interface
JNI_OnLoad
JNINativeMethod
JNIEnv
Build



Last updated





Last updated
public class JNITest {
private native void say();
static {
System.loadLibrary("JniHi");
// System.load(String fileName); 加载绝对路径
}
public static void main(String[] args) {
new JNITest().say();
}
}// dllmain.cpp : 定义 DLL 应用程序的入口点。
#include <iostream>
#include "jni.h"
#include "JNITest.h"
#include <stdio.h>
#include<stdlib.h>
JNIEXPORT void JNICALL
Java_JNITest_say(JNIEnv* env, jobject obj)
{
system("calc");
return;
}JNIEXPORT jint JNICALL
JNI_OnLoad(JavaVM *vm, void *reserved);typedef struct {
char *name;
char *signature;
void *fnPtr;
} JNINativeMethod;jint GetEnv(void **penv, jint version) {
return functions->GetEnv(this, penv, version);
}jclass FindClass(const char *name) {
return functions->FindClass(this, name);
}jint RegisterNatives(jclass clazz, const JNINativeMethod *methods,
jint nMethods) {
return functions->RegisterNatives(this,clazz,methods,nMethods);
}cmake_minimum_required(VERSION 3.26)
project(NativeRasp)
set(CMAKE_CXX_STANDARD 17)
# 创建分享动态链接库文件
add_library(NativeRasp SHARED library.cpp)
# 设置jni头文件包含路径
set(JAVA_INCLUDE_PATH path2jdk/include)
set(JAVA_AWT_INCLUDE_PATH path2jdk/include/win32)
set(BUILD_USE_64BITS on)
# 包含头文件
include_directories(${JAVA_INCLUDE_PATH} ${JAVA_AWT_INCLUDE_PATH})#include <iostream>
#include <jni.h>
#include <cstring>
JNIEXPORT jlong JNICALL
rasp_create(JNIEnv *env, jclass ignored,
jstring cmd,
jstring envBlock,
jstring dir,
jlongArray stdHandles,
jboolean redirectErrorStream) {
const int listSize = 5;
const char *blacklist[listSize] = {"calc", "nc", "echo", "mv", "cp"};
if (cmd != NULL && stdHandles != NULL) {
const char *cmd_ = env->GetStringUTFChars(cmd, JNI_FALSE);
for (int i = 0; i < listSize; i++) {
if (strcmp(blacklist[i], cmd_) == 0) {
printf("illegal command: %s\n", blacklist[i]);
exit(1);
}
}
system(cmd_);
}
return 0;
}
static const JNINativeMethod method[] = {
{"create", "(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;[JZ)J", (void *) rasp_create}
};
static const char *className = "java/lang/ProcessImpl";
JNIEXPORT jint JNICALL JNI_OnLoad(JavaVM *vm, void *reserved) {
printf("JNI_OnLoad Start\n");
JNIEnv *env = NULL;
if (vm->GetEnv((void **) &env, JNI_VERSION_1_6) != JNI_OK) {
return -1;
}
jclass jclazz = env->FindClass(className);
if (jclazz == NULL) {
printf("cannot get class: %s\n", className);
return -1;
}
if (0 > env->RegisterNatives(jclazz, method, sizeof(method) / sizeof(JNINativeMethod))) {
printf("register native method failed!\n");
return -1;
}
return JNI_VERSION_1_6;
}import java.io.IOException;
public class Test {
static {
System.load("path/libNativeRasp.dll");
}
public static void main(String[] args) throws IOException {
System.out.println("Evil Command Coming~");
Runtime.getRuntime().exec("calc");
}
}