qtfreet00 发表于 2016-1-3 19:32

一个小CM的出题思路

既然雨神师傅已经破了,对他来说简直是分分钟的事情,那我也就把自己写的思路发出来一下

由于水平十分有限,CM中没有任何高大上的东西,jni中的加密(也根本不能说加密),仅仅是一个base64

      Bitmap bitmap = BitmapFactory.decodeResource(getResources(), R.drawable.hmily);
      int raw = bitmap.getRowBytes();

首先大家看到的那张Hmily的图片其实就是题中的一个加密key,取到图片的大小然后截取第三位数字

      final int key = Integer.parseInt(String.valueOf(raw).substring(2));

                String answer = Encoding.encryptXOR(s, key);

//                Log.e("qtfreet",answer);

                boolean demo = check.mcheck(answer);
                if (demo){
                     mtextview.setText("恭喜,你竟然猜中的小明的心思");
                  mtextview.setTextColor(Color.GREEN);
                }else {
                  mtextview.setText("没有这么简单吧");
                  mtextview.setTextColor(Color.RED);
                }

这个地方也就是题目的关键所在了,所以说为什么不能爆破,爆破的话强制demo这个值为true就行了,这样完全没意思啊


public static String encryptXOR(String message, int key) {

      try {
            if (message == null) return null;

            char[] mesg = message.toCharArray();


            int ml = mesg.length;
            int[] newmsg = new int;
            for (int i = 0; i < ml; i++) {
                newmsg = mesg ^ key;
            }

            return chargeIntToString(newmsg);

      } catch (Exception e) {
            e.printStackTrace();
            return null;
      }
    }

此处就是java层的加密,将用户输入的内容的每个字节与key进行异或运算,得到的返回值传入native层

    static {
      System.loadLibrary("check");
    }
    public static nativeboolean mcheck(String answer);

native返回的就是一个bool类型的值

JNIEXPORT jboolean JNICALL Java_com_wuaipojie_crack01_check_mcheck
      (JNIEnv *env, jobject obj, jstring str) {
    const char *strs;
    bool succ = false;
    strs = (env)->GetStringUTFChars(str, NULL);
    char *str2 = base64encode(strs);
    env->ReleaseStringUTFChars(str, strs);
    jstring lock = (env)->NewStringUTF(str2);
        AntiDebug();
    jstring key = (env)->NewStringUTF("MzY0MTMyMzIzNTEyNjEyNDEyNTEyMg==");
    char *answer = jstringTostring(env,key);
    char *result = jstringTostring(env,lock);
    //__android_log_print(ANDROID_LOG_ERROR, "test-jni", "%s", signResult);
    //__android_log_print(ANDROID_LOG_ERROR, "test-jni2", "%s", result);
    if (!strcmp(answer, result)) {
      succ = true;
    }

    free(str2);
    return succ;
}

将传入的参数进行base64编码,在编码之前首先检查用户是否处于调试模式,也就是最常见的ptrace,如果发现tracerpid不为0,则结束进程,将base64后的编码与事先内置的编码进行strcmp比较,一致则返回true

此外,so做了代码加密处理,增加一点点的分析难度,不过可以动态解密哈

{:1_911:}

2217936322 发表于 2016-1-3 19:37

膜拜师傅的教程 师傅的沙发我来座!!!

codemonkey 发表于 2016-1-3 19:45

看不懂。。。

Ericky 发表于 2016-1-3 19:46

顶一下!

smile1110 发表于 2016-1-3 20:32

这个题目让俺想起了很多年前东京大学情报理工系的那个招募题,那时候大家并不懂破解,也国内人才辈出,先是ocr然后是字符码转换接着是java编译最后是反向日语声音片段,不胜唏嘘

熊大猫来了 发表于 2016-1-4 09:30

这么一看清晰多了,当时看到获取加密key那里就直接动态调smali找出来了,没想到是图片大小。。。
另外so文件给了x86和arm两个版本然后只加密了arm的,也让我钻了个空子

xiaomi1991 发表于 2016-4-6 10:19

感谢露珠无私奉献~

独孤.求败 发表于 2016-4-10 20:03

感谢楼主分享!!

lengyecanxue123 发表于 2016-4-27 16:26

感谢楼主的无私分享!

butterfly.super 发表于 2016-7-29 14:57

还不会动态调试。。。
页: [1]
查看完整版本: 一个小CM的出题思路