-
-
[原创]第二题 我的分析结果
-
发表于:
2008-10-7 12:32
6745
-
扔进ollydbg中,一步一步的跟,发现有时候要飞,有时候不飞。
该程序存在一个 自校验的过程,在自校验的时候如果有下断点,那么就是自校验失败然后飞了。。
于是,在004039F3 . 3D 3E5BDF02 CMP EAX,2DF5B3E 这个位置下了个断点,F9到这个位置以后,再把其他的禁用的断点进行恢复。
逆向出的整体程序流程是:
1.username的检验,长度必须是12字节,必须是a到z之间的小写字母,并且不能取字母z,不能有重复的字母。
2.key的检验,长度必须是超过0x35,只能是0,1,2,3这四个数字中间的数字。
3.当username和key检验通过以后,进入加密算法的函数,三个参数:0012F544---key的首地址
0012F7BC——username的大小顺序标识(从0到B的12个数字,按照username的对应大小顺序排列)
0012F6F4——算法处理结果的地址。
4.算法处理完成以后,将0012F6F4的字符串进行处理,首先也是判断是否都是a到z之间的小写字母是否有重复,如果不满足条件直接NG窗口,判断排列顺序于username的大小排列顺序是否一样。一样就成功了。。
加密算法的分析结果:
用key[0]与0xC做除运算,其商作为其中一层循环判断的次数m。
将24个最终处理结果用两个不同的表格C来进行运算。前半部分的C由一个28和11个1E初始化
后一部分用14和11个1E初始化
总体流程如下:
sum1=C[key[1]*4]+C[key[1]*4+1]+……+C[key[1]*4+m-1]
sum2=C[key[2]*4]+C[key[2]*4+1]+……+C[key[2]*4+m-1]
if(sum1==sum2)
if(C[key[3]*4+key[4]]==C[key[5]*m+key[6]])
{if(C[key[7]*4+key[8]]==C[key[9]*4+key[10])
输出l
else 输出k
}
else
{if(C[key[7]*4+key[8]]==C[key[9]*4+key[10])
输出j
else 输出i
}
if(sum1>sum2)
C做变换E(C)。C变换的公式如下:
C[key[1]*4+key[11]]=C[key[12]*4+key[13]];
C[key[1]*4+key[14]]=C[key[15]*4+key[16]];
C[key[1]*4+key[17]]=C[key[18]*4+key[19]];
C[key[2]*4+key[20]]=C[key[21]*4+key[22]];
C[key[2]*4+key[23]]=C[key[24]*4+key[25]];
C[key[2]*4+key[26]]=C[key[27]*4+key[28]];
sum3=C[key[1]*4]+C[key[1]*4+1]+……+C[key[1]*4+m-1]
sum4=C[key[2]*4]+C[key[2]*4+1]+……+C[key[2]*4+m-1]
if(sum3>sum4)
if(C[key[29]*4+key[30]]==C[key[31]*4+key[32]])
输出e
else输出a
if(sum3<sum4)
if(C[key[33]*4+key[34]]>C[key[35]*4+key[36]])
输出j
else if(C[key[33]*4+key[34]]<C[key[35]*4+key[36]])
输出f
else if(C[key[33]*4+key[34]]==C[key[35]*4+key[36]])
输出h
if(sum3==sum4)
C做变换,恢复到和初始化一样的状态
if(C[key[37]*4+key[38]]>C[key[39]*4+key[40]])
输出b
else if(C[key[37]*4+key[38]]<C[key[39]*4+key[40]])
输出c
else if(C[key[37]*4+key[38]]==C[key[39]*4+key[40]])
输出d
if(sum1<sum2)
C做变换E(C)
sum3=C[key[1]*4]+C[key[1]*4+1]+……+C[key[1]*4+m-1]
sum4=C[key[2]*4]+C[key[2]*4+1]+……+C[key[2]*4+m-1]
if(sum3>sum4)
if(C[key[41]*4+key[42]]>C[key[43]*4+key[44]])
输出f
else if(C[key[41]*4+key[42]]<C[key[43]*4+key[44]])
输出g
else if(C[key[41]*4+key[42]]==C[key[43]*4+key[44]])
输出h
if(sum3<sum4)
if(C[key[45]*4+key[46]]==C[key[47]*4+key[48]])
输出e
else输出a
if(sum3==sum4)
C做变换,恢复到和初始化一样的状态
if(C[key[49]*4+key[50]]>C[key[51]*4+key[52]])
输出c
else if(C[key[49]*4+key[50]]<C[key[51]*4+key[52]])
输出b
else if(C[key[49]*4+key[50]]==C[key[51]*4+key[52]])
输出d
根据username的大小顺序标识,将字母按照对应的顺序连续输出两次就通过算法的验证。
只要做该算法的逆运算就能根据username而得出对应的key,个人觉得注册器通过key来得出username会更为简单。
[招生]科锐逆向工程师培训(2024年11月15日实地,远程教学同时开班, 第51期)