cyclops's Jade Crackme详解
来源:互联网 发布:mac os 10.7的升级包 编辑:程序博客网 时间:2024/06/05 16:51
CM介绍:
这是一个www.crackmes.de上2006的CM。
Download Jade.zip, 6 kb
Browse contents of Jade.zip
This is some thing different from others....
No crypto....But some thing else....
Difficulty: 2 - Needs a little brain (or luck)
Platform: Windows 2000/XP only
Language: C/C++
Published: 26. Jul, 2006
Downloads: 696
在看雪的Crackme2007全集里也有,但不详细!
一、打开这个CM,发现没得文本控件,不能输入用户名和密码之类的。只有两个按键,一个“注册”和“关闭”。点注册也没有反应。用OD打开,查找字串,找到:
00401BE0 . A1 5C464000 mov eax,dword ptr ds:[0x40465C]00401BE5 . 56 push esi00401BE6 . 85C0 test eax,eax00401BE8 . 8BF1 mov esi,ecx00401BEA . 74 22 je X00401C0E00401BEC . 68 58414000 push 00404158 ; Registered!!!00401BF1 . 68 E8030000 push 0x3E800401BF6 . E8 59020000 call <jmp.&MFC42.#CWnd::SetDlgItemTextA_>
看看流程,[0x40465C]里为非0才注册成功。[0x40465C]在哪里赋值呢?用OD的查找常量0x40465C,找到:
00401795 |. 51 push ecx ; 组100401796 |. 52 push edx ; data+t100401797 |. E8 44FBFFFF call 004012E00040179C |. 83C4 08 add esp,0x80040179F |. A3 5C464000 mov dword ptr ds:[0x40465C],eax
只有一个地方,就是call 004012E0的返回值。向上看看,看到:
004016D7 |. E8 8E060000 |call <jmp.&MFC42.#CAsyncSocket::Receive_5478> ; }
居然用CAsyncSocket的Receive来接收数据,看来要先补一补CAsyncSocket(我有另一个文章专门介绍CAsyncSocket的)。
二、根据CAsyncSocket编程流程,先要找到它的Create方法,在OD反汇编窗口,按Ctrl+N,找到:MFC42.#CAsyncSocket::Create_2077,点它,按回车,OK。
0040141E |. 56 push esi0040141F |. 6A 3F push 0x3F00401421 |. 6A 01 push 0x100401423 |. 68 31200000 push 0x203100401428 |. B9 48424000 mov ecx,004042480040142D |. 8975 F8 mov [local.2],esi00401430 |. 8975 F4 mov [local.3],esi00401433 |. E8 4A090000 call <jmp.&MFC42.#CAsyncSocket::Create_2077>
看看Create的参数,Create(0x2031,0x1,0x3F,0),它监听着本机地址的上0x2031端口,所以客户端也要这样。进入监听后,它循环执行Accept(并非CAsyncSocket的正确方法)
,直到有客户端连接。
三、分析Accept后的代码,由于代码太多,这里不粘出来了,主要是4014D6到40179F。以下是分析:
1、4014D6,发送一个“hello”给客户湍。
2、401503,循环接收数据,大小为0x64,记为KEY1。
3、401514,是一个比较函数,比较刚才接收的是否是"---...:: [CYc] ::...---"。
4、401524,随机返回一个数值,再转换成16进制形式的字串,记为RAND。
5、401547,一个简单的反Debug。
6、40158F,循环接收数据,大小为0x64,记为DATA。
7、4015B2,发RAND。
8、4015EC,循环接收数据,大小为0x64,记为SN。
9、401620,循环接收数据,大小为0x64,分析发现这个数据没有用。
10、40162A,是一个反调试,用带反反调试的OD不用理。
11、40168B,循环接收数据,大小为0x64,记为T1。
12、40169D,把T1看成一个8进制字串,转换成16进制,和RAND比较,不对就OVER。
13、4016D7,循环接收数据,大小为0x64,记为KEY2。
14、4016E8,是一个比较函数,比较刚才接收的是否是"---...:: [cYC] ::...---"。
15、401713,把SN转换成SN1+‘-’+SN2。
16、40173F,这段前后是复制字串生成SN1+DATA+T1和DATA+T1。
17、40177A,两个作用。1.生成一个固定的整数数组,记为K1。2.根据K1和SN1+DATA+T1运算出一个数与SN2比较,不对就OVER。
18、401797,根据DATA+T1运算出两个数,转换成16进制字串后与SN1比较,不对就OVER。
19、[0x40465C]为1后,再点注册就可以注册成功了。
四、写逆向代码
先写RAND到T1的算法:
sscanf(RAND,"%x",&len);sprintf(T1,"%o",len);
SN1的算法,我是直接抠汇编:
void CMySocket::GetSN1(const char *indata, char *&outdata){outdata=new char[17];DWORD a=0,b=0;__asm{pushadxor eax,eaxxor edx,edxmov edi,indataxor esi,esimov cl,byte ptr ds:[edi] test cl,clje exit1start1:movsx ecx,clxor ecx,0x159753mov eax,ecxadd edx,ecxor eax,0x237891not eaxand eax,ecxmov cl,byte ptr ds:[esi+edi+0x1] add eax,edxlea edx,dword ptr ds:[edx+esi-0x1] xor edx,0xA6542689inc esitest cl,cljnz start1exit1:mov a,edxmov b,eaxpopad}sprintf(outdata,"%08X%08x",a,b);}
SN2的算法:
void CMySocket::GetSN2(const char *indata, char *&outdata){outdata=new char[9];DWORD sn=0xFFFFFFFF,k=0,*p=0;GetK1(p);__asm{pushadmov edi,pmov edx,indataor eax,0xFFFFFFFF movsx ecx,byte ptr ds:[edx] test ecx,ecxje exit1inc edxloop1:xor ecx,eax and ecx,0xFF shr eax,0x8mov ecx,dword ptr ds:[ecx*4+edi]xor eax,ecxmovsx ecx,byte ptr ds:[edx] inc edxtest ecx,ecxjnz loop1 ; 运算取EAX,要逆这个exit1:not eaxmov sn,eaxpopad}sprintf(outdata,"%x",sn);delete p;}
K1的算法:
int CMySocket::GetK1(DWORD *&K1){K1=new DWORD[0x400];DWORD t=0,i=0,j=0;for (i=0;i<0x400;i++){t=i;for (j=0;j<8;j++){if (t&1==1){__asm{pushadmov eax,tshr eax,1xor eax,0xEDB88320mov t,eaxpopad}}else{__asm{pushadmov eax,tshr eax,1mov t,eaxpopad}}}K1[i]=t;}return 0;}
五、写客户端
void CJade_CMDlg::On1() {const char key1[]="---...:: [CYc] ::...---";const char key2[]="---...:: [cYC] ::...---";char buffer[0x65]={0},*data=0,*sn1=0,*sn2=0,*sn=0,*temp=0;char t1[11]={0};DWORD len=0,stop=0,errorcode=0;if( AfxSocketInit() == FALSE){ AfxMessageBox("Failed to Initialize Sockets"); return; }CAsyncSocket s;if(s.Create(0,SOCK_STREAM,0x3f,"127.0.0.1")==FALSE){myerror(GetLastError());MessageBox("Failed to Create Socket");return;}s.Connect("127.0.0.1",8241);Sleep(200);stop=0;errorcode=s.Receive(buffer,5);while(-1==errorcode){errorcode=s.Receive(buffer,5);stop++;if (stop>10000){AfxMessageBox("Receive1 out time!");return;}}s.Send(key1,strlen(key1));memset(buffer,0xee,0x64);s.Send(buffer,0x64);stop=0;errorcode=s.Receive(t1,2);while(-1==errorcode){errorcode=s.Receive(t1,2);stop++;if (stop>10000){AfxMessageBox("Receive2 out time!");return;}}sscanf(t1,"%x",&len);sprintf(t1,"%o",len);len=0x64+strlen(t1);data=new char[len+1];ZeroMemory(data,len);memset(data,0xee,0x64);strcat(data,t1);GetSN1(data,sn1);delete [] data;len+=strlen(sn1);data=new char[len+1];ZeroMemory(data,len);strcpy(data,sn1);temp=(char*)((DWORD)data+strlen(sn1));memset(temp,0xee,0x64);strcat(data,t1);GetSN2(data,sn2);delete [] data;len=strlen(sn1)+strlen(sn2);sn=new char[len+2];strcpy(sn,sn1);strcat(sn,"-");strcat(sn,sn2);s.Send(sn,strlen(sn));s.Send(sn,strlen(sn));s.Send(t1,strlen(t1));s.Send(key2,strlen(key2));s.Close();//*/delete [] sn,sn1,sn2,data;AfxMessageBox("可以注册了!");}
总结:要注意的是客户端的IP,对本机而言,IP应该是“127.0.0.1”或是网的IP。端口要在连接时输入,在新建时输入会提示错误。
- cyclops's Jade Crackme详解
- Tiger's Crackme
- Duelist's Crackme #3
- Greedy Fly's Crackme
- Aesculapius's Crackme
- XiaoZi's CrackMe
- node框架---Jade详解
- jade
- Diablo 2oo2’s CrackMe 2 算法分析
- 破解教程 第十四课 用S命令破解crackme实例(TRW2000下)
- 《PEDIY CrackMe 2007》学习笔记(一) - 序列号 - aalloverred - Taliesin‘s KGM1Tal
- Triangle CrackMe
- CrackMe-crackhead
- crackme 网站
- Crackme 1
- Crackme 2
- Crackme 3
- Crackme 4
- 反射
- 重写系统确认对话框,使默认选中项为“取消”
- PHPMailer通过163邮箱发信
- C#学习笔记(五)(Winform窗体)(一)
- MyEclipse 8.5 安装 axis2 插件
- cyclops's Jade Crackme详解
- 使用DELETE ADJACENT DUPLICATES FROM <table>注意
- 我的oracle思想001:安装卸载oracle 11g 的心得体会
- JDeveloper介绍视频
- XP下采用DirectShow采集摄像头
- c/c++中的#ifndef和#define
- oracle case when的用法
- Winform MDI窗体子窗体显示区域大小
- 设置Eclipse里面的Android Virtual Device的存储位置