CrackMe_0006
这题我看是四星难度,算法还是有的一玩的。
拿到程序看看

无壳,直接OD里面看得了。
爆破
首先定位关键字符串
肯定是GOOD了

追踪进来
看到正确回显上面有个jnz,把他改掉


跑跑看,是可以的。

算法逆向
这个相对繁琐一些。
在这里读入name之后紧接着一个CALL,进去看看做了什么

第一阶段
代码流程不长,但是有一个什么循环在里面,主要是ECX和add eax和edx两步。
我们简单跑两轮

读入h,然后和1乘 和0相加存入eax

读入y 和刚刚的结果想成 存入eax

不过有个东西需要注意,这imul实际上是eax ^ ecx,然后如果超过32位,会存在edx,所以脚本如下
sName = "hyyyy"
nTemp = 1
nTemp1 = 0
nEnd1 = 0
sFlag = ""
for i in sName:
nTemp = nTemp * ord(i)
nTemp1 = nTemp & 0xffffffff
nTemp2 = nTemp // 0xffffffff
nEnd1 = nTemp1 + nTemp2
print("一阶段结果"+str(hex(nEnd1)))
在OD里跑出来
结果


OK
第二阶段
第二个阶段‘
又进入了一个call,进去看看

是这样的,实际上就是上面的结果循环左移,但是要注意,这不是«这个左移,这个左移在末位补0,而rol是把高位出去的补到低位去,让GPT写个相同作用的脚本

def rol(value, shift, bitsize=32):
shift %= bitsize
return ((value << shift) & (2**bitsize-1)) | (value >> (bitsize - shift))
#nEnd1 = nEnd1 << 1
nEnd1 = rol(nEnd1,1)
两边运行结果


ok的
第三阶段
第三阶段 出来之后,两个运算

比较简单,实际上就是
先和0x7DAF15F8 逻辑或
再去掉最高位
nEnd1 = nEnd1 | 0x7DAF15F8
nEnd1 = nEnd1 & 0xfffffff
两边结果


ok
第四阶段
主要阶段来了

还是比较纷杂的
最上面那个call

目的其实是啥呢?感觉很多,但其实就是为了获取上面经过计算dbf3ffa的最低位a
出来了,答案与我们分析一致

然后干啥呢,其实就是用这个a作为需要的位置然后取071362de9f8ab45c相应字符串添加进去而已
在进入下面的这个call

这个函数是为了缩短dbf3ffa,变成dbf3ff。
然后一遍遍循环就是了
for i in range(100):
nTemp3 = 0
sKey = "071362de9f8ab45c"
nTemp3 = nEnd1 & 0xf
sFlag += sKey[nTemp3]
#print("结果11ssa "+str(hex(nTemp3)))
nEnd1 = nEnd1 // 0x4
if (nEnd1 == 0):
break
#print(hex(nEnd1))
print (sFlag)
就可以输出正确的serial了。
完整keygen
sName = "hyyyy"
nTemp = 1
nTemp1 = 0
nEnd1 = 0
sFlag = ""
for i in sName:
nTemp = nTemp * ord(i)
nTemp1 = nTemp & 0xffffffff
nTemp2 = nTemp // 0xffffffff
nEnd1 = nTemp1 + nTemp2
print("一阶段结果"+str(hex(nEnd1)))
def rol(value, shift, bitsize=32):
shift %= bitsize
return ((value << shift) & (2**bitsize-1)) | (value >> (bitsize - shift))
#nEnd1 = nEnd1 << 1
nEnd1 = rol(nEnd1,1)
#nEnd1 = nEnd1 & 0xffffffff
print ("移位后结果"+str(hex(nEnd1)))
nEnd1 = nEnd1 | 0x7DAF15F8
nEnd1 = nEnd1 & 0xfffffff
print (hex(nEnd1))
for i in range(100):
nTemp3 = 0
sKey = "071362de9f8ab45c"
nTemp3 = nEnd1 & 0xf
sFlag += sKey[nTemp3]
#print("结果11ssa "+str(hex(nTemp3)))
nEnd1 = nEnd1 // 0x4
if (nEnd1 == 0):
break
#print(hex(nEnd1))
print (sFlag)
随便泡泡

ok了
