【APP逆向13】JNI开发简介之一

  • 简介:在一些不一般的APP中,核心算法不是直接写在java代码中,如果直接写在java中,逆向人员只需要简单的反编译就能找到;如是就出现了JNI:java native interface ,Java本地开发接口,实现JAVA和C语言之间的相互调用。将核心算法写在C语言中。

  • 1.正向开发流程

    • 1.1:新建一个java类,实现核心算法
    • 注意,看到native关键字,就说明此方法具体实现在C语言中实现
package com.nb.s6dayin;
public class Utils {

    static {
        System.loadLibrary("utils");   //对应的C文件
    }

    public native static int v1(int a1, int a2);

    public static native String v2(String old);   //native--说明具体实现在C语言中
}
  • 1.2:创建C文件,实现具体算法

#include <jni.h>

JNIEXPORT jint
JNICALL Java_com_nb_s6dayin_Utils_v1(JNIEnv *env, jclass clazz, jint a1, jint a2) {
    // 编写C语言的代码
    return a1 + a2 + 100;
}
  • 1.3:C编译配置

  • 1.4:java调用C语言

  • 1.5:当我们逆向某APP找到对应的native关键字方法时,就需要找到对应的so(压缩APK后,解压--lib--找到对应的so文件,名称一般为:lib+C文件名称)文件,查看C语言实现


  • 2.java调用C示例

    • 2.1:数字处理
public static native int v1(int v1, int v2);

#include <jni.h>
JNIEXPORT jint
JNICALL Java_com_nb_s4luffy_EncryptUtils_v1(JNIEnv *env, jclass clazz, jint v1, jint v2) {
    return v1 + v2;
}
  • 2.2:字符串修改,指针
public static native String v2(String old);

#include <jni.h>
#include <string.h>
#include <syslog.h>

JNIEXPORT jstring

JNICALL
Java_com_nb_s5dabai_EncryptUtils_v2(JNIEnv *env, jclass clazz, jstring old) {
	
    // char info[]  = {'w','w','p','e',..'w'...};
    char *info = (*env)->GetStringUTFChars(env, old, 0);
    syslog(LOG_ERR, "%s", info);

    info += 1;
    *info = 'w';
    info += 3;
    *info = 'w';
    info -= 4;
    syslog(LOG_ERR, "%s", info);
    return (*env)->NewStringUTF(env, info);
}
  • 2.3:字符串修改-数组
public static native String v3(String old);

JNIEXPORT jstring

JNICALL
Java_com_nb_s4luffy_EncryptUtils_v3(JNIEnv *env, jclass clazz, jstring old) {
	// 字符串数组
    char *info = (*env)->GetStringUTFChars(env, old, 0);
    info[0] = 'x';
    info[5] = 'x';
    
    return (*env)->NewStringUTF(env, info);
}
  • 2.4:字符串拼接
public static native String v4(String name, String role);

#include <jni.h>
#include <string.h>
#include <syslog.h>
#include<stdlib.h>


int GetStringLen(char *dataString) {
    int count = 0;
    for (int i = 0; dataString[i] != '\0'; i++) {
        count += 1;
    }
    return count;
}

JNIEXPORT jstring

JNICALL
Java_com_nb_s4luffy_EncryptUtils_v4(JNIEnv *env, jclass clazz, jstring name, jstring role) {
	
    // 字符数组=指针  alex   dsb
    char *nameString = (*env)->GetStringUTFChars(env, name, 0);
    char *roleString = (*env)->GetStringUTFChars(env, role, 0);
	
    // alexdsb
    char *result = malloc(GetStringLen(nameString) + GetStringLen(roleString) + 1);
    
    strcpy(result, nameString);
    strcat(result, roleString);
    syslog(LOG_ERR, "%s", result);
    return (*env)->NewStringUTF(env, result);
}
  • 2.5:字符处理
String n5 = EncryptUtils.v5("name=xwl&age=19");
public static native String v5(String data);

#include <jni.h>
#include <string.h>
#include <syslog.h>
#include<stdlib.h>

int GetStringLen(char *dataString) {
    int count = 0;
    for (int i = 0; dataString[i] != '\0'; i++) {
        count += 1;
    }
    return count;
}


JNIEXPORT jstring
JNICALL
Java_com_nb_s4luffy_EncryptUtils_v5(JNIEnv *env, jclass clazz, jstring data) {
	
    // "name=xwl&age=19"
    char *urlParams = (*env)->GetStringUTFChars(env, data, 0);
    int size = GetStringLen(urlParams);
	
    // v34 = {1,2,,,,,,,,,,,}
    char v34[size * 2];
    
    char *v28 = v34;

    for (int i = 0; urlParams[i] != '\0'; i++) {
        //syslog(LOG_ERR, "%02x", urlParams[i]);
        sprintf(v28, "%02x", urlParams[i]);
        v28 += 2;
    }

    return (*env)->NewStringUTF(env, v34);
}
  • 2.6:字节处理
String n6 = EncryptUtils.v6("name=xwl&age=19".getBytes());
public static native String v6(byte[] data);

#include <jni.h>
#include <string.h>
#include <syslog.h>
#include<stdlib.h>

JNICALL
Java_com_nb_s4luffy_EncryptUtils_v6(JNIEnv *env, jclass clazz, jbyteArray data) {

//    jbyte *byteArray = (*env)->GetByteArrayElements(env, data, 0);
    char *byteArray = (*env)->GetByteArrayElements(env, data, 0);
    int size = (*env)->GetArrayLength(env, data);

    char v34[size * 2];
    char *v28 = v34;

    for (int i = 0; byteArray[i] != '\0'; i++) {
        syslog(LOG_ERR, "%02x", byteArray[i]);
        sprintf(v28, "%02x", byteArray[i]);
        v28 += 2;
    }

    return (*env)->NewStringUTF(env, v34);
}
posted @ 2024-02-05 21:29  Tony_xiao  阅读(67)  评论(0编辑  收藏  举报