为什么一个APK在模拟器和真实设备之间的jni中获得了不同的签名?

时间:2019-07-16 06:56:56

标签: android java-native-interface signature

我尝试在jni中打印签名,但是相同的apk在模拟器和真实设备之间得到不同的值。   有谁知道为什么会这样吗?

仿真器像素2:

2019-07-16 22:38:10.725 2620-4374/my.package.name I/jnitest.cpp: JNI::loadSignature, [
2019-07-16 22:38:10.725 2620-4374/my.package.name I/jnitest.cpp: JNI::loadSignature, 30
2019-07-16 22:38:10.725 2620-4374/my.package.name I/jnitest.cpp: JNI::loadSignature, ffffff82
2019-07-16 22:38:10.725 2620-4374/my.package.name I/jnitest.cpp: JNI::loadSignature, 1
2019-07-16 22:38:10.725 2620-4374/my.package.name I/jnitest.cpp: JNI::loadSignature, ffffffdd
2019-07-16 22:38:10.725 2620-4374/my.package.name I/jnitest.cpp: JNI::loadSignature, 30
2019-07-16 22:38:10.725 2620-4374/my.package.name I/jnitest.cpp: JNI::loadSignature, ffffff82
2019-07-16 22:38:10.725 2620-4374/my.package.name I/jnitest.cpp: JNI::loadSignature, 1
2019-07-16 22:38:10.725 2620-4374/my.package.name I/jnitest.cpp: JNI::loadSignature, 46
2019-07-16 22:38:10.725 2620-4374/my.package.name I/jnitest.cpp: JNI::loadSignature, 2
2019-07-16 22:38:10.726 2620-4374/my.package.name I/jnitest.cpp: JNI::loadSignature, 1
2019-07-16 22:38:10.726 2620-4374/my.package.name I/jnitest.cpp: JNI::loadSignature, 1
2019-07-16 22:38:10.726 2620-4374/my.package.name I/jnitest.cpp: JNI::loadSignature, 30
2019-07-16 22:38:10.726 2620-4374/my.package.name I/jnitest.cpp: JNI::loadSignature, d
2019-07-16 22:38:10.726 2620-4374/my.package.name I/jnitest.cpp: JNI::loadSignature, 6
2019-07-16 22:38:10.726 2620-4374/my.package.name I/jnitest.cpp: JNI::loadSignature, 9
2019-07-16 22:38:10.726 2620-4374/my.package.name I/jnitest.cpp: JNI::loadSignature, 2a
2019-07-16 22:38:10.726 2620-4374/my.package.name I/jnitest.cpp: JNI::loadSignature, ffffff86
2019-07-16 22:38:10.726 2620-4374/my.package.name I/jnitest.cpp: JNI::loadSignature, 48
2019-07-16 22:38:10.726 2620-4374/my.package.name I/jnitest.cpp: JNI::loadSignature, ffffff86
2019-07-16 22:38:10.726 2620-4374/my.package.name I/jnitest.cpp: JNI::loadSignature, fffffff7
2019-07-16 22:38:10.726 2620-4374/my.package.name I/jnitest.cpp: JNI::loadSignature, d
2019-07-16 22:38:10.726 2620-4374/my.package.name I/jnitest.cpp: JNI::loadSignature, 1
2019-07-16 22:38:10.726 2620-4374/my.package.name I/jnitest.cpp: JNI::loadSignature, 1
2019-07-16 22:38:10.726 2620-4374/my.package.name I/jnitest.cpp: JNI::loadSignature, 5
2019-07-16 22:38:10.726 2620-4374/my.package.name I/jnitest.cpp: JNI::loadSignature, 5
2019-07-16 22:38:10.726 2620-4374/my.package.name I/jnitest.cpp: JNI::loadSignature, ]
2019-07-16 22:38:10.727 2620-4374/my.package.name I/jnitest.cpp: JNI::checkSignature, appSignature [0x119], [.2.C35(B)649+0,C64*25D1060/7-566]

Real Device Huawei:

2019-07-16 14:36:44.245 13046-13402/my.package.name I/jnitest.cpp: JNI::loadSignature, [
2019-07-16 14:36:44.245 13046-13402/my.package.name I/jnitest.cpp: JNI::loadSignature, 30
2019-07-16 14:36:44.245 13046-13402/my.package.name I/jnitest.cpp: JNI::loadSignature, 82
2019-07-16 14:36:44.245 13046-13402/my.package.name I/jnitest.cpp: JNI::loadSignature, 1
2019-07-16 14:36:44.245 13046-13402/my.package.name I/jnitest.cpp: JNI::loadSignature, dd
2019-07-16 14:36:44.245 13046-13402/my.package.name I/jnitest.cpp: JNI::loadSignature, 30
2019-07-16 14:36:44.245 13046-13402/my.package.name I/jnitest.cpp: JNI::loadSignature, 82
2019-07-16 14:36:44.245 13046-13402/my.package.name I/jnitest.cpp: JNI::loadSignature, 1
2019-07-16 14:36:44.245 13046-13402/my.package.name I/jnitest.cpp: JNI::loadSignature, 46
2019-07-16 14:36:44.245 13046-13402/my.package.name I/jnitest.cpp: JNI::loadSignature, 2
2019-07-16 14:36:44.245 13046-13402/my.package.name I/jnitest.cpp: JNI::loadSignature, 1
2019-07-16 14:36:44.245 13046-13402/my.package.name I/jnitest.cpp: JNI::loadSignature, 1
2019-07-16 14:36:44.245 13046-13402/my.package.name I/jnitest.cpp: JNI::loadSignature, 30
2019-07-16 14:36:44.245 13046-13402/my.package.name I/jnitest.cpp: JNI::loadSignature, d
2019-07-16 14:36:44.245 13046-13402/my.package.name I/jnitest.cpp: JNI::loadSignature, 6
2019-07-16 14:36:44.245 13046-13402/my.package.name I/jnitest.cpp: JNI::loadSignature, 9
2019-07-16 14:36:44.245 13046-13402/my.package.name I/jnitest.cpp: JNI::loadSignature, 2a
2019-07-16 14:36:44.245 13046-13402/my.package.name I/jnitest.cpp: JNI::loadSignature, 86
2019-07-16 14:36:44.245 13046-13402/my.package.name I/jnitest.cpp: JNI::loadSignature, 48
2019-07-16 14:36:44.245 13046-13402/my.package.name I/jnitest.cpp: JNI::loadSignature, 86
2019-07-16 14:36:44.245 13046-13402/my.package.name I/jnitest.cpp: JNI::loadSignature, f7
2019-07-16 14:36:44.245 13046-13402/my.package.name I/jnitest.cpp: JNI::loadSignature, d
2019-07-16 14:36:44.245 13046-13402/my.package.name I/jnitest.cpp: JNI::loadSignature, 1
2019-07-16 14:36:44.245 13046-13402/my.package.name I/jnitest.cpp: JNI::loadSignature, 1
2019-07-16 14:36:44.245 13046-13402/my.package.name I/jnitest.cpp: JNI::loadSignature, 5
2019-07-16 14:36:44.245 13046-13402/my.package.name I/jnitest.cpp: JNI::loadSignature, 5
2019-07-16 14:36:44.245 13046-13402/my.package.name I/jnitest.cpp: JNI::loadSignature, ]
2019-07-16 14:36:44.245 13046-13402/my.package.name I/jnitest.cpp: JNI::checkSignature, appSignature [0x115], [E2EC358B9649B0CC64A25D1060F7D566]

java:

jstring loadSignature(JNIEnv *env, jobject context) {
//    __android_log_print(ANDROID_LOG_INFO, LOG_TAG, "JNI::loadSignature");

    jclass cls = env->GetObjectClass(context);
    jmethodID mid = env->GetMethodID(cls, "getPackageManager",
                                     "()Landroid/content/pm/PackageManager;");

    jobject pm = env->CallObjectMethod(context, mid);

    mid = env->GetMethodID(cls, "getPackageName", "()Ljava/lang/String;");
    jstring packageName = (jstring) env->CallObjectMethod(context, mid);

    cls = env->GetObjectClass(pm);
    mid = env->GetMethodID(cls, "getPackageInfo",
                           "(Ljava/lang/String;I)Landroid/content/pm/PackageInfo;");
    jobject packageInfo = env->CallObjectMethod(pm, mid, packageName, 0x40); //GET_SIGNATURES = 64;
    cls = env->GetObjectClass(packageInfo);
    jfieldID fid = env->GetFieldID(cls, "signatures", "[Landroid/content/pm/Signature;");
    jobjectArray signatures = (jobjectArray) env->GetObjectField(packageInfo, fid);
    jobject signature = env->GetObjectArrayElement(signatures, 0);

    cls = env->GetObjectClass(signature);
    mid = env->GetMethodID(cls, "toByteArray", "()[B");
    jbyteArray signatureByteArray = (jbyteArray) env->CallObjectMethod(signature, mid);

    env -> DeleteLocalRef(cls);
    env -> DeleteLocalRef(pm);
    env -> DeleteLocalRef(packageName);
    env -> DeleteLocalRef(packageInfo);
    env -> DeleteLocalRef(signatures);
    env -> DeleteLocalRef(signature);

    {
        // debug signature
        __android_log_print(ANDROID_LOG_INFO, LOG_TAG, "JNI::loadSignature, [");
        jboolean isCopy;
        jbyte *bytes = env->GetByteArrayElements(signatureByteArray, &isCopy);
        char *chars = (char *) bytes;
        for (int i = 0; i < strlen(chars); i++) {
            __android_log_print(ANDROID_LOG_INFO, LOG_TAG, "JNI::loadSignature, %x", chars[i]);
        }
        __android_log_print(ANDROID_LOG_INFO, LOG_TAG, "JNI::loadSignature, ]");
    }


    return jbyteArrayToMd5(env, signatureByteArray);
}


jboolean checkSignature(JNIEnv *env, jobject context) {
//    __android_log_print(ANDROID_LOG_INFO, LOG_TAG, "JNI::checkSignature");

    jstring appSignature = loadSignature(env, context);
    const char *charAppSignature = env->GetStringUTFChars(appSignature, 0);
    __android_log_print(ANDROID_LOG_INFO, LOG_TAG, "JNI::checkSignature, %4d, [%s]", strlen(charAppSignature), charAppSignature);
...

更新:

    2019-07-17 01:23:18.633 11560-13925/my.package.name I/jnitest.cpp: JNI::loadSignature, signaturesSize=1

    jsize signaturesSize = env->GetArrayLength(signatures);
        __android_log_print(ANDROID_LOG_INFO, LOG_TAG, "JNI::loadSignature, signaturesSize=%d", signaturesSize);

更新:

jstring jbyteArrayToMd5(JNIEnv *env, jbyteArray source) {
    //__android_log_print(ANDROID_LOG_INFO, LOG_TAG, "JNI::jbyteArrayToMd5");

    jclass classMessageDigest = env->FindClass("java/security/MessageDigest");
    jmethodID midGetInstance = env->GetStaticMethodID(classMessageDigest, "getInstance",
                                                      "(Ljava/lang/String;)Ljava/security/MessageDigest;");
    // MessageDigest object
    jobject objMessageDigest = env->CallStaticObjectMethod(classMessageDigest, midGetInstance,
                                                           env->NewStringUTF("md5"));

    jmethodID midUpdate = env->GetMethodID(classMessageDigest, "update", "([B)V");
    env->CallVoidMethod(objMessageDigest, midUpdate, source);

    jmethodID midDigest = env->GetMethodID(classMessageDigest, "digest", "()[B");
    jbyteArray objArraySign = (jbyteArray) env->CallObjectMethod(objMessageDigest, midDigest);

    jsize intArrayLength = env->GetArrayLength(objArraySign);
    jbyte *byte_array_elements = env->GetByteArrayElements(objArraySign, NULL);
    size_t length = (size_t) intArrayLength * 2 + 1;
    char *char_result = (char *) malloc(length);
    memset(char_result, 0, length);

    ByteToHexStr((const char *) byte_array_elements, char_result, intArrayLength);
    *(char_result + intArrayLength * 2) = '\0';

    jstring stringResult = env->NewStringUTF(char_result);
    // release
    env->ReleaseByteArrayElements(objArraySign, byte_array_elements, JNI_ABORT);
    free(char_result);
    env->DeleteLocalRef(classMessageDigest);
    env->DeleteLocalRef(objMessageDigest);

    return stringResult;
}

1 个答案:

答案 0 :(得分:0)

引用亚当·萨维奇(Adam Savage):这是您的问题! 您的ByteToHexStr接受带符号的字符并对它们进行位操作。 这些操作的行为是implementation defined

当您的MD5string的 parts 被破坏时,我注意到了这一点,而其他人则没有。现在您已经发布了ByteToHexStr的实现,我知道为什么了。 用于获取高半字节的右移运算符会保留输入的符号。 对于字节0xCC,这意味着高字节将通过以下步骤:

  • -0xC右移后
  • 0x2C添加了0x30,这是ASCII逗号(,

亲自看看:

#include <stdio.h>
int main() {
    signed char c = 0xCC;
    signed char low = c & 0xf;
    signed char high = c >> 4;
    printf("low: %d high: %d\n", low+0x30, high+0x30);
}

明确使用unsigned char而不是(signedchar应该可以解决此问题并使两个平台的行为相同。