Illusion
题目来源: CISCN-2018-Quals
题目描述:题目很简单,但想要快速找到正确答案,就要对安卓原生熟悉。
查看java层,发现是将输入通过CheckFlag与assets里的Flag进行比较
assets里的Flag内容为"Ku@'G_V9v(yGS"
CheckFlag在native-lib库里
查看libnative-lib.so
so文件里虽然有一个CheckFlag,不过这个是假的,真正的CheckFlag是通过动态加载的
查看JNI_OnLoad,找到真实的CheckFlag
CheckFlag被IDA解析的有点问题,通过读汇编得到,逻辑是
将输入每个字符的ascii加上给的字符串"(Ljava/lang/String;Ljava/lang/String;)Ljava/lang/String;"对应字符的ascii码减去64再减去93*sub_10C0的返回值得到处理后的字符串
解密脚本如下
import string encflag = "Ku@'G_V9v(yGS" key = "(Ljava/lang/String;Ljava/lang/String;)Ljava/lang/String;" def decrypt(a1, a2): v2 = a1 ^ a2 v3 = 1 v4 = 0 if (a2 & 0x80000000) != 0: a2 = -a2 if (a1 & 0x80000000) != 0: a1 = -a1 if a1 >= a2: while a2 < 0x10000000 and a2 < a1: a2 *= 16 v3 *= 16 while a2 < 0x80000000 and a2 < a1: a2 *= 2 v3 *= 2 while True: if a1 >= a2: a1 -= a2 v4 |= v3 if a1 >= a2 >> 1: a1 -= a2 >> 1 v4 |= v3 >> 1 if a1 >= a2 >> 2: a1 -= a2 >> 2 v4 |= v3 >> 2 if a1 >= a2 >> 3: a1 -= a2 >> 3 v4 |= v3 >> 3 if a1 == 0: break v3 >>= 4 if v3 == 0: break a2 >>= 4 result = v4 if v2 < 0: result = -v4 return result flag = '' for i in range(len(encflag)): for ch in string.printable: if chr(ord(ch) + ord(key[i]) - 64 - 93 * decrypt(ord(ch) + ord(key[i]) - 64, 93) + 32) == encflag[i]: flag += ch break print(flag)
得到flag
CISCN{GJ5728}