summer14

CrackMe爆破与算法分析(二)

[wocy.1]

程序功能:输入username和id,判断是否注册。

爆破

IDA发现关键字符串“Registed. Good job.”,根据字符串定位到代码段。

  

关键跳是jnz这条指令。要想“Registed. Good job.”正常输出,把jnz这条指令替换为空指令即可。

运行后输入长度比较短的字符串,发现注册失败。IDA查看前面还有一跳。再把jl指令nop掉。

  

成功爆破

算法分析

判断username长度不小于4后,在0x40164D处调用库函数(MakeReverse)翻转username字符串,再用翻转后的字符串与id比较,相等则表示注册成功。

 

[ArturDents-CrackMe#2]

程序功能:输入Name和Serial,检查是否正确。输入错误没有提示。

爆破

根据字串“Yeah, you did it!”定位关键代码段。

关键跳是位于地址40111A处的:jge  short loc_401134和位于地址40115A处的:jnz  short locret_401174。

其中jge这条指令判断输入的字符数是否大于5,大于5则跳转执行401134处的指令。利用这一跳绕过字符串长度的检查。

把jge指令改成jmp、jnz指令改成nop,成功爆破。

算法分析

GetDlgItemTextA函数获取输入Name的长度,如果长度小于5,则发出警告,并退出程序。

执行下面一段循环,循环次数取决于Name的长度。每次循环取出Name字符串第一个字符,ascii码减去当前Name字符串长度后与Serial第一个字符比较,相等则继续执行循环。Name和Serial都删掉第一个字符后作为新的Name和Serial。

  

写成python,获取每个Name的正确Serial

#!/usr/bin/env python3

name = list(input("input you name[length >= 5]:"))
for i in range(len(name)):
    arry = name[i:]
    name[i] = chr(ord(arry[0]) - len(arry))
print(f'your serial is:{"".join(name)}')

 

[Acid burn]

程序有两个功能。一个功能是输入Serial,判断Serial是否正确;另一个功能是输入Username和Serial,判断Username对应的Serial是否正确。

去掉Nag窗口

nag是指一种弹出窗口,用于提醒用户购买正版软件或者注册软件。

每次启动都弹出窗口,目的是不让程序弹出这个窗口。

静态分析

 IDA首先找到弹出这个窗口的函数入口地址0042F784,现在要找出调用这个函数的指令。

  

Ctrl+x查看交叉引用,并没有显示引用该函数的地址。说明主调函数在动态执行过程中才获取到这个函数的地址。

动态分析

OD在函数入口0042F784下断点,F9执行到此处。查看栈的情况如下,ESP所指的数据就是函数的返回地址。

  

 00425643处的调用指令,就是这一条指令调用弹出Nag窗口函数。

  

低地址的JE指令可以让程序跳过call指令,把JE改成JMP就行了。

爆破

爆破的方式与前面的类似,找到关键字符串的所在代码的关键跳转,nop掉即可。

算法分析

功能一:只输入Serial

两个局部变量,分别赋值为"Hello"和"Dude!",合并后"Hello Dude!"与输入进行比较

功能二:输入Username和Serial

#代码段前面有很多对程序没有作用的指令,但是为了往下分析,也不得不把这一部分分析出来。起到了一定的保护作用。
#这一大段指令做了如下工作,其中ESI、EAX为寄存器,但是它们并没有被赋值给程序的变量或参数 ESI
= h << 3 - h ESI = u << 4 + ESI ESI = 0x6E * 0x0B EAX = 0x61 * 0x0E ESI = EAX + ESI

真正起到作用的部分,转为python

key_bk = "CW-"
key_fd = "-CRACKED"

name = input("name:")
number = ord(name[0]) * 0x29 * 2
print("your serial:" + key_bk + str(number) + key_fd)

 

posted on 2023-05-11 22:09  summer14  阅读(62)  评论(0编辑  收藏  举报

导航