又是废物的一天。
昨天学了ARM汇编,今天看看这道题。
加载了so文件。
调用了原生程序的CheckFlag方法,参数v2是我们的输入,v1是assets目录内Flag文件的内容。 Ku@'G_V9v(yGS
然后分析lib-native.so文件。
直接找到这个方法进行分析,Java_monkeylord_illusion_MainActivity_CheckFlag
比较v11和v10,分析sub_10C0函数。
a2 = 93,所以必定执行sub_1028函数。
没啥分析的,直接抄代码就可以了。
然后发现这个函数跑出来是0,1,2....
估计IDA不够用了,检验ARM汇编的时刻到了。
ADDS R1,#0x20
对R1进行操作,所以我们分析函数看看R1。
进入sub_10C0函数,
发现 R0,R1,LR入栈,然后出栈到R1,R2,R3。
这个函数执行完 R1=R1-R2 * R0
R0是sub_1028中得到的,也就是0,1,2.....
R1等于原先的R0,R2等于原先的R1。
原先的R0是(输入的字符 + 给出的字符 - 64)
原先的R1是 93
所以最终的计算的字符串是 {(输入的字符 + 给出的字符 - 64)- 93 * (sub_1028的返回值)}
发现跑出来不对,然后看了看writeup,才知道我用的假函数,真正的函数在JNI_OnLoad里动态加载了,以后一定不能忽略这个函数。
查看off_4004:
跳转到sub_DC8处就是真正的函数。发现功能一样,就是给出的字符串发生了变化。
给出python脚本参考:
import string
s = "Ku@'G_V9v(yGS"
strs=string.printable
def decode(x, y):
v2 = x ^ y
v3 = 1
v4 = 0
if x < 0:
x = -x
if y < 0:
y = -y
if x >= y:
while x > y:
y *= 16
v3 *= 16
while x > y:
y *= 2
v3 *= 2
while True:
if x >= y:
x -= y
v4 |= v3
if x >= y >> 1:
x -= (y >> 1)
v4 |= (v3 >> 1)
if x >= y >> 2:
x -= (y >> 2)
v4 |= (v3 >> 2)
if x >= y >> 3:
x -= (y >> 3)
v4 |= (v3 >> 3)
if x == 0:
break
v3 >>= 4
if v3 == 0:
break
y >>= 4
if v2 < 0:
return -v4
return v4
flag = ''
data_tmp = '(Ljava/lang/String;Ljava/lang/String;)Ljava/lang/String;'
for i in range(len(s)):
for j in strs:
data1 = ord(j) + ord(data_tmp[i]) - 64
data2 = 93
d = decode(data1, data2)
print(str(data1)+':'+str(d))
if (data1- d * 93) + 32 == ord(s[i]):
flag += j
print(flag)
跑出flag,正确。但是攻防世界提交错误,。。。。