广告下学长的小站:http://zhan.renren.com/reversing?from=bar。。欢迎关注
感觉注册算法挺简单的,只有一个函数比较难分析:总体思路是从下图1的0、1序列中选出一条长度为16的全1序列,从(0,0)开始,只能向右、上、下走16步(不能走到第13列)。
下面开始分析汇编代码:
通过字符串搜索或是其它方法都可以很快找到关键Call,00401869地址处:
跟进关键Call,前面几句代码有检查是否存在“-”字符的,无甚意思,关键在004013a0处的sscanf函数调用处,这里就可以知道注册码的大致格式为:XDSEC??-????????-????????-????????-????????。
继续跟踪到下图中的函数:
Crackme4.00401656函数的作用是判断所给的字符是否属于某字符串:
第一次调用Crackme4.00401656是判断注册码的第六位是否在XDSECJQ字符串里,第二次判断注册码的第七位是否在VYBFGH字符串内。再继续到下图代码:
此处函数Crackme4.0040163a则是分别计算出第六个字符在字符串XDSEXJ中的位置记为a:
然后字符串再循环左移a个,保证字符串XDSECJQ以第a个字母开头,下面还有一个Crackme4.0040163a调用是对第七个字符和字符串VYBFGH的,现在注册码的第一部分XDSEC??就明确含义了,剩余部分经过sscanf之后合并成32位字符串,没有了中间的“-“符号(????????-????????-????????-????????->?*32)。下面就开始判断这32个字符了,首先进行的判断注册码剩余32个字符的奇数位是否在XDSECJQ那个串,偶数位判断是否在VY那个串,构造字符串跟踪时注意就行:
再继续就终于来到算法的关键处了:
循环共16次,每次顺序判断注册码去除XDSEC??的剩余32个字符中的两个,经过函数Crackme4.0040163a(见下图)计算出的字符所在字符串偏移a、b之后,再利用Crackme4.40161a计算(a+13*b)*4是不是在程序的0、1表常量中,(图1是简化的0、1图,1代表程序中的01 00 00 00,0代表程序中的00 00 00 00,实际是判断数组a+13*b元素是否为1,即a行b列)
如果在的话继续,不在的话修改变量再去死。然后函数Crackme4.401588在判断a,b与上一步判断的a1,b1的关系,第一次调用Crackme4.401588(部分代码见下图)是a与-1判断,如果第一次a不等于0则退出,所以32个字符中第一个就是注册码第一部分XDSEC??的第六个字符,b的位置在满足Crackme4.40161a的前提下随意,之后的15次调用Crackme4.401588则是判断本次判断的两个字符在循环移位后字符串的位置偏移a,b和之前两个字符的偏移a1、b1的关系,只有满足条件a=a1,|b-b1|=1或是a-a1=1,b=b1程序才不会结束循环,跳转到失败对话框,相当于是只能在迷宫中往右、上、下方向走16步,注册码就取其每一步坐标的行数和列数值(同时满足每一步坐标在在0、1表中的对应的值是为1)。Crackme4.401588部分代码:
下面以一组注册码XDSECWF-WFWGAGAH-AIAKANAO-APATRTRU-RVRYRBMB为例,直接从(0,0)开始走的,其它的方法也无所谓,看下图蓝线的路径,16个点:
写注册机也比较简单,直接记住一个路径,循环移位后的字符串按路径输出即可。
效果截图: