能力值:
( LV12,RANK:260 )
|
-
-
51 楼
RC4可逆,加密和解密都是调用XOR指令,且加密解密可以调用同一个函数。
另外,CRECKME 7中,我的注册码校验不是运用RC4。RC4是用在一个反调试的应用上 :)
呵呵~
可以先出一个破解版吗?
|
能力值:
( LV9,RANK:180 )
|
-
-
52 楼
RC4没Key可逆是书上讲的?
|
能力值:
( LV12,RANK:260 )
|
-
-
53 楼
要KEY,
啊..被你发现关键了~ :)
能绕过去吗?
|
能力值:
( LV9,RANK:180 )
|
-
-
54 楼
这不叫可逆.
另外, 我没看到什么奇怪的地方.
不是要攻击你的Key去解 402260 吗?
|
能力值:
( LV9,RANK:180 )
|
-
-
55 楼
先排除掉攻RC4的做法, 至少我做不到.
NAME 为 p!sessiondiy 时, 可将 func_402260 解成开头为 ret
使之有机会比对序号是否为 'RESERVEME' 若是的话则弹框.
但前提是 -> 下面这行是不是应该 PUSH 0040CCB8
原为 00401AC2 |. 68 BCCC4000 push 0040CCBC
因为序号字符串的位址是放在 0040CCB8 的
(0040CCBC 好像是注册成功视窗里的一个 Label)
附件是我擅自修成 PUSH 0040CCB8 的, 当然其'PE'前的CheckSum我也得一拼改.
不知你真正的用意为何...除此之外, 我没看到其它可能注册成功的方法.
---------------
p!sessiondiy
RESERVEME
---------------
楼主的英文...
|
能力值:
( LV2,RANK:10 )
|
-
-
56 楼
不知道哪里错了
|
能力值:
( LV9,RANK:180 )
|
-
-
57 楼
LZ写CM8的同时顺便帮我讲评一下吧.
我有没有漏了什么?
在不攻RC4Key的情况之下是否有其它的暗桩可使之注册成功?
或CM7的用意是要大家完整解出 func_402260 ?
|
能力值:
( LV12,RANK:260 )
|
-
-
58 楼
我看过你的CRACKME 72了,破解的不完整导致字符串显示错误,在实际中应该会有问题。
具体实现流程和源代码我已发出:http://bbs.pediy.com/showthread.php?p=663830#post663830,CRACKME 7中,我SMC加密部分是用RC4,密码校验部分是用RSA。
还有,我刚刚看了CRACKME 2009大赛规则,好像我的CRACKME里面用的算法 RC4,RSA都是不允许的,晕! 我只是想以一个普通程序员的角度来想尽办法做一个强度高的CRACKME。
下次改进。再次谢谢你的关注!
|
能力值:
( LV9,RANK:180 )
|
-
-
59 楼
你一直没回答我(也可能是所有有下载的人)的问题, 我要知道的是你这 CM7 是要给大家破什么 ?
1. 攻出你 RC4 的 Key 来解 func_402260
2. 不用攻出Key, 即可注册成功.
当时我相信你不会因为没了VMP而做 1 这种事.
因为这三不五时就有不知情的人放这种CM. 只会害到不知情的人. 当然跟帖者也没好话.
所以我研究 2 .
显示字符串问题我在55楼已讲了. 要正常显示甚或指定字符串都很简单.
改 exe 已是我最大的底限了, 所以我只改 1 字节. 因为重点不是这个.
或许你也没料到我CM7是用ret这鸟方式.
(我甚至猜你CM7根本不是要比对'REVERSEME'来弹框)
任何软件到手该做什么破解动作. 我还不至于僵硬到去套用一个破解过程.
我下载了. 你里面应该没有放 CrackME 7 的源码
这不重要.
我知道exe里面有大数库, 但是我没看到你使用他.
所以当时我认为这是你写1~6时所留下来的.
除非...你序号验证程序码是放在 需用RC4_key 才能解开来的 func_402260 里面 换句话说. 你这 CM7 与要大家去爆 rar 密码是一样的意思.
否则请你讲出 情况2 的正确注册成功方式. 注.给其它有下载来玩的人 : RC4_key 就是 UserName
很多人都跟你一样.
最后, 你可否直接回答这个问题 :
CM7 的 Name(RC4的Key), 是用来解 func_402260, Length=3D0h (没记错的话)
里头含有 用RSA来验证序号的程序码. 所有下载玩过你的CM的人都有权知道.
-------------------------------------------------
另外你 http://bbs.pediy.com/showthread.php?p=663830 这一帖写 :
#if _ENABLE_SMCENCRYPT_
enddecrypt:
SMCEncryptEnd
//加密还原回去,否则第二次解密就错了
RC4EncryptBlock((DWORD *)address1,encryCodeSize,Name);
若有人输入的Key刚好解成了 mov [.text/.data], reg/imm 之类的指令
你的程序一样将造成 bug'漏洞'shellcode'崩掉.
若 [.text] 刚好落在你加解密这func, 你一样 "第二次解密就错了"
供你参考.
|
能力值:
( LV2,RANK:10 )
|
-
-
60 楼
来看一看了
|
能力值:
( LV4,RANK:50 )
|
-
-
61 楼
让我望尘莫及的解答 回去再学习去
|
能力值:
( LV12,RANK:260 )
|
-
-
62 楼
呵呵。。。不好意思,上次没有完全领会你的问题。
CM7 我本来的初衷是尝试下SMC+RC4的运用和其强度如何。现在返回去想想,要解出注册码应该就只有你说的暴力破解的方法了。但是在CM7中我也留了破解的洞口。见代码:
DecryptBlock((char *)CalcRegCode,nFuncSize,Name);//首先解密代码段
if(CalcRegCode(Name,SN,szBuff,128))//调用注册码计算函数,只加密了CalcRegCode,并没有加密OnOK();
OnOK();
EncryptBlock((char *)CalcRegCode,nFuncSize,Name);//调用后加密代码段
我这边之加密了CalcRegCode函数,这个函数就是验证注册码的函数,里面用了RSA算法,因为PE文件被加密了,所以你看不到。
在CalcRegCode函数中,我就是对返回的全局字符串进行了定义
TCHAR szBuff[12]={0};
if(lstrcmp(Name,temp)!=0||j==1||len==0) //失败
{
szBuff[0] = 'E'; //测试不直接用字符串
szBuff[1] = 'R';
szBuff[2] = 'R';
szBuff[3] = 'O';
szBuff[4] = 'R';
szBuff[5] = 0x00;
iRet = 0;
}
else //成功
{
szBuff[0] = 'R';
szBuff[1] = 'E';
szBuff[2] = 'V';
szBuff[3] = 'E';
szBuff[4] = 'R';
szBuff[5] = 'S';
szBuff[6] = 'E';
szBuff[7] = 'M';
szBuff[8] = 'E';
szBuff[9] = 0x00;
iRet = 1;
}
theApp.m_reverse =iRet ;
theApp.m_OutPutString = szBuff;
弹出框的确是通过比较字符串来确认的,而且弹出框的过程我没有用SMC保护起来,CRC内存校验部分我也没有用SMC框起来,就是为了给CRACK留个洞口。 当成功弹完框后,我的本意是检验theApp.m_reverse 这个变量再对theApp.m_OutPutString 赋值,然后显示在对话栏中看看到底是被CRACK还是REVERSE的,并且想把这段代码SMC起来,后来发现加了这段代码后CRC校验不过(因为还没运行到SMC部分),想想这个强度已经够了,就没有把它加进去。
总之,C7目前的状态就是以字符串来判断的,唉。。。
我的意思也不是说让大家去暴力破解,我就想看看大牛对SMC有什么高招,就像上次VM那样,还不是被你看得清清楚楚。还有,这次破解的校验我也故意放得很分散,还不是都被你跟到了:( -----------------------------------
#if _ENABLE_SMCENCRYPT_
enddecrypt:
SMCEncryptEnd
//加密还原回去,否则第二次解密就错了
RC4EncryptBlock((DWORD *)address1,encryCodeSize,Name);
若有人输入的Key刚好解成了 mov [.text/.data], reg/imm 之类的指令
你的程序一样将造成 bug'漏洞'shellcode'崩掉.
若 [.text] 刚好落在你加解密这func, 你一样 "第二次解密就错了"
-------------------------------------
里面有catch()捕捉异常,主要考虑两点
1,真正程序中,加SMC都要加catch()捕捉异常防止崩溃。
2,再密码校验时如果真正凑巧跳出异常机制的话,也可以说明注册码是非法的,程序崩溃也不用负责任(这个是我土想的,呵呵 ^_^)
SMC DEMO和C7代码大致是相同的,只是C7写的很乱,没有去整理,我现在也把它发出来吧。嘻嘻,里面英文错了,我也不该了:)
还有,你昨晚通宵?
|
能力值:
( LV9,RANK:180 )
|
-
-
63 楼
你可能没了解我的意思. 你再想想好了.
这题就到这里. 日后旁观你的8'9了.
你1楼的下载连结已被挤到最后, 导致下载的人不多.
睡觉时间得看工作而定.
|
能力值:
( LV12,RANK:260 )
|
-
-
64 楼
嗯,谢谢你的一直关注,我是菜鸟,以后还需向你多多请教。
|
能力值:
( LV5,RANK:60 )
|
-
-
65 楼
我是初学者,昨天做了两个CM0,CM1
逆出了代码很高兴
CM0就是普通的明码,比较:
name: IndolentAfternoon
key: 5687255
CM1对我们新手有点挑战:
name的必须含有子串“ZENG”,而且offset必须大于0.
key的判定:第0位必须为5,第4,5位必须为"31",第1位为所有偶数位字符之和,其他的数据可以任意构造好像。不知道这个算不算写出注册机了,我是新手不懂
我不是通过查找字符串定位的,我是通过假码输入,暂停然后回溯call stack,然后向上分析解之
随便举个:
YZENGJ
5900311
楼主的CM1写的很好哦,对新手很练手
明天开始逆你的CM2。
|
能力值:
( LV5,RANK:60 )
|
-
-
66 楼
感谢楼主哦,CM2,CM3也逆出算法了
CM3楼主好像在里面故意绕来绕去,特别是那个自定义函数,参数传递的是ECX中寄存器,我还以为那个参数是可变的,弄好久,后来那个参数是固定的从0012fefc中读出的,很不错的CM
明天试试你的CM4,还有你CM3成功提示不准确额:You can come here,and I think you aren't a rookie now.
I just study reversing a week, and I think I'm a rookie now.
thanks !!
|
能力值:
( LV5,RANK:60 )
|
-
-
67 楼
楼主能透漏下,CM3防爆破的方法吗?
而且我发现在调试状态下,那个成功对话框是不出的,进程直接结束了
|
能力值:
( LV12,RANK:260 )
|
-
-
68 楼
是CRC校验,在调试的时候有设中断,CRC校验值发生变化就通不过了。
|
能力值:
( LV5,RANK:60 )
|
-
-
69 楼
那么硬件中断呢?不写入0x0CC,这样CRC校验值不会变化吧
|
能力值:
( LV2,RANK:10 )
|
-
-
70 楼
菜鸟一个... 看了破文也没有追出注册码. 爆了一个. 继续....
|
能力值:
( LV2,RANK:10 )
|
-
-
71 楼
crackme1明码:
name: IndolentAfternoon
key: 5687255
crackme2:
name必须含'ZENG'(大写).且开头要有别的字符.(如ZENG111无效)并且name长度大于6.
key第0位必须为5. 4.5 2位必须是31,第1位为各偶数位之和.如果偶数位之和大于10,也是无效的.,key长度也必须大于6.
crackme3:
满足下列条件即可:(name的长度必须为6,多一位少一位都不行.),key必须为数字,并且必须大于100000.
(name[0]+name[1]+name[2]) * 1000 + (name[3]+name[4]+name[5]) = key
|
能力值:
( LV4,RANK:50 )
|
-
-
72 楼
楼主貌似CRACK4弄反了,附件里面的crackme4修正版是原来的版本,而crackme0-5里面的是新的版本...
贴上注册机源代码,高手不要笑哈~~
#include <stdio.h>
#include <Windows.h>
#include<intrin.h>
#include "md5.c"
void XOR(DWORD *buff,__int64 *key)
{
*key = buff[1]^buff[7]^buff[5] ^ buff[3];
*key <<= 32;
*key |= (buff[0]^buff[6]^buff[4]^ buff[2]);
return;
}
int main()
{
char name[20]={0},code[20]={0};
DWORD xor_buff[8]={0};
printf("输入用户名(6个字符):");
scanf("%s",name);
if (strlen(name)!=6)
{
return FALSE;
}
__int64 mul_name=0,cpu_key=0,temp=0;
//用户名前3位相乘的2倍
mul_name = 2*name[0]*name[1]*name[2];
//printf("%I64u",mul_name);
int CPUInfo[4] = {-1};
//获取cpu信息
__cpuid(CPUInfo,1);
memcpy(xor_buff,CPUInfo+3,sizeof(BYTE)*4);
memcpy(xor_buff+2,CPUInfo,sizeof(BYTE)*4);
__cpuid(CPUInfo,3);
memcpy(xor_buff+4,CPUInfo+3,sizeof(BYTE)*4);
memcpy(xor_buff+6,CPUInfo+2,sizeof(BYTE)*4);
DWORD result[2]={-1};
//做异或
XOR(xor_buff,&cpu_key);
//与前面的结果做与运算
temp = mul_name|cpu_key;
char md5_code[9] = {0};
BYTE md5_result[16];
//貌似源程序只用了32位作为参数
sprintf(md5_code,"%x",(DWORD)temp);
//对得到的字符串MD5加密
MD5_CTX md5_contex;
MD5Init(&md5_contex);
MD5Update(&md5_contex,(UCHAR *)md5_code,8);
MD5Final(md5_result,&md5_contex);
//结果转置后做异或
RtlZeroMemory(xor_buff,sizeof(DWORD)*8);
BYTE *p=(BYTE *)xor_buff;
int i=0;
while(i<16){
p[0+i*2]=md5_result[3+i];
p[1+i*2]=md5_result[2+i];
p[2+i*2]=md5_result[1+i];
p[3+i*2]=md5_result[0+i];
i+=4;
}
XOR(xor_buff,&temp);
printf("注册码:%I64d\n",temp);
return TRUE;
}
|
能力值:
( LV15,RANK:1395 )
|
-
-
73 楼
收藏一个,学习
|
能力值:
( LV12,RANK:260 )
|
-
-
74 楼
没有弄反,md5是单向算法,我的意思是md5(F(NAME,SN))=A,如果A不是固定值的话,你看,就被你写成注册机了:) 如果A是固定值的话,如果不用爆破的话,无解,只有穷举法。
|
能力值:
( LV4,RANK:50 )
|
-
-
75 楼
原来是这样啊......嘿嘿
|
|
|