From b72be3d018a77d81ab8150912933c3fe4d65843a Mon Sep 17 00:00:00 2001 From: mahongyin Date: Wed, 17 Nov 2021 23:43:24 +0800 Subject: [PATCH] =?UTF-8?q?=E9=AA=8C=E8=AF=81apk=20md5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 36 +++++++++++-------- app/libs/readme.txt | 1 + app/src/main/cpp/apisecurity-lib.cpp | 1 + .../java/cn/android/sample/MainActivity.java | 2 +- 防止二改/CheckVirtual.java | 2 +- 5 files changed, 26 insertions(+), 16 deletions(-) create mode 100644 app/libs/readme.txt diff --git a/README.md b/README.md index 837424e..6b44755 100644 --- a/README.md +++ b/README.md @@ -73,6 +73,14 @@ Android API Security(.so),安卓APP/API安全加密so库,防二次打包, ###2 签名验证 application名验证 防护签名校验 Jni验证 +虚拟机/模拟器检查 网络代理/VPN/SSL证书验证 + +混淆 加固 + +https://juejin.cn/post/7024695135535366151 + +https://juejin.cn/post/7001409376745422885 + ![jni属性签名](jni属性签名.jpg) @@ -114,18 +122,18 @@ JNIEXPORT void JNICALL Java_com_test_JniTest_accessField jfieldID fid = (*env)->GetFieldID(env, clz, "str", "Ljava/lang/String;"); //通过属性ID拿到属性的值 jstring jstr = (*env)->GetObjectField(env, jobj, fid); - + //通过Java字符串拿到C字符串,第三个参数是一个出参,用来告诉我们GetStringUTFChars内部是否复制了一份字符串 //如果没有复制,那么出参为isCopy,这时候就不能修改字符串的值了,因为Java中常量池中的字符串是不允许修改的(但是jstr可以指向另外一个字符串) char* cstr = (*env)->GetStringUTFChars(env, jstr, NULL); //在C层修改这个属性的值 char res[20] = "I love you : "; strcat(res, cstr); - + //重新生成Java的字符串,并且设置给对应的属性 jstring jstr_new = (*env)->NewStringUTF(env, res); (*env)->SetObjectField(env, jobj, fid, jstr_new); - + //最后释放资源,通知垃圾回收器来回收 //良好的习惯就是,每次GetStringUTFChars,结束的时候都有一个ReleaseStringUTFChars与之呼应 (*env)->ReleaseStringUTFChars(env, jstr, cstr); @@ -218,17 +226,17 @@ JNIEXPORT void JNICALL Java_com_test_JniTest_accessStaticMethod //调用java的静态方法,拿到返回值 jstring jstr = (*env)->CallStaticObjectMethod(env, clz, mid); - + //把拿到的Java字符串转换为C的字符串 char* cstr= (*env)->GetStringUTFChars(env, jstr, NULL); - + //后续操作,产生以UUID为文件名的文件 char fielName[100]; sprintf(fielName, "D:\\%s.txt", cstr); FILE* f = fopen(fielName, "w"); fputs(cstr, f); fclose(f); - + printf("output from C : File had saved", jstr); } 最后在Java中测试: @@ -284,7 +292,7 @@ JNIEXPORT void JNICALL Java_com_test_JniTest_accessNonvirtualMethod //拿到父类的类,以及speek的方法id jclass clz_human = (*env)->FindClass(env, "com/test/Human"); jmethodID mid = (*env)->GetMethodID(env, clz_human, "speek", "()V"); - + //调用自己的speek实现 (*env)->CallVoidMethod(env, man, mid); //调用父类的speek实现 @@ -323,15 +331,15 @@ JNIEXPORT jlong JNICALL Java_com_test_JniTest_accessConstructor //构造方法的函数名的格式是: //不能写类名,因为构造方法函数名都一样区分不了,只能通过参数列表(签名)区分 jmethodID mid_Date = (*env)->GetMethodID(env, clz_date, "", "()V");; - + //调用构造函数 jobject date = (*env)->NewObject(env, clz_date, mid_Date); - + //注意签名,返回值long的属性签名是J jmethodID mid_getTime= (*env)->GetMethodID(env, clz_date, "getTime", "()J"); //调用getTime方法 jlong jtime = (*env)->CallLongMethod(env, date, mid_getTime); - + return jtime; } 最后在Java中测试: @@ -395,20 +403,20 @@ JNIEXPORT jstring JNICALL Java_com_test_JniTest_testChineseOut //需要返回的字符串 char* c_str = "我爱你"; //jstring j_str = (*env)->NewStringUTF(env, c_str); - + //通过调用构造方法String string = new String(byte[], charsetName);来解决乱码问题 - + //0.找到String类 jclass clz_String = (*env)->FindClass(env, "java/lang/String"); jmethodID mid = (*env)->GetMethodID(env, clz_String, "", "([BLjava/lang/String;)V"); - + //准备new String的参数:byte数组以及字符集 //1.创建字节数组,并且将C的字符串拷贝进去 jbyteArray j_byteArray = (*env)->NewByteArray(env, strlen(c_str)); (*env)->SetByteArrayRegion(env, j_byteArray, 0, strlen(c_str), c_str); //2.创建字符集的参数,这里用Windows的more字符集GB2312 jstring charsetName = (*env)->NewStringUTF(env, "GB2312"); - + //调用 jstring j_new_str = (*env)->NewObject(env, clz_String, mid, j_byteArray, charsetName); return j_new_str; diff --git a/app/libs/readme.txt b/app/libs/readme.txt new file mode 100644 index 0000000..0e39f87 --- /dev/null +++ b/app/libs/readme.txt @@ -0,0 +1 @@ +这里的libold.so事apk hook替换签名用 \ No newline at end of file diff --git a/app/src/main/cpp/apisecurity-lib.cpp b/app/src/main/cpp/apisecurity-lib.cpp index 804171b..676ba45 100644 --- a/app/src/main/cpp/apisecurity-lib.cpp +++ b/app/src/main/cpp/apisecurity-lib.cpp @@ -71,6 +71,7 @@ jint getDeviceVersion(JNIEnv *env) { // LOGD("printByte:%s", hexA); //} +//签名验证 char *digest(JNIEnv *env, const char *algorithm, jbyteArray cert_byte) { jclass message_digest_class = env->FindClass("java/security/MessageDigest"); jmethodID methodId = env->GetStaticMethodID(message_digest_class, "getInstance", diff --git a/app/src/main/java/cn/android/sample/MainActivity.java b/app/src/main/java/cn/android/sample/MainActivity.java index f30af8a..d1e0d00 100644 --- a/app/src/main/java/cn/android/sample/MainActivity.java +++ b/app/src/main/java/cn/android/sample/MainActivity.java @@ -32,7 +32,7 @@ public class MainActivity extends AppCompatActivity { public void onClick(View v) { //API签名字符串 String aptStr="123456"; - tv.setText("Sign:" + APISecurity.sign(aptStr)); + tv.setText("Sign加盐:" + APISecurity.sign(aptStr)); } }); diff --git a/防止二改/CheckVirtual.java b/防止二改/CheckVirtual.java index 20b45a1..2ed5c91 100644 --- a/防止二改/CheckVirtual.java +++ b/防止二改/CheckVirtual.java @@ -154,7 +154,7 @@ public class CheckVirtual { } /** - * Return whether device is emulator. + * Return whether device is emulator.模拟器 * * @return {@code true}: yes
{@code false}: no */