前期工作
查壳,无。安装打开黑屏。
逆向分析
用jadx打开看看
什么都没有,但可以看一下AndroidManifest
可以看到这个是个纯C/C++写的,没有Java代码,是个NativeActivity。
但是后面又有个MainActivity,所以可能是运行so之后就会放出来一个dex。
NativeActivity的启动函数是android_main,进入so中查看android_main
off_43A18存的是0x3CA10
开始把0x7004开始的长度为0x3CA10的数据拷贝到v3里
然后一顿操作后提示
想想都知道正常人是肯定做不到的,继续往下看
v14应该就是手机摇动次数了,如果符合要求的话就解压v3到dest然后写入一个文件。v3存的应该就是dex了。将内容dump下来。
通过对比很明显,这个不是dex,猜测有加密,回到前面看看
这块地方操作了off_43A18和v3,所以这里应该是解密部分,前面应该是获取手机摇动次数。看看这里 发生了什么
编写解密脚本,其实就是将IDA翻译成python
import zlib
with open('d:\\easydex', 'rb') as f:
data = list(f.read())
size = 0x3ca10
times = 0
while True:
if times <= 0x59:
t = int(times / 10)
if times % 10 == 9:
s = int(size / 10)
x = (t + 1) * s
if s * t < x:
c = 0
for _ in range(s):
data[s * t + c] = data[s * t + c] ^ times
c += 1
if times == 0x59:
while x < size:
data[x] = data[x] ^ 89
x += 1
break
times += 1
fbytes = bytes(data)
with open('easydex.dex', 'wb') as f1:
f1.write(zlib.decompress(fbytes))
得到dex放入jadx继续分析
文件结构
MainActivity
监听器是a,
查找这个资源id
猜测是twofish加密了,I have a male fish and a female fish.这个应该是密钥,明文加密钥加密得到m正确即可
再回看MainActivity中的m,居然有负数。其中Byte.MIN_VALUE数值为-128。
查找资料
编写脚本解密后得到的不是可读字符,网上在线twofish的结果是base64编码的,所以将结果进行base64
最终脚本
import base64
flag = [-120, 77, -14, -38, 17, 5, -42, 44, -32, 109, 85, 31, 24, -91, -112, -83, 64, -83, -128, 84, 5, -94, -98, -30, 18, 70, -26, 71, 5, -99, -62, -58, 117, 29, -44, 6, 112, -4, 81, 84, 9, 22, -51, 95, -34, 12, 47, 77]
data = []
for i in flag:
data.append(i&0xff)
print(base64.b64encode(bytes(data)))
拿去解密
得到flag
FLAG
qwb{TH3y_Io<e_EACh_OTh3r_FOrEUER}
总结
做这题真是学到了很多东西,也掌握了一些技巧。首先看到黑屏且没有代码很慌,查看Manifest之后又去查找资料才知道这个是NativeActivity,之后dump内存用的脚本也是上网查找资料才知道又idaapi这种东西,查找字符串资源的时候因为jadx在资源文件中搜不到所以将项目导出后用AndroidStudio打开查找才找得到,什么zlib之类的也是第一次看见,这题查资料学东西花了两天。