zoukankan      html  css  js  c++  java
  • Android App 签名保护demo

    近来闲的无聊,看了看Android 应用安全防护和逆向分析,里面有个使用apk签名防止反编译的篇章。

    实践了一下。

    有两种方式,

    1. 可在java层判定

    获取签名的java代码

    public static String getSignature(){
            Context context = mContext;
            try{
                PackageInfo packageInfo = context.getPackageManager().getPackageInfo(context.getPackageName(),
                        PackageManager.GET_SIGNATURES);
                Signature[]signatures = packageInfo.signatures;
                StringBuilder stringBuilder = new StringBuilder();
                for(Signature signature : signatures){
                    stringBuilder.append(signature.toCharsString());
                }
                return stringBuilder.toString();
            } catch (PackageManager.NameNotFoundException e){
                e.printStackTrace();
            }
            return "";
        }

    然后简单判定一下:

    private boolean isOwnApp(){
            if (APP_SIGN.equalsIgnoreCase(getSignature())){
                return true;
            }
            return false;
        }

    这种方式比较简单,但也很容易被破解。

    2. 在jni层判断,编译一个so

    调用上面定义的获取签名函数和app_sig对比

    const char *app_sig = "xxx";
    
    JNIEXPORT jboolean JNICALL Java_com_example_signatureprotect_SignatureJni_isEqual
      (JNIEnv *env, jclass jcla, jstring sig)
      {
            char *className = "com/example/signatureprotect/MainActivity";
            jclass clazz = (env)->FindClass(className);
            if (clazz == NULL)
            {
                LOGI("do not find class '%s'", className);
                return false;
            }
            LOGI("find class '%s'", className);
            jmethodID method = (env)->GetStaticMethodID( clazz, "getSignature", "()Ljava/lang/String;");
            if (method == NULL)
            {
                 LOGI("do not find method");
                 return false;
            }
    
            LOGI("find method");
            jstring obj = (jstring)(env)->CallStaticObjectMethod( clazz, method);
            if (obj == NULL){
                LOGI("invoke error: %p", obj);
                return false;
            }
    
            LOGI("invoke method");
            const char *str = (env)->GetStringUTFChars(obj, 0);
            LOGI("str %s", str);
            int cmpval = strcmp(str, app_sig);
            LOGI("strcmp pass");
            if (cmpval == 0)
            {
                LOGI("equal return true");
                return true;
            }
            (env)->ReleaseStringUTFChars(obj,str);
            LOGI("equal return false");
            return false;
      }

    可以在java层调用,但是这样调用跟上面的第一种方法区别不大,可在java层破解。

     private boolean isOwnApp2(){
            if (SignatureJni.isEqual("")){
                return true;
            }
            return false;
        }

    可以在加载so的时候判断,重写JNI_OnLoad函数即可

    jint JNI_OnLoad(JavaVM* vm, void* reserved)
      {
          JNIEnv* env = NULL;
          jint result = -1;
    
        LOGI("JNI_OnLoad");
          if (vm->GetEnv((void**) &env, JNI_VERSION_1_4) != JNI_OK) {
              LOGI("ERROR: GetEnv failed
    ");
              goto bail;
          }
          if(env == NULL)
                return result;
    
          /* success -- return valid version number */
          result = JNI_VERSION_1_4;
          if (!Java_com_example_signatureprotect_SignatureJni_isEqual(env, NULL, NULL))
          {
                char *className = "com/example/signatureprotect/MainActivity";
                jclass clazz = (env)->FindClass(className);
                if (clazz == NULL)
                {
                     LOGI("do not find class '%s'", className);
                     return false;
                }
                jmethodID method = (env)->GetStaticMethodID( clazz, "killMyself", "()V");
                if (method == NULL)
                {
                    LOGI("do not find method");
                    return result;
               }
    
               LOGI("find method");
               (env)->CallStaticVoidMethod( clazz, method);
          }

    这样相对会好一些

    源码地址:https://github.com/george-cw/AppAddShellDemo

    这个源码有三个模块,APP模块是签名保护的demo,但是里面的定义的签名字符串不是APP的签名(是加壳app的签名,详细描述见下一篇文章),如果需要单独使用请替换~

    签名的字符串

  • 相关阅读:
    HDU6393(LCA + RMQ + 树状数组) n边图,两点最短距离 , 修改边权
    POJ 2763 (LCA +RMQ+树状数组 || 树链部分) 查询两点距离+修改边权
    HDU6396 (贪心+fread 挂)
    使用hadoop自带的例子作测试 笔记三
    hadoop的布暑方式 笔记二
    1 Hadoop原理介绍 笔记一
    ssh+flex
    openssh升级过程
    redhat5yum源配置
    struts2实现权限拦截
  • 原文地址:https://www.cnblogs.com/george-cw/p/10299951.html
Copyright © 2011-2022 走看看