题目链接:https://pan.baidu.com/s/1PNNAo2Ive4K7eYEifVIwsQ
提取码:8b2v
用Exeinfo PE查壳发现是UPX壳
使用UPX-3.95(可以在吾爱破解Tools->Packers可以下到)的upx -d 命令脱壳
然后我们在IDA里找到关键算法部分
可以看出循环是根据每个字符生成v6和v7,然后16*v6+v7当下标,在数字byte_4021A0中就行寻值。然后和(v11+v12)^0x19进行比较,若不相等则失败,而v11和v12是根据数组byte_402150生成的。
其实对输入字符处理到最后的16*v6+v7仍然是输入字符的ascii值,而v11+v12其实就是byte_401250处存储的字符串“2a49f69c38395cde96d6de96d6f4e025484954d6195448def6e2dad67786e21d5adae6”的每两位的写入内存的十六进制,相当于python3的bytes.fromhex()函数。
也就是说最后的比较就是data[input[i]] == arr[i]^0x19
我们把byte_4021A0处的数据dump下来,然后写脚本运行即可得到flag。
data = open('E:\\data','rb').read() arr = bytes.fromhex("2a49f69c38395cde96d6de96d6f4e025484954d6195448def6e2dad67786e21d5adae6") for i in range(len(arr)): print(chr(data.index(arr[i]^0x19)),end="")
如果看不出来对字符的处理是怎么回事的话,也可以进行爆破。
def fun(i): if(data1[i] < 48 | data1[i] > 57): a = data1[i] - 87 else: a = data1[i] - 48 a = a * 16 if(data1[i+1] < 48 | data1[i+1] > 57): b = data1[i+1] - 87 else: b = data1[i+1] - 48 return ((a + b) ^ 0x19) for i in range(35): z = i for m in range(128): a = (m >> 4) % 16 b = (16 * m >> 4) % 16 j = 16 * a + b k = fun(i*2) if(data[j] == k): print(chr(m),end="")