Android逆向 JNI静态注册(c++和java交互)

  • A+
所属分类:Asura笔记本
摘要

请看NCK大佬的文章:https://www.cnblogs.com/fuhua/p/12695436.html先加个textview方便输出调试信息

Android逆向 JNI静态注册(c++和java交互)

使用Android Studio新建JNi项目

请看NCK大佬的文章:

https://www.cnblogs.com/fuhua/p/12695436.html

先加个textview方便输出调试信息

 1  2  3  4  5  6  7  8  9 10 11 12 13 14 15 
<?xml version="1.0" encoding="utf-8"?> <androidx.coordinatorlayout.widget.CoordinatorLayout xmlns:android="http://schemas.android.com/apk/res/android"     xmlns:app="http://schemas.android.com/apk/res-auto"     xmlns:tools="http://schemas.android.com/tools"     android:layout_width="match_parent"     android:layout_height="match_parent"     tools:context=".MainActivity">      <TextView         android:id="@+id/TextViewDebug"         android:layout_width="match_parent"         android:layout_height="match_parent"         android:gravity="center"         android:text="TextView" /> </androidx.coordinatorlayout.widget.CoordinatorLayout> 

Android逆向 JNI静态注册(c++和java交互)

1. JNI普通字段,静态字段互操作.

目标: 获取普通字段的值,设置普通字段的值,获取静态字段的值,设置静态字段的值。

编辑java文件加入静态字段和四个将要写到jni中的方法:
如下:

 1  2  3  4  5  6  7  8  9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 
package com.example.jnidemo2;  import android.os.Bundle;  import com.google.android.material.floatingactionbutton.FloatingActionButton; import com.google.android.material.snackbar.Snackbar;  import androidx.appcompat.app.AppCompatActivity; import androidx.appcompat.widget.Toolbar;  import android.view.View; import android.view.Menu; import android.view.MenuItem; import android.widget.TextView; import android.widget.Toast;  public class MainActivity extends AppCompatActivity {      static {         System.loadLibrary("hello");     }      private String ReflectionField = "Reflection Field";     private static String StaticReflectionField = "Static Reflection Field";      private native String get_reflection_field();      private native String get_static_reflection_field();      private native void set_reflection_field(String value);      private native void set_static_reflection_field(String value);      @Override      protected void onCreate(Bundle savedInstanceState) {         super.onCreate(savedInstanceState);         setContentView(R.layout.activity_main);          //首先获取字段         String debug_string = "获取字段/r/n";         debug_string += "1:普通字段=>" + get_reflection_field() + "/r/n";         debug_string += "2:静态字段=>" + get_static_reflection_field() + "/r/n";  //        Toast.makeText(MainActivity.this, "1:普通字段=>" + get_reflection_field(), Toast.LENGTH_LONG).show(); //        Toast.makeText(MainActivity.this, "2:静态字段=>" + get_static_reflection_field(), Toast.LENGTH_LONG).show();          //设置字段         String set_field = "Setting Reflection Field";         set_reflection_field(set_field);         String set_static_field = "Setting Static Reflection Field";         set_reflection_field(set_static_field);          debug_string += "设置字段/r/n";         debug_string +="3:普通字段=>" + ReflectionField+"/r/n";         debug_string +="4:静态字段=>" + StaticReflectionField+ "/r/n";          TextView txtOutputDebug=(TextView) findViewById(R.id.TextViewDebug);         txtOutputDebug.setText(debug_string );  //        Toast.makeText(this, "3:普通字段=>" + ReflectionField, Toast.LENGTH_LONG).show(); //        Toast.makeText(this, "4:静态字段=>" + StaticReflectionField, Toast.LENGTH_LONG).show();     }      @Override     public boolean onCreateOptionsMenu(Menu menu) {         // Inflate the menu; this adds items to the action bar if it is present.         getMenuInflater().inflate(R.menu.menu_main, menu);         return true;     }      @Override     public boolean onOptionsItemSelected(MenuItem item) {         // Handle action bar item clicks here. The action bar will         // automatically handle clicks on the Home/Up button, so long         // as you specify a parent activity in AndroidManifest.xml.         int id = item.getItemId();          //noinspection SimplifiableIfStatement         if (id == R.id.action_settings) {             return true;         }          return super.onOptionsItemSelected(item);     } } 

接下来生成jni

1 2 3 
# 因为我这里用的utf-8的字符来保存源文件 所以这里要加上 -encoding UTF-8 # 否则会出现:   错误: 编码GBK的不可映射字符 javah  -encoding UTF-8 -jni -d ../jni com.example.jnidemo2.MainActivity 

这是看到已经生成好了头文件
Android逆向 JNI静态注册(c++和java交互)

头文件内容如下

 1  2  3  4  5  6  7  8  9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 
/* DO NOT EDIT THIS FILE - it is machine generated */ #include <jni.h> /* Header for class com_example_jnidemo2_MainActivity */  #ifndef _Included_com_example_jnidemo2_MainActivity #define _Included_com_example_jnidemo2_MainActivity #ifdef __cplusplus extern "C" { #endif /*  * Class:     com_example_jnidemo2_MainActivity  * Method:    get_reflection_field  * Signature: ()Ljava/lang/String;  */ JNIEXPORT jstring JNICALL Java_com_example_jnidemo2_MainActivity_get_1reflection_1field   (JNIEnv *, jobject);  /*  * Class:     com_example_jnidemo2_MainActivity  * Method:    get_static_reflection_field  * Signature: ()Ljava/lang/String;  */ JNIEXPORT jstring JNICALL Java_com_example_jnidemo2_MainActivity_get_1static_1reflection_1field   (JNIEnv *, jobject);  /*  * Class:     com_example_jnidemo2_MainActivity  * Method:    set_reflection_field  * Signature: (Ljava/lang/String;)V  */ JNIEXPORT void JNICALL Java_com_example_jnidemo2_MainActivity_set_1reflection_1field   (JNIEnv *, jobject, jstring);  /*  * Class:     com_example_jnidemo2_MainActivity  * Method:    set_static_reflection_field  * Signature: (Ljava/lang/String;)V  */ JNIEXPORT void JNICALL Java_com_example_jnidemo2_MainActivity_set_1static_1reflection_1field   (JNIEnv *, jobject, jstring);  #ifdef __cplusplus } #endif #endif 

接下来编写cpp文件 实现头文件中的方法

源码如下

 1  2  3  4  5  6  7  8  9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 
// // Created by asura on 2020/4/24. //  #include "com_example_jnidemo2_MainActivity.h"  /*  * Class:     com_example_jnidemo2_MainActivity  * Method:    get_reflection_field  * Signature: ()Ljava/lang/String;  */ extern "C" JNIEXPORT jstring JNICALL Java_com_example_jnidemo2_MainActivity_get_1reflection_1field(JNIEnv *env, jobject obj) {     auto clazz = env->FindClass("com/example/jnidemo2/MainActivity");     auto fieldId = env->GetFieldID(clazz, "ReflectionField", "Ljava/lang/String;");     auto pJstring = (jstring) env->GetObjectField(obj, fieldId);     return pJstring; }  /*  * Class:     com_example_jnidemo2_MainActivity  * Method:    get_static_reflection_field  * Signature: ()Ljava/lang/String;  */ extern "C" JNIEXPORT jstring JNICALL Java_com_example_jnidemo2_MainActivity_get_1static_1reflection_1field(JNIEnv *env, jobject obj) {     auto clazz = env->FindClass("com/example/jnidemo2/MainActivity");     auto fieldId = env->GetStaticFieldID(clazz, "StaticReflectionField", "Ljava/lang/String;");     auto pJstring = (jstring) env->GetStaticObjectField(clazz, fieldId);     return pJstring; }  /*  * Class:     com_example_jnidemo2_MainActivity  * Method:    set_reflection_field  * Signature: (Ljava/lang/String;)V  */ extern "C" JNIEXPORT void JNICALL Java_com_example_jnidemo2_MainActivity_set_1reflection_1field(JNIEnv *env, jobject obj,jstring str) {     auto clazz = env->FindClass("com/example/jnidemo2/MainActivity");     auto fieldId = env->GetFieldID(clazz, "ReflectionField", "Ljava/lang/String;");     env->SetObjectField(obj,fieldId,str); }  /*  * Class:     com_example_jnidemo2_MainActivity  * Method:    set_static_reflection_field  * Signature: (Ljava/lang/String;)V  */ extern "C" JNIEXPORT void JNICALL Java_com_example_jnidemo2_MainActivity_set_1static_1reflection_1field(JNIEnv *env, jobject obj, jstring str) {     auto clazz = env->FindClass("com/example/jnidemo2/MainActivity");     auto fieldId = env->GetStaticFieldID(clazz, "StaticReflectionField", "Ljava/lang/String;");     env->SetStaticObjectField(clazz,fieldId,str); } 

编译后使用模拟器打开

Android逆向 JNI静态注册(c++和java交互)
成功!!

2. JNI普通方法,静态方法调用。

java代码中增加静态方法和普通方法:

 1  2  3  4  5  6  7  8  9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 
package com.example.jnidemo2;  import android.os.Bundle;  import com.google.android.material.floatingactionbutton.FloatingActionButton; import com.google.android.material.snackbar.Snackbar;  import androidx.appcompat.app.AppCompatActivity; import androidx.appcompat.widget.Toolbar;  import android.view.View; import android.view.Menu; import android.view.MenuItem; import android.widget.TextView; import android.widget.Toast;  public class MainActivity extends AppCompatActivity {      static {         System.loadLibrary("hello");     }      private String ReflectionField = "Reflection Field";     private static String StaticReflectionField = "Static Reflection Field";      private native String get_reflection_field();      private native String get_static_reflection_field();      private native void set_reflection_field(String value);      private native void set_static_reflection_field(String value);      private native String CallMethod(String watermark);      private native String CallStaticMethod(String watermark);      private static String StaticDemoMethod(String str) {         return "Static Call End" + str + "/r/n";     }      private String DemoMethod(String str) {         return "Call End" + str + "/r/n";     }      @Override     protected void onCreate(Bundle savedInstanceState) {         super.onCreate(savedInstanceState);         setContentView(R.layout.activity_main);          //首先获取字段         String debug_string = "----------获取字段/r/n";         debug_string += "1:普通字段=>" + get_reflection_field() + "/r/n";         debug_string += "2:静态字段=>" + get_static_reflection_field() + "/r/n";  //        Toast.makeText(MainActivity.this, "1:普通字段=>" + get_reflection_field(), Toast.LENGTH_LONG).show(); //        Toast.makeText(MainActivity.this, "2:静态字段=>" + get_static_reflection_field(), Toast.LENGTH_LONG).show();          //设置字段         set_reflection_field("Setting Reflection Field");         set_static_reflection_field("Setting Static Reflection Field");          debug_string += "---------------设置字段/r/n";         debug_string += "3:普通字段=>" + ReflectionField + "/r/n";         debug_string += "4:静态字段=>" + StaticReflectionField + "/r/n";  //        Toast.makeText(this, "3:普通字段=>" + ReflectionField, Toast.LENGTH_LONG).show(); //        Toast.makeText(this, "4:静态字段=>" + StaticReflectionField, Toast.LENGTH_LONG).show();          debug_string += "----------------jni调用 /r/n";         debug_string += CallMethod("JNI_MARK ");         debug_string += CallStaticMethod("JNI_STATIC_MARK");         TextView txtOutputDebug = (TextView) findViewById(R.id.TextViewDebug);         txtOutputDebug.setText(debug_string);     }      @Override     public boolean onCreateOptionsMenu(Menu menu) {         // Inflate the menu; this adds items to the action bar if it is present.         getMenuInflater().inflate(R.menu.menu_main, menu);         return true;     }      @Override     public boolean onOptionsItemSelected(MenuItem item) {         // Handle action bar item clicks here. The action bar will         // automatically handle clicks on the Home/Up button, so long         // as you specify a parent activity in AndroidManifest.xml.         int id = item.getItemId();          //noinspection SimplifiableIfStatement         if (id == R.id.action_settings) {             return true;         }          return super.onOptionsItemSelected(item);     } }  

继续生成头文件 并且书写对应的 代码
这里就不放全图了 放个写好的c++ 方法

 1  2  3  4  5  6  7  8  9 10 11 12 13 14 15 16 17 18 19 20 
 extern "C" JNIEXPORT jstring JNICALL Java_com_example_jnidemo2_MainActivity_CallMethod         (JNIEnv *env, jobject jobj, jstring watermark) {     auto clazz = env->FindClass("com/example/jnidemo2/MainActivity");     auto method_id = env->GetMethodID(clazz, "DemoMethod",                                       "(Ljava/lang/String;)Ljava/lang/String;");     auto method_return = (jstring) env->CallObjectMethod(jobj, method_id, watermark);      return method_return; }  extern "C" jstring JNICALL Java_com_example_jnidemo2_MainActivity_CallStaticMethod         (JNIEnv *env, jobject jobj, jstring watermark) {     auto clazz = env->FindClass("com/example/jnidemo2/MainActivity");     auto static_method_id = env->GetStaticMethodID(clazz, "StaticDemoMethod",                                                    "(Ljava/lang/String;)Ljava/lang/String;");     auto static_method_return = (jstring) env->CallStaticObjectMethod(clazz, static_method_id,                                                                       watermark);     return static_method_return; } 

编译输出:

Android逆向 JNI静态注册(c++和java交互)

代码详见:

https://github.com/luodaoyi/Android_JNI/tree/master/03_JNI_register2

发表评论

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen: