# CTF 移动端
# 第一题 Illusion
jadx 打开
发现就是对输入的进行了一个判断,用到的是 native 方法
用 ida 打开 so,然后修改下变量名
这里的 aE 就对应的下面这个长字符串
然后这串代码的大致意思其实就是判断计算的这个 Buffer 中的每一个值是不是和 enc 中的相等,如果相等那就返回 correct,接下来就需要进一步查看 sub_10C0 的逻辑,因为这里的 a2 恒为 93,那么直接进入 sub_1028 查看对应逻辑
直接把 sub_10C0 代码 copy 下来测试
发现主要逻辑与 a1,a2 的大小有关,如果 a1 小于 a2 就为 0,同时观察函数名可以猜测应该和除有关,接着测试几个,发现这个其实就是整数除法。
回到 so 开始位置还原逻辑
# 对应的 for 循环内部的操作 | |
(a + b - 64)/93 >> 32 + 32 = c | |
c - 32 = (a + b - 64)/93 [0,1,2...] | |
c + 32 - b = a [分情况] |
ord 返回字符的 unicode 编码
chr 将 unicode 编码转化为字符
直接不采用分情况的写法会拿到如下 ascii 码表,其中包含负数,我们知道一个负数 / 93 然后在 >> 32 是会得到 0 的,同时,如果一个数大于 32 , 那么 对其进行 >>32 的操作,其实是不会变的,所以就需要分离出小于 32 的情况。
key = '(Ljava/lang/String;Ljava/lang/String;)Ljava/lang/String;' | |
enc = "Ku@'G_V9v(yGS" | |
flag = [(ord(i) + 32 - ord(j))for i,j in zip(enc,key)] | |
print(flag) | |
for i in range(len(flag)): | |
if flag[i] <= 0x20: | |
flag[i] = chr(93+flag[i]) | |
else: | |
flag[i] = chr(flag[i]) | |
print(''.join(flag)) | |
# CISCN{GJ5728} |
这里有个小 bug,就是 key 这里的值,用 Ida 打开直接看发现是上述那个 32 位的字符串