第一步,熟悉的查壳,没什么有用的信息,发现是64位程序,那我们接着用IDA打开
第二步,用IDA打开分析
__int64 __fastcall main(int a1, char **a2, char **a3)
{
int i; // [rsp+Ch] [rbp-34h]
char s[40]; // [rsp+10h] [rbp-30h] BYREF
unsigned __int64 v6; // [rsp+38h] [rbp-8h]
v6 = __readfsqword(0x28u);
sub_A90((void (__fastcall *)(void *))sub_916); //一个函数
fgets(s, 35, stdin); s
for ( i = 0; i <= 33; ++i )
s1[i] ^= s[i];
return 0LL;
}
这里有一个sub_A90
和sub_916
,怀疑是main执行完后的回调,看一下sub_916
unsigned __int64 sub_916()
{
unsigned __int64 v1; // [rsp+8h] [rbp-8h]
v1 = __readfsqword(0x28u);
if ( !strcmp(s1, s2) )
puts("Congratulations!");
else
puts("Wrong!");
return __readfsqword(0x28u) ^ v1;
}
从这里可以看出确实是;这里有在对比 s1
和 s2
, 二者一样就ok
从main中可以看出s1对输入的字符串做了一个异或操作,那就是异或后再比较
找到s1 和 s2对应的字符串的值
s1 = 'qasxcytgsasxcvrefghnrfghnjedfgbhn'
s2 = [0x56, 0x4e, 0x57, 0x58, 0x51, 0x51, 0x09, 0x46,
0x17, 0x46, 0x54,
0x5A, 0x59, 0x59, 0x1F, 0x48, 0x32, 0x5B, 0x6B,
0x7C, 0x75, 0x6E, 0x7E, 0x6E, 0x2F, 0x77, 0x4F,
0x7A, 0x71, 0x43, 0x2B, 0x26, 0x89, 0xFE, 0x00]
那我们写个脚本让s1和s2异或试试
def decode():
s1 = 'qasxcytgsasxcvrefghnrfghnjedfgbhn'
s2 = [0x56, 0x4e, 0x57, 0x58, 0x51, 0x51, 0x09, 0x46,
0x17, 0x46, 0x54,
0x5A, 0x59, 0x59, 0x1F, 0x48, 0x32, 0x5B, 0x6B,
0x7C, 0x75, 0x6E, 0x7E, 0x6E, 0x2F, 0x77, 0x4F,
0x7A, 0x71, 0x43, 0x2B, 0x26, 0x89, 0xFE, 0x00]
flag = ''
for x in range(33):
flag += chr(ord(s1[x])^s2[x])
print(flag)
if __name__ == '__main__':
decode()
结果为 :'/$ 2(}!d''":/m-T<A*$INç,明显不对,但是好像已经分析完毕了
这时候可能还有其他值修改了,我们找到S1
ctrl+x 交叉引用,查看有那些哪些函数引用了这个变量的值
发现除了上面的分析之外,还有一个sub_84A()函数引用了该变量,那么我们F5进入该函数
发现还有一个异或,那么思路到此我们在原来代码的基础上增加一个异或
def decode():
s1 = 'qasxcytgsasxcvrefghnrfghnjedfgbhn'
s2 = [0x56, 0x4e, 0x57, 0x58, 0x51, 0x51, 0x09, 0x46,
0x17, 0x46, 0x54,
0x5A, 0x59, 0x59, 0x1F, 0x48, 0x32, 0x5B, 0x6B,
0x7C, 0x75, 0x6E, 0x7E, 0x6E, 0x2F, 0x77, 0x4F,
0x7A, 0x71, 0x43, 0x2B, 0x26, 0x89, 0xFE, 0x00]
flag = ''
for x in range(33):
flag += chr(ord(s1[x])^ (2 * x + 65)^s2[x])
print(flag)
if __name__ == '__main__':
decode()
得到flag flag{c0n5truct0r5_functi0n_in_41f}