hgame week re#

hgame week3 的re, 链接: https://pan.baidu.com/s/1jdYHLzhz3ygEtW0NPgqQsw 密码: w03a

@[toc]

hidden#

首先搜索字符串找到输出正误的函数,然后查看调用找到check函数:

img-blog.csdnimg.cn 程序逻辑比较清晰,就是在encode函数中加密,然后查看是否和两个值相等,

img-blog.csdnimg.cn

然后进入函数后看到对函数的处理只在后半段,前面只是处理数据,但是我们动调会发现函数会莫名的在前面这个函数中间跑飞:

img-blog.csdnimg.cn

动调时最关键的在于这个函数内部的这个调用:

img-blog.csdnimg.cn

步入调用内部,然后似乎还是一个比较完整的函数,一直找到后面的ret位置,然后按P, 分析为函数,还可以f5

img-blog.csdnimg.cn img-blog.csdnimg.cn

得到一个加密的位置,而且最后调用的函数为我们直接输出正误的那个函数,所以这个程序前面静态看到的都是假的,真正的流程是运行到这个位置,然后直接判定了flag正误, 我们前面动调在这里推出也是因为程序已经运行完了。

然后看下程序的逻辑中间的几个运算基本可以直接反着写, 动调发现需要注意一个&0xff的操作,然后key是flag最后的两位,直接断到判定位置发现flag的加密是19×2的形式,避开了最后两位,所以我们后面的data中的对应flag位置就是key, 可以直接取出来。

然后就得到解密脚本:

key = [0x7d,0x65]
cipher_data = [8896099409227384902, 5221214014029134222, 5439652918615309179, 9331866693134944349, 9035724225678832282]
cipher = [(cipher_data[i] >> 8 * j) & 0xff  for i in range(5) for j in range(8)]
for i in range(19):
	for j in range(2):
		cipher[i + 19] ^= cipher[i]
		cipher[i + 19] += 0x67
		cipher[i + 19] &= 0xff
		cipher[i] -= key[j]
		cipher[i] &= 0xff
		cipher[i] ^= cipher[i + 19]
for i in range(40):
	print(chr(cipher[i]), end='')

注意倒这些,但是key需要注意下要反过来,或者写for j in range(1,-1,-1)

就得到flag:hgame{h1dden_1n_mem0ry_15_excited_2eeee}

ollvm#

简单动调看了下程序的运行,主要的加密就只有这个位置: 主要的判定位置是: img-blog.csdnimg.cn table2[i] = ~flag[i] & (i + table1[i]) | ~(i + table1[i]) & flag[i] 由于是位运算, 我们看下这个运算时数据的二进制,然后得到一个这样的规矩: img-blog.csdnimg.cn 所以这个加密对应的解密方式是一个异或关系而已, 直接在ida中解密出来,

addr1 = 0x602050
addr2 = 0x602080
arr1 = []
arr2 = []
for  i in range(34):
    arr1.append(Byte(addr1 + i))
    arr2.append(Byte(addr2 + i))
print(arr1)
print(arr2)
s = ''
for i in range(34):
    s += chr(arr2[i] ^ (arr1[i]+i))
print(s)

得到: img-blog.csdnimg.cn