【软件名称】crackme2.exe
【下载地址】见附件
【应用平台】Win9x
【软件大小】未知
【软件限制】未知
【破解声明】破解只是感兴趣,无其它目的。失误之处敬请诸位大侠赐教!
【破解工具】peid ,trw2000,w32dasm
【软件简介】老外写的一个crackme程序,记不清从那里下载的
========================================================================================
【分析过程】
windows下dos窗口程序的破解(涉及浮点汇编指令问题)
用peid检测,无壳,用dev-c++编写的程序,该程序在windows下dos窗口运行,怎么中断呢?
现运行一下程序,dos窗口显示your name: 我们就从这里下手。
先用w32dasm反汇编,查找串参考your name,如下所示:
我们就在trw2000中下中断:bpx 00401663,然后再用TRW2000 load 该程序,就能中断在所设置的断点上。
.....
0167:00401600 C744240430144000 mov [esp+04], 00401430
0167:00401608 C70424B0754300 mov dword ptr [esp], 004375B0
0167:0040160F E8CC090300 call 00431FE0
* Possible StringData Ref from Code Obj ->"Your Name: " //输入姓名 |
0167:00401614 C74424044F144000 mov [esp+04], 0040144F
0167:0040161C C70424B0754300 mov dword ptr [esp], 004375B0
0167:00401623 E8B8090300 call 00431FE0
0167:00401628 8D85F8FEFFFF lea eax, dword ptr [ebp+FFFFFEF8]
0167:0040162E 89442404 mov dword ptr [esp+04], eax
0167:00401632 C7042410754300 mov dword ptr [esp], 00437510
0167:00401639 E842120300 call 00432880
* Possible StringData Ref from Code Obj ->"Your Serial: " //输入序列号
|
0167:0040163E C74424045B144000 mov [esp+04], 0040145B
0167:00401646 C70424B0754300 mov dword ptr [esp], 004375B0
0167:0040164D E88E090300 call 00431FE0
0167:00401652 8D85F8FDFFFF lea eax, dword ptr [ebp+FFFFFDF8]
0167:00401658 89442404 mov dword ptr [esp+04], eax
0167:0040165C C7042410754300 mov dword ptr [esp], 00437510
0167:00401663 E818120300 call 00432880 //取序列号的call 在此下断
0167:00401668 8D85F8FEFFFF LEA EAX,[EBP+FFFFFEF8]
0167:0040166E 890424 MOV [ESP],EAX
0167:00401671 E85AF60000 CALL `MSVCRT!strlen` //取姓名的长度
0167:00401676 89C2 MOV EDX,EAX //eax=7
0167:00401678 69D2CD750800 IMUL EDX,EDX,000875CD //edx=eax*0x875cd=3b389b=3881115
0167:0040167E B81F85EB51 MOV EAX,51EB851F //eax=0x51eb851f
0167:00401683 F7E2 MUL EDX //eax=eax*edx=0x51eb851f*0x3b389b=0xccdd61c5 edx=eax/0xffffffff=0x12f364
0167:00401685 89D0 MOV EAX,EDX //eax=edx
0167:00401687 C1E805 SHR EAX,05 //eax按位右移五位,eax=eax/0x20=0x979b
0167:0040168A 69C090FCFFFF IMUL EAX,EAX,FFFFFC90 //eax=eax*0xfffffc90=0x979b*0xfffffc90=0xfdf6db30
0167:00401690 BA00000000 MOV EDX,00
0167:00401695 52 PUSH EDX
0167:00401696 50 PUSH EAX
0167:00401697 DF2C24 FILD QWORD [ESP] //浮点汇编指令开始,将eax值以整数形式装入[ESP]
0167:0040169A 8D642408 LEA ESP,[ESP+08]
0167:0040169E DD9DF0FBFFFF FSTP QWORD [EBP+FFFFFBF0] //将eax的值0xfdf6db30转换为双精度(64位)浮点数据
0167:004016A4 DD85F0FBFFFF FLD QWORD [EBP+FFFFFBF0] //转换为后的双精度(64位)浮点数据储存
0167:004016AA DD5C2408 FSTP QWORD [ESP+08] //取出转换后为双精度(64位)浮点数据的低端32位数据放入地址[ESP+08],并转换为整数0x66000000(十进制1711276032)
0167:004016AE C744240469144000 MOV DWORD [ESP+04],00401469 //将00401469地址的数据取出放入地址[ESP+04],和上述数据连接一起 下d00401469,显示:-x019871
0167:004016B6 8D85F8FCFFFF LEA EAX,[EBP+FFFFFCF8] //将组合好的数据从地址[EBP+FFFFFCF8]中取出,放入eax中
0167:004016BC 890424 MOV [ESP],EAX
0167:004016BF E8FCF50000 CALL `MSVCRT!sprintf`
0167:004016C4 8D85F8FCFFFF LEA EAX,[EBP+FFFFFCF8] //下deax,显示正确的注册码:1711276032-x019871
0167:004016CA 89442404 MOV [ESP+04],EAX
0167:004016CE 8D85F8FDFFFF LEA EAX,[EBP+FFFFFDF8] //下deax,显示输入的注册码:78787878
0167:004016D4 890424 MOV [ESP],EAX
0167:004016D7 E8D4F50000 CALL `MSVCRT!strcmp` //比较两组数据,不一致则跳,game over!
0167:004016DC 8985ECFBFFFF MOV [EBP+FFFFFBEC],EAX
0167:004016E2 83BDECFBFFFF00 CMP DWORD [EBP+FFFFFBEC],BYTE +00
0167:004016E9 742E JZ 00401719
0167:004016EB C744240490144000 MOV DWORD [ESP+04],00401490
0167:004016F3 C70424B0754300 MOV DWORD [ESP],004375B0
0167:004016FA E8E1080300 CALL 00431FE0
0167:004016FF C70424AF144000 MOV DWORD [ESP],004014AF
0167:00401706 E8D5F50000 CALL `MSVCRT!system`
0167:0040170B C704248F134000 MOV DWORD [ESP],0040138F
0167:00401712 E8C9F50000 CALL `MSVCRT!system`
0167:00401717 EB40 JMP SHORT 00401759
0167:00401719 C7442404B5144000 MOV DWORD [ESP+04],004014B5
0167:00401721 C70424B0754300 MOV DWORD [ESP],004375B0
0167:00401728 E8B3080300 CALL 00431FE0
0167:0040172D C7442404CB144000 MOV DWORD [ESP+04],004014CB
0167:00401735 C70424B0754300 MOV DWORD [ESP],004375B0
0167:0040173C E89F080300 CALL 00431FE0
0167:00401741 C70424AF144000 MOV DWORD [ESP],004014AF
0167:00401748 E893F50000 CALL `MSVCRT!system`
0167:0040174D C704248F134000 MOV DWORD [ESP],0040138F
0167:00401754 E887F50000 CALL `MSVCRT!system`
0167:00401759 B800000000 MOV EAX,00
0167:0040175E 8B7DFC MOV EDI,[EBP-04]
0167:00401761 C9 LEAVE
0167:00401762 C3 RET
========================================================================================
【分析总结】
1. 姓名长度乘以 0x875CD
2. 结果再乘以 0x51EB851F
3. 结果再右移 5位
4. 结果再乘以0xFFFFFC90
5. 结果放入 FPU stack
6. 储存数据为浮点双精度 (real8, 64 bit)
7. 将低端32位再转换位整数
8. 加上后缀 "-x019871".
序列号只和姓名长度有关,注册机如下:
#include <iostream.h>
#include <string.h>
#include <stdlib.h>
#include <math.h>
main()
{
cout<<"the keymaker of crackme2"<<endl;
cout<<"========================"<<endl;
cout<<"made by subTWay+0"<<endl;
cout<<"========================"<<endl;
cout<<endl;
char name[20];
cout<<"please input your name:";
cin>>name;
int len=strlen(name);
unsigned long num1;
double num2,num;
num1=len*0x875CD;
num2=0x51eb851f*num1;
num2=num2/0xffffffff;
num1=num2/32;
num=num1*0xFFFFFC90;
double M;
static int s2[64],s3[32];
int E,S,i;
E=(int)(log(num)/log(2.));
M=num/pow(2,E);
M=M-1;
E=E+0x3ff;
if(num<0)
S=1;
else
S=0;
s2[0]=S;
for(i=1;i<=11;i++)
{
if(E%2==0)
s2[i]=1;
else
s2[i]=0;
E=E/2;
}
for(i=12;i<64;i++)
{
M=M*2;
if(M<1)
s2[i]=0;
else
{
s2[i]=1;
M--;
}
}
for(i=0;i<64;i++)
int key=0;
for(i=32;i<64;i++)
key=key+s2[i]*pow(2,63-i);
cout<<"you password is: "<<key<<"-x019871"<<endl;
system ("PAUSE");
return 0;
}
========================================================================================
【版权信息】
copyright subtway+0 all rights reserved
2004-12-29附件:C2.rar
[招生]科锐逆向工程师培训(2024年11月15日实地,远程教学同时开班, 第51期)