-
-
[原创]lsunday的cm源码及简单分析
-
发表于:
2009-9-25 15:52
7414
-
参加这次cm比赛目的在于交流技术,写了我cm的思路供大家参考,具体情形请参考源码。
1.输入用户名,不够32字节重复复制,扩展成32字节。
for(i=0,j=0,len=strlen(szName1);i<32;i++)
{
szName1[i]=szName1[(j++)%len];
}
2.从name中计算出c[0],c[1],c[2],c[3]备用。
for(i=0;i<4;i++)
{
for(j=0;j<4;j++)
c[i]=c[i]*256+(BYTE)(szName1[j*8+i]*szName1[j*8+i+4]);
}
3.输入序列号,必须32字节,8字节一组,通过映射函数将一字节转换成4bit形成四个unsigned int 型变量x[0],x[1],x[2],x[3]备用。
int SerialToX(char ch)
{
if(ch>='0'&&ch<='9')
return ch-'0';
if(ch>='a'&&ch<='z')
return (ch-'a'+10)%16;
if(ch>='A'&&ch<='Z')
return (ch-'A'+10)%16;
}
4.用x[],c[]和a[][](线性方程组的系数矩阵),b=A*x-c计算出b[0],b[1],b[2],b[3],他们就是程序中必须满足的四个量,如果不和预计指向等不会得到正确结果。
x[0]用于跳转到成功注册函数的地址
x[1]用于解密将用道德dll的名称
x[2]用于对显示字符串解密
x[3]用于解密成功注册函数
【注】该算法的理论基础为:
A是整型矩阵,|A|=1<=>A^-1也是整型矩阵,保证了线性方程组有唯一解。
由于实际实现时x[1]没有起到作用,一个用户名可能对应多个序列号。具体细节参见程序。
A矩阵
81269 -68028 73939 -87743
-74628 62469 -67897 80573
85019 -71167 77351 -91792
-77801 65125 -70784 83999
A^-1矩阵
317 380 -93 -135
340 413 -97 -147
267 329 -25 -64
255 309 -32 -65
程序要在编译之后做以下事情:
修改CrackMe_Win32.h的宏常量
去掉Success函数//如果没有call Success函数,不会编译Success
修改.text区段属性//让其为可写
xor.exe//加密成功注册函数
去掉nop指令//nop用于定位重要地址,修改宏常量时用到
以上方法可能会有些麻烦,欢迎大家批评指教。第一次写文章,不周之处请见谅。
[招生]科锐逆向工程师培训(2024年11月15日实地,远程教学同时开班, 第51期)