OCN CrackMe2003算法分析+C++注册机源码
【破文标题】OCN CrackMe2003算法分析+C++注册机源码
【破解作者】hrbx
【作者主页】hrbx.ys168.com
【作者邮箱】[email protected]
【破解平台】WinXP
【使用工具】flyOD1.10、Peid
【破解日期】2006-01-03
【软件名称】OCN CrackMe2003
【软件大小】176KB
【下载地址】http://ocn.e5v.com/bbs1/viewthread.php?tid=1113&fpage=1&highlight=&page=1
【加壳方式】UPX 0.89.6 - 1.02 / 1.05 - 1.24 -> Markus & Laszlo
【软件简介】OCN CrackMe2003
-----------------------------------------------------------------------------------------------
【破解声明】我是一只小菜鸟,偶得一点心得,愿与大家分享:)
-----------------------------------------------------------------------------------------------
【破解过程】
1.脱壳。用Peid扫描程序,显示为:UPX 0.89.6 - 1.02 / 1.05 - 1.24 -> Markus & Laszlo。
直接用PEID自带的脱壳插件脱之,脱壳后再次用Peid扫描,显示为:Borland Delphi 4.0 - 5.0。
2.试运行。输入注册信息,点注册按钮后程序没有任何提示。通过DeDe分析得知,确定按钮事件开始地址为0044FEF8。
3.追出算法。OD载入,Ctrl+G,输入 0044FEF8,回车,在0044FEF8处按F2下断,F9运行,输入注册信息:
================================
机器码:0186809720
用户名:hrbx
注册码:9876543210
================================
点击注册按钮立即中断:
0044FEF8 55 push ebp ; F2在此下断,中断后F8往下走
0044FEF9 8BEC mov ebp,esp
0044FEFB B9 0B000000 mov ecx,0B
0044FF00 6A 00 push 0
0044FF02 6A 00 push 0
0044FF04 49 dec ecx
0044FF05 ^ 75 F9 jnz short Unpack20.0044FF00
0044FF07 53 push ebx
0044FF08 56 push esi
0044FF09 57 push edi
0044FF0A 8BF0 mov esi,eax
0044FF0C 33C0 xor eax,eax
0044FF0E 55 push ebp
0044FF0F 68 8A014500 push Unpack20.0045018A
0044FF14 64:FF30 push dword ptr fs:
0044FF17 64:8920 mov dword ptr fs:,esp
0044FF1A 8D55 CC lea edx,dword ptr ss:
0044FF1D 8B86 F4020000 mov eax,dword ptr ds:
0044FF23 E8 3046FDFF call Unpack20.00424558 ; 获取用户名长度,EAX=4
0044FF28 837D CC 00 cmp dword ptr ss:,0 ; 比较用户是否为空
0044FF2C 75 1F jnz short Unpack20.0044FF4D ; 用户名不为空则跳
0044FF2E 8B86 F4020000 mov eax,dword ptr ds:
0044FF34 33D2 xor edx,edx
0044FF36 E8 4D46FDFF call Unpack20.00424588
0044FF3B 8B86 F8020000 mov eax,dword ptr ds:
0044FF41 33D2 xor edx,edx
0044FF43 E8 4046FDFF call Unpack20.00424588
0044FF48 E9 E3010000 jmp Unpack20.00450130
0044FF4D 8D55 C8 lea edx,dword ptr ss:
0044FF50 8B86 F8020000 mov eax,dword ptr ds:
0044FF56 E8 FD45FDFF call Unpack20.00424558 ; 获取注册码长度,EAX=0xA
0044FF5B 837D C8 00 cmp dword ptr ss:,0 ; 比较注册码是否为空
0044FF5F 75 1F jnz short Unpack20.0044FF80 ; 注册码不为空则跳
0044FF61 8B86 F4020000 mov eax,dword ptr ds:
0044FF67 33D2 xor edx,edx
0044FF69 E8 1A46FDFF call Unpack20.00424588
0044FF6E 8B86 F8020000 mov eax,dword ptr ds:
0044FF74 33D2 xor edx,edx
0044FF76 E8 0D46FDFF call Unpack20.00424588
0044FF7B E9 B0010000 jmp Unpack20.00450130
0044FF80 8D55 E0 lea edx,dword ptr ss:
0044FF83 8B86 00030000 mov eax,dword ptr ds:
0044FF89 E8 CA45FDFF call Unpack20.00424558 ; 获取机器码长度,EAX=0xA
0044FF8E 8D55 C4 lea edx,dword ptr ss:
0044FF91 8B45 E0 mov eax,dword ptr ss: ; 机器码"0186809720"
0044FF94 E8 27FCFFFF call Unpack20.0044FBC0 ; 关键CALL-1,F7进入
0044FF99 8B45 C4 mov eax,dword ptr ss: ; 机器码运算得到字符串"4846"
0044FF9C E8 BF7EFBFF call Unpack20.00407E60 ; 字符串"4846"转为16进制数0x12EE
0044FFA1 99 cdq
0044FFA2 8945 D0 mov dword ptr ss:,eax ; EAX保存,EAX=0x12EE
0044FFA5 8955 D4 mov dword ptr ss:,edx
0044FFA8 8D55 C0 lea edx,dword ptr ss:
0044FFAB 8B86 F4020000 mov eax,dword ptr ds:
0044FFB1 E8 A245FDFF call Unpack20.00424558 ; 获取用户名长度,EAX=4
0044FFB6 8B45 C0 mov eax,dword ptr ss: ; 用户名"hrbx"
0044FFB9 8D55 DC lea edx,dword ptr ss:
0044FFBC E8 FFFBFFFF call Unpack20.0044FBC0 ; 同上面关键CALL-1,见前面分析
0044FFC1 C745 F0 00000000 mov dword ptr ss:,0 ; 用户名运算得到的字符串"3085"
0044FFC8 C745 F4 00000000 mov dword ptr ss:,0
0044FFCF C745 E8 00000000 mov dword ptr ss:,0
0044FFD6 C745 EC 00000000 mov dword ptr ss:,0
0044FFDD 8D45 E4 lea eax,dword ptr ss:
0044FFE0 E8 6739FBFF call Unpack20.0040394C
0044FFE5 8B45 DC mov eax,dword ptr ss:
0044FFE8 E8 DF3BFBFF call Unpack20.00403BCC ; 获取字符串"3085"长度,EAX=4
0044FFED 8BF8 mov edi,eax ; EDI=EAX=4
0044FFEF 85FF test edi,edi
0044FFF1 0F8E DF000000 jle Unpack20.004500D6
0044FFF7 BB 01000000 mov ebx,1 ; EBX赋初值,EBX=1
0044FFFC 8D45 BC lea eax,dword ptr ss:
0044FFFF 8B55 DC mov edx,dword ptr ss: ; 字符串"3085"
00450002 8A541A FF mov dl,byte ptr ds: ; 循环取字符串"3085"每一位的ASCII值
00450006 E8 E93AFBFF call Unpack20.00403AF4
0045000B 8B45 BC mov eax,dword ptr ss:
0045000E E8 4D7EFBFF call Unpack20.00407E60 ; 取ASCII值相应的字符,第一位字符"3",EAX=3
00450013 F7EB imul ebx ; EAX=EAX*EBX,字符*字符在字符串的位置
00450015 99 cdq
00450016 0345 E8 add eax,dword ptr ss: ; EAX=EAX+ ss:,ss:为下面保存的EAX值
00450019 1355 EC adc edx,dword ptr ss:
0045001C 52 push edx
0045001D 50 push eax
0045001E 8BC3 mov eax,ebx
00450020 99 cdq
00450021 52 push edx
00450022 50 push eax ; 将EAX压入地址ss:处
00450023 8B45 D0 mov eax,dword ptr ss: ; EAX=ss:=0x12EE,即机器码运算结果
00450026 8B55 D4 mov edx,dword ptr ss:
00450029 E8 F25BFBFF call Unpack20.00405C20 ; EAX=0X12EE*循环次数
0045002E 030424 add eax,dword ptr ss: ; EAX=EAX+ss:,ss:即上面EAX的值
00450031 135424 04 adc edx,dword ptr ss:
00450035 83C4 08 add esp,8
00450038 8945 E8 mov dword ptr ss:,eax ; EAX保存在ss:,供上面加法调用,EAX=0XBD7B
0045003B 8955 EC mov dword ptr ss:,edx
0045003E 8D45 B4 lea eax,dword ptr ss:
00450041 8B55 DC mov edx,dword ptr ss: ; 字符串"3085"
00450044 8A541A FF mov dl,byte ptr ds: ; 循环取字符串"3085"第一位的ASCII值,0x33("3")
00450048 8850 01 mov byte ptr ds:,dl
0045004B C600 01 mov byte ptr ds:,1
0045004E 8D55 B4 lea edx,dword ptr ss:
00450051 8D45 B0 lea eax,dword ptr ss:
00450054 E8 4328FBFF call Unpack20.0040289C
00450059 8D45 AC lea eax,dword ptr ss:
0045005C 8B55 DC mov edx,dword ptr ss:
0045005F 8A141A mov dl,byte ptr ds: ; 循环取字符串"3085"第二位的ASCII值,0x30("0")
00450062 8850 01 mov byte ptr ds:,dl
00450065 C600 01 mov byte ptr ds:,1
00450068 8D55 AC lea edx,dword ptr ss:
0045006B 8D45 B0 lea eax,dword ptr ss:
0045006E B1 02 mov cl,2
00450070 E8 F727FBFF call Unpack20.0040286C ; 连接每次取出的两个字符
00450075 8D55 B0 lea edx,dword ptr ss: ; 得到字符串"30"
00450078 8D45 B8 lea eax,dword ptr ss:
0045007B E8 F03AFBFF call Unpack20.00403B70
00450080 8B45 B8 mov eax,dword ptr ss:
00450083 E8 D87DFBFF call Unpack20.00407E60 ; 字符串"30"转为16进制数形式,0x1E
00450088 50 push eax ; EAX=0x1E
00450089 8B45 DC mov eax,dword ptr ss:
0045008C E8 CF7DFBFF call Unpack20.00407E60 ; 字符串"3085"转为16进制数形式,0xC0D
00450091 5A pop edx ; EDX为每次取的两个字符的16进制形式,30=0x1E
00450092 0FAFD0 imul edx,eax ; EDX=EAX*EDX,EAX为"3085"各位字符ASCII值之和0xCOD
00450095 8BC2 mov eax,edx ; EAX=EDX
00450097 99 cdq
00450098 0345 F0 add eax,dword ptr ss: ; EAX=EAX+ss:,运算结果累加
0045009B 1355 F4 adc edx,dword ptr ss:
0045009E 8945 F0 mov dword ptr ss:,eax ; EAX保存
004500A1 8955 F4 mov dword ptr ss:,edx
004500A4 6A 00 push 0
004500A6 68 49010000 push 149 ; 常数,0x149
004500AB 8B45 F0 mov eax,dword ptr ss:
004500AE 8B55 F4 mov edx,dword ptr ss:
004500B1 E8 6A5BFBFF call Unpack20.00405C20 ; EAX=EAX*0x149
004500B6 52 push edx ; 得到EAX=0x07BE5A80
004500B7 50 push eax
004500B8 8D45 FC lea eax,dword ptr ss:
004500BB E8 307DFBFF call Unpack20.00407DF0 ; 0x07BE5A80转为10进制形式,0x07BE5A80=129915520
004500C0 FF75 EC push dword ptr ss:
004500C3 FF75 E8 push dword ptr ss: ; 取出前面保存的数值,ss:=0xBD7B
004500C6 8D45 F8 lea eax,dword ptr ss:
004500C9 E8 227DFBFF call Unpack20.00407DF0 ; 0xBD7B转为10进制形式,0xBD7B=48507
004500CE 43 inc ebx
004500CF 4F dec edi
004500D0 ^ 0F85 26FFFFFF jnz Unpack20.0044FFFC ; 没取完字符串则跳回去继续循环
004500D6 FF75 FC push dword ptr ss: ; "129915520"
004500D9 68 A0014500 push Unpack20.004501A0
004500DE FF75 F8 push dword ptr ss: ; "48507"
004500E1 8D45 E4 lea eax,dword ptr ss:
004500E4 BA 03000000 mov edx,3
004500E9 E8 9E3BFBFF call Unpack20.00403C8C ; 连接字符串"129915520"和"48507"
004500EE 8D55 A8 lea edx,dword ptr ss:
004500F1 8B86 F8020000 mov eax,dword ptr ds:
004500F7 E8 5C44FDFF call Unpack20.00424558
004500FC 8B55 A8 mov edx,dword ptr ss: ; 假码"9876543210"
004500FF 8B45 E4 mov eax,dword ptr ss: ; 真码"129915520-48507",内存注册机
00450102 E8 6DFBFFFF call Unpack20.0044FC74 ; 真假码比较CALL
00450107 3C 01 cmp al,1
00450109 75 25 jnz short Unpack20.00450130 ; 暴破点,NOP掉
0045010B B1 0A mov cl,0A
F7进入0044FF94处的关键CALL-1,来到:
0044FBC0 55 push ebp
0044FBC1 8BEC mov ebp,esp
0044FBC3 83C4 F0 add esp,-10
0044FBC6 56 push esi
0044FBC7 33C9 xor ecx,ecx
0044FBC9 894D F0 mov dword ptr ss:,ecx
0044FBCC 894D F4 mov dword ptr ss:,ecx
0044FBCF 8955 F8 mov dword ptr ss:,edx
0044FBD2 8945 FC mov dword ptr ss:,eax
0044FBD5 8B45 FC mov eax,dword ptr ss:
0044FBD8 E8 A341FBFF call Unpack20.00403D80
0044FBDD 33C0 xor eax,eax
0044FBDF 55 push ebp
0044FBE0 68 65FC4400 push Unpack20.0044FC65
0044FBE5 64:FF30 push dword ptr fs:
0044FBE8 64:8920 mov dword ptr fs:,esp
0044FBEB 8D45 F4 lea eax,dword ptr ss:
0044FBEE E8 593DFBFF call Unpack20.0040394C
0044FBF3 33F6 xor esi,esi
0044FBF5 8D55 F0 lea edx,dword ptr ss:
0044FBF8 8B45 FC mov eax,dword ptr ss: ; 机器码"0186809720"
0044FBFB E8 0C81FBFF call Unpack20.00407D0C
0044FC00 8B45 F0 mov eax,dword ptr ss:
0044FC03 E8 C43FFBFF call Unpack20.00403BCC ; 获取机器码长度,EAX=0xA
0044FC08 8BD0 mov edx,eax
0044FC0A 85D2 test edx,edx
0044FC0C 7E 1B jle short Unpack20.0044FC29
0044FC0E B8 01000000 mov eax,1 ; EAX赋初值1,EAX为所取字符在字符串的位置
0044FC13 8B4D FC mov ecx,dword ptr ss: ; 机器码"0186809720"
0044FC16 8A4C01 FF mov cl,byte ptr ds: ; 循环取机器码每一位的ASCII值
0044FC1A 81E1 FF000000 and ecx,0FF ; ECX=ECX and 0FF
0044FC20 0FAFC8 imul ecx,eax ; ECX=ECX*EAX
0044FC23 03F1 add esi,ecx ; ESI=ESI+ECX,累加每次运算结果
0044FC25 40 inc eax ; EAX加1,取机器码下一位
0044FC26 4A dec edx ; EDX减1
0044FC27 ^ 75 EA jnz short Unpack20.0044FC13 ; 没取完机器码则跳回去继续
0044FC29 8D55 F4 lea edx,dword ptr ss: ; 机器码运算结果,ECX=0x12EE
0044FC2C 8D86 BB070000 lea eax,dword ptr ds: ; EAX=ESI+7BB=0x12EE
0044FC32 E8 8981FBFF call Unpack20.00407DC0 ; 运算结果转为10进制,0x12EE=4846
0044FC37 8B45 F8 mov eax,dword ptr ss:
0044FC3A 8B55 F4 mov edx,dword ptr ss: ; EDX=ss:,"4846"
0044FC3D E8 5E3DFBFF call Unpack20.004039A0
0044FC42 33C0 xor eax,eax
0044FC44 5A pop edx
0044FC45 59 pop ecx
0044FC46 59 pop ecx
0044FC47 64:8910 mov dword ptr fs:,edx
0044FC4A 68 6CFC4400 push Unpack20.0044FC6C
0044FC4F 8D45 F0 lea eax,dword ptr ss:
0044FC52 BA 02000000 mov edx,2
0044FC57 E8 143DFBFF call Unpack20.00403970
0044FC5C 8D45 FC lea eax,dword ptr ss:
0044FC5F E8 E83CFBFF call Unpack20.0040394C
0044FC64 C3 retn
-----------------------------------------------------------------------------------------------
【破解总结】
1.程序循环取机器码每一位字符的ASCII值*字符在机器码中的位置,结果累加再加上0xFBB,记为Sum1.
2.程序取用户名经过与机器码相同的运算得到一个数值,记为Sum2,将数值Sum2转为字符串,记为str.
3.循环取str中的每一个字符转为数字*字符在字符串str中的位置加上Sum1*字符在字符串str中的位置,结果累加转为字符串,记为st1.
4.循环取str中的每两个字符转为数字*Sum2,结果*0x149,转为字符串,记为st2.
5.依次连接st2,"-",st1即为注册码。
一组可用注册码:
机器码:0186809720
用户名:hrbx
注册码:129915520-48507
暴破更改以下位置:
00450109 jnz short Unpack20.00450130 ; jnz====>NOP
内存注册机:
中断地址:450102
中断次数:1
第一字节:E8
指令长度:5
内存方式--->寄存器:EAX
【C++注册机源码】
//VC6.0+WinXP编译通过
#include <iostream>
using namespace std;
int main ()
{
cout<<"=========================================================\n";
cout<<"= Keygen For OCN CrackMe 2003 =\n";
cout<<"= Cracked By hrbx =\n";
cout<<"= 2006-01-03 =\n";
cout<<"=========================================================\n";
int i,temp,temp1,temp2,Sum1=0x7BB,Sum2=0x7BB,length;
char code,name;
unsigned long Serial1=0,Serial2;
cout<<"Please inter MachineCode:";
cin>>code;
cout<<"Please inter UserName:";
cin>>name;
length=strlen(code);
for (i=0;i<length;i++) Sum1+=code*(i+1);
length=strlen(name);
for (i=0;i<length;i++) Sum2+=(name&0xFF)*(i+1);
temp=temp1=temp2=Sum2;
length=0;
while(temp)
{
length++;
temp/=10;
};
for(i=0;i<length;i++)
{
Serial1+=temp1%10*(length-i)+Sum1*(length-i);
temp1/=10;
}
Serial2=Sum2%10*temp2*0x149;
for(i=0;i<length-1;i++)
{
Serial2+=Sum2%100*temp2*329;
Sum2/=10;
}
cout<<"Your Serial is:"<<Serial2<<"-"<<Serial1<<endl;
system("pause");
return 0;
}
-----------------------------------------------------------------------------------------------
【版权声明】本文纯属技术交流, 转载请注明作者并保持文章的完整, 谢谢!
[ 本帖最后由 hrbx 于 2006-1-4 00:26 编辑 ] 强,算法,我要努力学习 顶你,好好学习学习~~ 不错,加油。 附件呢?有吗? 是呀,有破文没附件不好学呀 文件哪里下 强,学习.支持! 哇,这么多高手。。。。。。。。。。。。。汗 太强了,自己写的注册机!!!/:L
页:
[1]
2