160个crackme(6)

这是160个crackme的第六道,比较简单;

一·逆向的软件及目的:

   

当我们点击About-Help的时候,就知道了这道crackme是让我们输入正确的Nome(我觉得作者是将name打错了…)和Codice,然后OK键和Cancella键会消失,显示出后面的图标:

二·开始工作:

分析:首先我们发现这个欧卡键是被灰度的,不可用,所以猜测应该是先输入正确的注册码后,Cancella键消失,然后ok键可以用,然后再输入正确的注册码后Ok键消失,图标显示出来。

正式开始逆向:

  1. PEID查壳:

没有壳,是Delphi写的。

  1. 因为IDE对Delphi编写的软件我觉得没有DeDe分析的好,所以我喜欢用DeDe查看一下事件:

一共有10个事件,根据名字我们发现前四个事件应该是关键的,我们在OD中将这几个事件的开始地址00442C78,00442D64,00442E04,00442EA8下断点并写上注释。

NomeChange事件:当我还在输入的时候就断在了00442E04的位置,然而我们并没有点击任何按钮,说明软件在输入的时候就开始判断对不对了。然后我们F8单步继续走(注意观察堆栈和寄存器的变化),当我们走到00442E57的时候,我们发现将我们输入的name放到寄存器EAX里了,而下面刚好有一个call,这个call很有可能是验证name的函数,所以F7单步进入,然后看到这里:

说明输入的name必须大于5个字符,然后下面就是关键算法:

00442A93到00442AAC就是判断name的算法,翻译成python就是:

eax=1
name=input(“name”)
a=name
b=len(a)
ebx=b
for i in range(0,b-1):
     ecx=ord(a[i])
     esi=ord(a[i+1])
     ecx=ecx*esi
     ecx=ecx*eax
     ebx=ebx+ecx
     eax=eax+1
print(hex(ebx))

 

然后通过name用上面算法算出来的一个值减去通过codice用另一个算法算出来的值,如果等于0x29A,那么cancella键就会消失

CodeChange事件:当我们输入codie时,程序断下来了,然后F8继续执行,同样观察堆栈和寄存器,在00442EE3的地址处,codice放入EAX中,所以进入下面的call,刚好是codice的算法。

判断codice的算法:

可以看出输入的codice必须是数字,然转换为python代码就是:

for i in codie:
     ecx=10*eax+int(i)
     eax=ecx
print(hex(eax))

其实就是将codie字符串转换为unicode编码

codeclik事件:点击cancella键时,在00442EA8断了下来,然后00442EE7位置的call进入,这里就是让cancella键消失的关键函数了:

取name的第五位a[4],然后除以0x7取余数后加0x2的值的阶乘保存下来,然后减去name计算出来的值如果等于0x7A69,就消去cancella键。

所以消去cancella键的注册机可以这样写:

name=input("输入name:")
eax=ord(name[4])%0x7+0x2    #对应0x0442B35
ebx=1
for i in range(1,eax+1):          #call 0x042A20
     ebx=ebx*i
eax=0
for i in name:
     eax=eax+ord(i)*ebx         #对应0x0442B54
ebx=eax-0x7a69                  #反推密码 对应0x0442B65
key=ebx
print(u"cancella键消失的密码:%d"%key)

 

okclik事件:用上面同样的方法,找到时ok键消失的算法的位置00442BF9:

 

密码从后往前获取密码一位的平方乘以(下标+1),除以0x19,余数加0x41,替换掉原来的密码位置,然后和name比较一不一样,如果一样就将ok键消失掉。

所以用python写注册机可以这样写:

先输入codice然后再根据codice反算出name:

codice=input("输入codice:")
a=codice
ecx=len(a)
eax=0
x=0
key=" "
for i in range(0,ecx):
     x=ord(a[i])*ord(a[i])         #对应0x0442C0E
     if(x>0xffff):                    #对应0x0442C10
          x=0xffff
     eax=x*(i+1)%0x19+0x41   #对应0x0442C1B和0x0442C1D
     if(eax>0xff):
          eax=0xff
     key=key+chr(eax)                  #对应0x0442C21
print("OK键消失的name:%s"%key)

 

总结:将使ok键消失的代码和cancella消失的代码分开写,也就是让cancella的代码是通过name算出codice,让ok键消失的代码是通过codice去算name,这样要简单一点!

 

猜你喜欢

转载自blog.csdn.net/qq_40827990/article/details/84715672