
这一题有点难度,依旧放die
看到64位小端序,放ida64
看主函数,输入存在v6
首先会看if ( aGyURsywBFbLwya[j] != byte_414040[j] )
只要不满足这个条件,就可以到达打印right,分支,所以aGyURsywBFbLwya[j]就是加密之后
的flag,双击进去就可以看到加密后的字符串

转化位字符数组
char ans[] = {
'g', 'y', '{', 0x7F, 'u', '+', '<', 'R', 'S', 'y',
'W', '^', ']', 'B', '{', '-', '*', 'f', 'B', '~', 'L',
'W', 'y', 'A', 'k', '~', 'e', '<', '\\', 'E', 'o', 'b', 'M'
};然后继续看代码
加密过程就是
for ( i = 0; i <= 32; ++i )
{
byte_414040[i] = v6[dword_40F040[i]];
v4 = i;
byte_414040[i] ^= LOBYTE(dword_40F040[i]);
}
首先,dword_40F040[i]的值作为输入v6的下标,比如:dword_40F040[1] = 3, byte_414040[i] = v6[3],
解密的话就是v6[dword_40F040[1]] = byte_414040[1]
接着看:
byte_414040[i] ^= LOBYTE(dword_40F040[i]);
这句就是byte_414040[i]和dword_40F040[i]异或
为什么有LOBYTE?因为dword_40F040[i]是整形,有四字节,而byte_414040[i]是char型,只有一字节,所以要异或的话就是用
LOBYTE取低8位,这里不用细究
因为异或的对象是两个不同的数组,先后异或的结果不会影响到最终结果,所以解密直接照抄就行
ans[i] ^= index[i] & 0xff
我这里把lobyte改成和0xff按位与,结果是一样的
exp:
#include<iostream>
#include<string>
using namespace std;
int main()
{
int index[33] = {
0x9, 0xA, 0xF, 0x17, 0x7, 0x18, 0xC, 0x6, 0x1, 0x10,
0x3, 0x11, 0x20, 0x1D, 0xB, 0x1E, 0x1B, 0x16, 0x4, 0xD,
0x13, 0x14, 0x15, 0x2, 0x19, 0x5, 0x1F, 0x8, 0x12, 0x1A,
0x1C, 0xE, 0x0
};
char ans[] = {
'g', 'y', '{', 0x7F, 'u', '+', '<', 'R', 'S', 'y',
'W', '^', ']', 'B', '{', '-', '*', 'f', 'B', '~', 'L',
'W', 'y', 'A', 'k', '~', 'e', '<', '\\', 'E', 'o', 'b', 'M'
};
char flag[34] = { 0 };
for (int i = 0; i <= 32; i++)
{
ans[i] ^= index[i] & 0xff;
flag[index[i]] = ans[i];
}
cout << flag << endl;
return 0;
}