SkillAgentSearch skills...

Jnihook

Hook Java methods natively from C/C++

Install / Use

/learn @rdbo/Jnihook
About this skill

Quality Score

0/100

Supported Platforms

Universal

README

JNIHook

jnihook-logo

Hook Java methods natively from C/C++

Made by Rdbo

License

This project is licensed under the GNU AGPL-3.0. No later version is allowed.

Read the file LICENSE for more information.

Examples

Hooking the function static int myFunction(int mynumber, String name) from a class Dummy:

jmethodID originalMethod;
jint hkMyFunction(JNIEnv *env, jclass clazz, jint number, jstring name)
{
	// Print parameters
	std::cout << "[*] mynumber value: " << mynumber << std::endl;
	std::cout << "[*] name object: " << name << std::endl;

	// Call the original method with 'mynumber' set to '1337'
	env->CallStaticIntMethod(dummyClass, originalMethod, 1337, name);

	return 42; // Modify the return value to '42'
}

void start(JavaVM *jvm)
{
	jclass dummyClass = env->FindClass("dummy/Dummy");
	jmethodID myFunctionID = env->GetStaticMethodID(dummyClass, "myFunction",
							"(ILjava/lang/String;)I");

	JNIHook_Init(jvm);
	JNIHook_Attach(myFunctionID, reinterpret_cast<void*>(hkMyFunction), &originalMethod);
}

Hooking the constructor from a class Target:

jmethodID originalInit;
void hkMyInit(JNIEnv *env, jobject object, jint number)
{
	// Print parameters
	std::cout << "[*] number value: " << number << std::endl;

	// Call the constructor with 'number' set to '1337'
	env->CallVoidMethod(object, originalInit, 1337);

	return;
}
void start(JavaVM *jvm)
{	
	jclass targetClass = env->FindClass("dummy/Target");
	jmethodID myInitID = env->GetMethodID(targetClass, "<init>", "(I)V");

	JNIHook_Init(jvm);
	JNIHook_Attach(myInitID, reinterpret_cast<void*>(hkMyInit), &originalInit);
}

Building

To build this, you can either compile all the files in src into your project, or use CMake to build a static library, which can be compiled into your project.

NOTE: This requires C++17, which is available on newer versions of Visual Studio and GCC.

The steps ahead are for building a static library with CMake.

  1. Setup your JAVA_HOME environment variable. It will be used for accessing jni.h, jvmti.h, and linking the jvm library. On Linux, it's usually on /usr/lib/jvm/<java release>, and on Windows at %ProgramFiles%\Java\jdk-<version>.

  1. Clone the project
git clone https://github.com/rdbo/jnihook --recursive

  1. Create a build directory inside the root directory of the repository and enter it:

NOTE: Use the x64 Native Tools Command Prompt on Windows.

mkdir build
cd build

  1. Run CMake to setup the project

Linux/*nix:

cmake .. -DCMAKE_BUILD_TYPE=Release

Windows:

cmake .. -DCMAKE_BUILD_TYPE=Release -G "NMake Makefiles" -DCMAKE_CXX_STANDARD=17

  1. Build using nmake (Windows) or make (*nix):

Linux/*nix:

make

Windows:

nmake

After running these commands, you will have libjnihook.a or jnihook.lib in your build directory, which you can compile along with your project.

NOTE: Don't forget to include JNIHook's include dir in your project so that you can #include <jnihook.h>.

Acknowledgements

Special thanks to:

  • @Lefraudeur for helping me with information about JVM functionality throughout jnihook V1 development.
  • @acuarica for the awesome JNIF library, which i modified to fit jnihook's use case.
  • @griffith1deady for providing me informations about JVM internals.
  • @TIMER-err for the jvm-runtime-noverify project, which made me realise I could patch flags at runtime cleanly.
  • @awrped for helping to fix Windows and JNIF issues.
  • myself for coming up with the V2 hooking method (c'mon, it was not an easy task)
  • @rewawe for the bytecode hooking methods (init, clinit, midfunction)
View on GitHub
GitHub Stars212
CategoryDevelopment
Updated4d ago
Forks37

Languages

C++

Security Score

95/100

Audited on Mar 23, 2026

No findings