There are two ways to register JNI functions, namely static registration and dynamic registration. The corresponding codes are as follows:
Static registration:
Statically registered method names Java_
start with .
Dynamic registration:
Dynamic registration is registered by calling the RegisterNatives method.
static registration
Understanding the registration process of these two registration methods is the prerequisite for learning vmp. The following first analyzes the static registration process.
When loading a class, first obtain the class information, if it has properties and methods, call LoadClassMembers to load the class
The front part of the LoadClassMembers method is the loading of static attributes and instance attributes, and the latter is the loading of instance methods and static methods. I only posted the method loading in the above picture. From the source code, we can see that there are two steps to load the method——LoadMethod, LinkCode
loadMethod is to initialize the ArtMethod instance object in the parameter
The first half of LinkCode judges whether it is a class compiled by oat and whether it needs to be interpreted and executed by an interpreter. Since the reinforcement manufacturer usually blocks the compilation of dex into oat, the return value of the ShouldUseInterpreterEntrypoint method should be true
When the method is a native method, call UnregisterNative() for the first registration. This method will be called whether it is static registration or dynamic registration. The difference between the two registration methods is mainly in the second registration. Let’s not say more. Enter this method to see
The code is very simple. Set the return value of GetJniDlsymLookupStub() as the entry point. What is the return value of GetJniDlsymLookupStub()?
The address pointed to by the function pointer is returned art_jni_dlsym_lookup_stub
, let's see what this function is
You can see that this function is written in assembly, open the arm 32-bit code to have a look
The assembly method calls the artFindNativeMethod method, follow up and take a look
It can be seen from the comments that the FindCodeForNativeMethod method returns the address of the method, and the second registration is performed through the RegisterNative method, which is the entire process of static registration.
If you continue to follow up the FindCodeForNativeMethod method, you will find the reason why the static registration starts with Java_. The key code is posted below, and interested readers can study it by themselves.
dynamic registration
For dynamic registration, the first registration is the same as the first registration position of static registration, which is the UnregisterNative() method, and the second registration of dynamic registration is completed by the programmer, mainly through the JNI_OnLoad method. Call the RegisterNatives method to register, follow up the implementation of the RegisterNatives method below
This method traverses the methods array, the member of which is the JNINativeMethod structure, and obtains its corresponding java name, signature information and concretely implemented function pointer
Finally, each method is registered with RegisterNative, and the dynamic registration process is now complete.
Summarize
The first registration of static registration and dynamic registration is realized by calling the UnregisterNative() method, the second registration of static registration is called the RegisterNative method, and the second registration of dynamic registration is the RegisterNatives method actively called by the programmer Register all the methods in the methods array, but finally call the RegisterNative method to register.