Lazy loaded image
安卓逆向
NDK开发小结
字数 482阅读时长≈ 2 分钟
2021-8-31
2024-7-5
7
type
status
date
slug
summary
tags
category
icon
password

一、JNI

作用:用于java代码和C++、c代码的交互(代码混编)。
分类使用:Jni静态注册、jni动态注册

二、静态注册

1、定义被native修饰的方法

public native String Getstring();

2、根据java代码生成.h头文件(javah -jni 类的包名路径)

javah -jni com.example.jnitest.MainActivity

3、编写C/C++代码,导入.h头文件,实现我们.h头文件中方法

#include <JNItest.h> JNIEXPORT jstring JNICALL Java_com_example_jnitest_MainActivity_Getstring (JNIEnv *env, jobject obj) { jstring str = (*env)->NewStringUTF(env, "hello ndk"); return str; }

4、编写(配置)两个mk文件:application.mk/android.mk

#application.mk APP_ABI := armeabi #android.mk LOCAL_PATH := $(call my-dir) include $(CLEAR_VARS) LOCAL_MODULE := JNItest LOCAL_SRC_FILES := JNItest.c LOCAL_ARM_MODE := arm LOCAL_LDLIBS += -llog include $(BUILD_SHARED_LIBRARY)

5、通过ndk-build生成so文件

ndk-build

6、java代码中加载so文件/libs文件下去头去尾(头:lib;尾:.so)

static{ System.loadLibrary("JNItest"); }

7、build.gradle文件配置

androi -ddefaultConfig --ndk { // 设置支持的SO库架构 abiFilters 'armeabi' ,'x86', 'armeabi-v7a', 'x86_64','arm64-v8a' }

8、main创建jniLibs文件夹将so文件复制

main -jniLibs --armeabi ---libJNItest.so --armeabi-v7a ---libJNItest.so

三、动态注册

1、.c文件编写JNI_OnLoad

FindClass处填写对应类
JNIEXPORT jint JNICALL JNI_OnLoad(JavaVM* vm, void* reserved){ JNIEnv* env; if((*vm)->GetEnv(vm, (void**)&env, JNI_VERSION_1_4)!=JNI_OK){ return JNI_ERR; } jclass cls=(*env)->FindClass(env, "com/example/myjnireistest/MainActivity"); if((*env)->RegisterNatives(env, cls, jninativemethod,2)!=JNI_OK){ return JNI_ERR; } return JNI_VERSION_1_4; }

2、.c文件定义方法结构体

JNINativeMethod jninativemethod[]={ { "getInt", "()I", (void*)GetInt }, { "getChar", "()C", (void*)GetChar, } };

3、.c文件对应C函数

jint GetInt (JNIEnv *env, jobject obj){ return 99; } jchar GetChar(JNIEnv* env, jobject obj){ return 'y'; }

4、java代码逻辑

static { System.loadLibrary("MyJniTest"); } public native int getInt(); public native char getChar();

四、SO库获取java层字段值

//反射获取对应类 jclass clazz=(*env)->FindClass(env, "com/example/myjnilogin/MainActivity"); //获取实例字段id (env, clazz, 字段名,字段类型) jfieldID fieldid = (*env)->GetFieldID(env, clazz, "userId","Ljava/lang/String;"); //根据实例id获取对应的值 jstring jstr_user = (*env)->GetObjectField(env, obj, fieldid); //将string转化char const char* user= (*env)->GetStringUTFChars(env, jstr_user, 0);

五、SO库调用JAVA函数

//反射获取方法id jmethodID methodID = (*env)->GetMethodID(env,clazz, "pwError", "()V"); //call调用方法 (*env)->CallVoidMethod(env,obj, methodID);
上一篇
smali语法基础详解
下一篇
实战分析自毁程序Crackme IDA动态调试

评论
Loading...