【文章标题】: 我的第一次,写注册机【邀请码已发】
【软件名称】: 房友软件 V9.7
【保护方式】: ASPack 2.12 -> Alexey Solodovnikov
【使用工具】: OD,PEID
【操作平台】: WINDOWS XP SP3
【作者声明】: 只是感兴趣,练习,没有其他目的。
首先PEID查壳,结果为ASPack 2.12,老牌的压缩壳,没什么难度,想怎么搞,随便你了,ESP定律,单步,或者其它的,为了方便,直接弄个脱壳机,这个看雪也有下载,不多说,脱之...命名为crack.exe
直接运行crack.exe,无问题,说明脱壳正常。
接下来,OD载入,F9直接跑起,出现一个小窗口,给出了你硬盘指纹(6位),提示需要输入6位的验证码,OK,随便输,"123456",单击“确定”,提示错误,要的就是这个,切换OD,按“F12”,ALT+K,右击(一般是)最后一个,选择SHOW CALL,然后直接 ALT+F9,这时再跑去点掉刚才的提示,此时OD停在了用户的代码区,此时走过2个 retn,再往上翻就看到下面的一段代码
01BB646B 8B02 mov eax, dword ptr [edx] ; 硬盘指纹
01BB646D 50 push eax
01BB646E FF15 2C10B901 call dword ptr [0x1B9102C] ; 获取指纹长度
01BB6474 8B35 9812B901 mov esi, dword ptr [0x1B91298] ; msvbvm60.__vbaStrMove
01BB647A 8B3D 2811B901 mov edi, dword ptr [0x1B91128] ; msvbvm60.__vbaStrCmp
01BB6480 8B1D 0810B901 mov ebx, dword ptr [0x1B91008] ; msvbvm60.__vbaStrI2
01BB6486 8985 7CFFFFFF mov dword ptr [ebp-0x84], eax ; 将长度存入dword ptr [ebp-0x84]
01BB648C B8 01000000 mov eax, 0x1
01BB6491 8945 E8 mov dword ptr [ebp-0x18], eax
01BB6494 3B85 7CFFFFFF cmp eax, dword ptr [ebp-0x84] ; 开始--根据硬盘指纹获取邀请码.此处为一个for循环的开始,
01BB649A 0F8F C9010000 jg 01BB6669 ; 比如:for(eax =1;eax<=dword ptr [ebp-0x84];eax++)
01BB64A0 8B4D 08 mov ecx, dword ptr [ebp+0x8]
01BB64A3 8D55 C8 lea edx, dword ptr [ebp-0x38]
01BB64A6 52 push edx
01BB64A7 50 push eax
01BB64A8 894D A0 mov dword ptr [ebp-0x60], ecx
01BB64AB 8D45 98 lea eax, dword ptr [ebp-0x68]
01BB64AE 8D4D B8 lea ecx, dword ptr [ebp-0x48]
01BB64B1 50 push eax
01BB64B2 51 push ecx
01BB64B3 C745 D0 0100000>mov dword ptr [ebp-0x30], 0x1
01BB64BA C745 C8 0200000>mov dword ptr [ebp-0x38], 0x2
01BB64C1 C745 98 0840000>mov dword ptr [ebp-0x68], 0x4008
01BB64C8 FF15 0811B901 call dword ptr [0x1B91108] ; 中截取,将指纹中的当前位取出
01BB64CE 8D55 B8 lea edx, dword ptr [ebp-0x48]
01BB64D1 52 push edx
01BB64D2 FF15 3410B901 call dword ptr [0x1B91034] ; msvbvm60.__vbaStrVarMove
01BB64D8 8BD0 mov edx, eax
01BB64DA 8D4D E0 lea ecx, dword ptr [ebp-0x20]
01BB64DD FFD6 call esi
01BB64DF 8D45 B8 lea eax, dword ptr [ebp-0x48]
01BB64E2 8D4D C8 lea ecx, dword ptr [ebp-0x38]
01BB64E5 50 push eax
01BB64E6 51 push ecx
01BB64E7 6A 02 push 0x2
01BB64E9 FF15 4010B901 call dword ptr [0x1B91040] ; msvbvm60.__vbaFreeVarList
01BB64EF 8B55 E0 mov edx, dword ptr [ebp-0x20]
01BB64F2 83C4 0C add esp, 0xC
01BB64F5 8D4D 84 lea ecx, dword ptr [ebp-0x7C]
01BB64F8 FF15 1412B901 call dword ptr [0x1B91214] ; msvbvm60.__vbaStrCopy
01BB64FE 8B55 84 mov edx, dword ptr [ebp-0x7C] ;以下为判断,根据上面获取的一位数值,获取一对应码
01BB6501 52 push edx ; 当前数值
01BB6502 68 808AB901 push 01B98A80 ; 比较码 1
01BB6507 FFD7 call edi
01BB6509 85C0 test eax, eax
01BB650B 75 10 jnz short 01BB651D ; 判断这里是不是和1相等,如果不是则跳转
01BB650D 6A 04 push 0x4 ; 如果相等则 返回 4
01BB650F FFD3 call ebx
01BB6511 8BD0 mov edx, eax
01BB6513 8D4D E4 lea ecx, dword ptr [ebp-0x1C]
01BB6516 FFD6 call esi
01BB6518 E9 1F010000 jmp 01BB663C
01BB651D 8B45 84 mov eax, dword ptr [ebp-0x7C] ; dword ptr [ebp-0x7C]中存放的是 当前数值
01BB6520 50 push eax
01BB6521 68 048BB901 push 01B98B04 ; 比较码 4
01BB6526 FFD7 call edi
01BB6528 85C0 test eax, eax
01BB652A 75 10 jnz short 01BB653C ; 判断这里是不是和4相等,如果不是则跳转
01BB652C 6A 07 push 0x7 ; 如果相等则 返回 7
01BB652E FFD3 call ebx
01BB6530 8BD0 mov edx, eax
01BB6532 8D4D E4 lea ecx, dword ptr [ebp-0x1C]
01BB6535 FFD6 call esi
01BB6537 E9 00010000 jmp 01BB663C
01BB653C 8B4D 84 mov ecx, dword ptr [ebp-0x7C]
01BB653F 51 push ecx
01BB6540 68 9C8BB901 push 01B98B9C ; 比较码 7
01BB6545 FFD7 call edi
01BB6547 85C0 test eax, eax
01BB6549 75 10 jnz short 01BB655B
01BB654B 6A 01 push 0x1 ; 返回1
01BB654D FFD3 call ebx
01BB654F 8BD0 mov edx, eax
01BB6551 8D4D E4 lea ecx, dword ptr [ebp-0x1C]
01BB6554 FFD6 call esi
01BB6556 E9 E1000000 jmp 01BB663C
01BB655B 8B55 84 mov edx, dword ptr [ebp-0x7C]
01BB655E 52 push edx
01BB655F 68 AC8AB901 push 01B98AAC ; 比较码 2
01BB6564 FFD7 call edi
01BB6566 85C0 test eax, eax
01BB6568 75 10 jnz short 01BB657A
01BB656A 6A 05 push 0x5
01BB656C FFD3 call ebx
01BB656E 8BD0 mov edx, eax
01BB6570 8D4D E4 lea ecx, dword ptr [ebp-0x1C]
01BB6573 FFD6 call esi
01BB6575 E9 C2000000 jmp 01BB663C
01BB657A 8B45 84 mov eax, dword ptr [ebp-0x7C]
01BB657D 50 push eax
01BB657E 68 3C8BB901 push 01B98B3C ; 比较码 5
01BB6583 FFD7 call edi
01BB6585 85C0 test eax, eax
01BB6587 75 10 jnz short 01BB6599
01BB6589 6A 08 push 0x8
01BB658B FFD3 call ebx
01BB658D 8BD0 mov edx, eax
01BB658F 8D4D E4 lea ecx, dword ptr [ebp-0x1C]
01BB6592 FFD6 call esi
01BB6594 E9 A3000000 jmp 01BB663C
01BB6599 8B4D 84 mov ecx, dword ptr [ebp-0x7C]
01BB659C 51 push ecx
01BB659D 68 E48BB901 push 01B98BE4 ; 比较码 8
01BB65A2 FFD7 call edi
01BB65A4 85C0 test eax, eax
01BB65A6 75 10 jnz short 01BB65B8
01BB65A8 6A 02 push 0x2
01BB65AA FFD3 call ebx
01BB65AC 8BD0 mov edx, eax
01BB65AE 8D4D E4 lea ecx, dword ptr [ebp-0x1C]
01BB65B1 FFD6 call esi
01BB65B3 E9 84000000 jmp 01BB663C
01BB65B8 8B55 84 mov edx, dword ptr [ebp-0x7C]
01BB65BB 52 push edx
01BB65BC 68 D48AB901 push 01B98AD4 ; 比较码 3
01BB65C1 FFD7 call edi
01BB65C3 85C0 test eax, eax
01BB65C5 75 0D jnz short 01BB65D4
01BB65C7 6A 06 push 0x6
01BB65C9 FFD3 call ebx
01BB65CB 8BD0 mov edx, eax
01BB65CD 8D4D E4 lea ecx, dword ptr [ebp-0x1C]
01BB65D0 FFD6 call esi
01BB65D2 EB 68 jmp short 01BB663C
01BB65D4 8B45 84 mov eax, dword ptr [ebp-0x7C]
01BB65D7 50 push eax
01BB65D8 68 708BB901 push 01B98B70 ; 比较码 6
01BB65DD FFD7 call edi
01BB65DF 85C0 test eax, eax
01BB65E1 75 0D jnz short 01BB65F0
01BB65E3 6A 09 push 0x9
01BB65E5 FFD3 call ebx
01BB65E7 8BD0 mov edx, eax
01BB65E9 8D4D E4 lea ecx, dword ptr [ebp-0x1C]
01BB65EC FFD6 call esi
01BB65EE EB 4C jmp short 01BB663C
01BB65F0 8B4D 84 mov ecx, dword ptr [ebp-0x7C]
01BB65F3 51 push ecx
01BB65F4 68 188CB901 push 01B98C18 ; 比较码 9
01BB65F9 FFD7 call edi
01BB65FB 85C0 test eax, eax
01BB65FD 75 0D jnz short 01BB660C
01BB65FF 6A 03 push 0x3
01BB6601 FFD3 call ebx
01BB6603 8BD0 mov edx, eax
01BB6605 8D4D E4 lea ecx, dword ptr [ebp-0x1C]
01BB6608 FFD6 call esi
01BB660A EB 30 jmp short 01BB663C
01BB660C 8B55 84 mov edx, dword ptr [ebp-0x7C]
01BB660F 52 push edx
01BB6610 68 A085B901 push 01B985A0 ; 比较码 0
01BB6615 FFD7 call edi
01BB6617 85C0 test eax, eax
01BB6619 75 13 jnz short 01BB662E ; 如果不为0 则跳转.0的取值最复杂,是根据一系列的运算得出来的,由于本来时间比较紧
01BB661B 8B45 D8 mov eax, dword ptr [ebp-0x28] ; 不作过多尝试,反正也就对应了 10个数字,我本机,优先出来的是 6,所以在写注册机的时候
01BB661E 50 push eax ; 我会根据自身数据的判断,写出0 对应的 数值
01BB661F FF15 1810B901 call dword ptr [0x1B91018] ; msvbvm60.__vbaStrI4
01BB6625 8BD0 mov edx, eax
01BB6627 8D4D E4 lea ecx, dword ptr [ebp-0x1C]
01BB662A FFD6 call esi
01BB662C EB 0E jmp short 01BB663C
01BB662E BA A085B901 mov edx, 01B985A0
01BB6633 8D4D E4 lea ecx, dword ptr [ebp-0x1C]
01BB6636 FF15 1412B901 call dword ptr [0x1B91214] ; msvbvm60.__vbaStrCopy
01BB663C 8B4D DC mov ecx, dword ptr [ebp-0x24]
01BB663F 8B55 E4 mov edx, dword ptr [ebp-0x1C]
01BB6642 51 push ecx
01BB6643 52 push edx
01BB6644 FF15 6810B901 call dword ptr [0x1B91068] ; 数值连接 就是 把 6码都连起来
01BB664A 8BD0 mov edx, eax
01BB664C 8D4D DC lea ecx, dword ptr [ebp-0x24]
01BB664F FFD6 call esi
01BB6651 8B4D E8 mov ecx, dword ptr [ebp-0x18] ; 取出当前位置for语句的循环变量 i
01BB6654 B8 01000000 mov eax, 0x1
01BB6659 03C1 add eax, ecx ; i 加 1
01BB665B 0F80 99000000 jo 01BB66FA
01BB6661 8945 E8 mov dword ptr [ebp-0x18], eax
01BB6664 ^ E9 2BFEFFFF jmp 01BB6494 ; 这里是前面 for 语句的 回跳部分
01BB6669 8D4D 98 lea ecx, dword ptr [ebp-0x68] ; 结束
.
.
.
// 中间一部分代码省略 01BB0333 FF15 E010B901 call dword ptr [0x1B910E0] ; 01BB0339 8D45 98 lea eax, dword ptr [ebp-0x68]
01BB033C 50 push eax
01BB033D FF15 3410B901 call dword ptr [0x1B91034] ; msvbvm60.__vbaStrVarMove
01BB0343 8BD0 mov edx, eax
01BB0345 8D4D D8 lea ecx, dword ptr [ebp-0x28]
01BB0348 FF15 9812B901 call dword ptr [0x1B91298] ; msvbvm60.__vbaStrMove
01BB034E 8D4D B8 lea ecx, dword ptr [ebp-0x48]
01BB0351 FF15 DC12B901 call dword ptr [0x1B912DC] ; msvbvm60.__vbaFreeObj
01BB0357 8D4D 98 lea ecx, dword ptr [ebp-0x68]
01BB035A 51 push ecx
01BB035B 8D55 A8 lea edx, dword ptr [ebp-0x58]
01BB035E 52 push edx
01BB035F 6A 02 push 0x2
01BB0361 FF15 4010B901 call dword ptr [0x1B91040] ; msvbvm60.__vbaFreeVarList
01BB0367 83C4 0C add esp, 0xC
01BB036A C745 FC 0A00000>mov dword ptr [ebp-0x4], 0xA
01BB0371 8B45 DC mov eax, dword ptr [ebp-0x24]
01BB0374 50 push eax ; 根据指纹获取的密码压栈"..."
01BB0375 8B4D D8 mov ecx, dword ptr [ebp-0x28]
01BB0378 51 push ecx ; 客户输入的邀请码"123456"
01BB0379 FF15 2811B901 call dword ptr [0x1B91128] ; 比较注册码
01BB037F 85C0 test eax, eax
01BB0381 0F85 2F020000 jnz 01BB05B6 ; 关键跳
01BB0387 C745 FC 0B00000>mov dword ptr [ebp-0x4], 0xB
01BB038E 8D55 C8 lea edx, dword ptr [ebp-0x38]
01BB0391 52 push edx
01BB0392 8B45 08 mov eax, dword ptr [ebp+0x8]
01BB0395 8B48 38 mov ecx, dword ptr [eax+0x38]
01BB0398 51 push ecx
01BB0399 8B55 CC mov edx, dword ptr [ebp-0x34]
01BB039C 8B02 mov eax, dword ptr [edx]
01BB039E 8B4D CC mov ecx, dword ptr [ebp-0x34]
根据上面的注释,应该还算清楚了,首先,程序会根据获取的硬盘指纹,一位一位获取对应的“密码”并拼起来。比如是1,则返回4; 是4返回7。10个数字,除了0,其它都很简单,但为了节省大家和我的时间我们就不去深入研究了,毕竟0 也就对应了键盘上的10个数字而以。并且本人多次尝试把 本地日期改成不同时间,在断网(懒的开IRIS)的时候看,0对应的数字是否有变化,结果是一直为6,说明0的对应码跟日期无关。
根据上面的提示,我把 对应关系列一下。
1 4 7 2 5 8 3 6 9 0
4 7 1 5 8 2 6 9 3 未知
那好,现在就来写个简单的注册机吧,工具VS 2008 C++ int _tmain(int argc, _TCHAR* argv[])
{
int j=0;
char chr;
printf("\n请输入机器码:\n");
string s1,result;
cin>>s1;
while(s1.length() != 6)
{
cout<<"长度必须为 6"<<endl;
cin>>s1;
};
do{
char c;
for(int i=0;i<6;i++)
{
c = s1[i];
switch(c)
{
case '1':
result += "4";
break;
case '4':
result += "7";
break;
case '7':
result += "1";
break;
case '2':
result += "5";
break;
case '5':
result += "8";
break;
case '8':
result += "2";
break;
case '3':
result += "6";
break;
case '6':
result += "9";
break;
case '9':
result += "3";
break;
case '0':
switch(j)
{
case 0:
result += "6";
break;
case 1:
result += "5";
break;
case 2:
result += "2";
break;
case 3:
result += "1";
break;
case 4:
result += "3";
break;
case 5:
result += "4";
break;
case 6:
result += "7";
break;
case 7:
result += "8";
break;
case 8:
result += "9";
break;
case 9:
result += "0";
break;
}
break;
}
}
cout<<j<<" 激活码为: "<<result<<endl;
result.clear();
cout<<"是否需要继续(y/n)?: ";
j++;
cin>>chr;
}while(chr!='n' && chr!='N' );
return 0;
}
为什么当0 的时候,出现顺序为 6,5,2,0,1...9。 因为我本机0 出现的是6,后面只是个人喜好 好了,现在注册机也就有了,缺点就是运行不好的时候,会要运行上10次。
至于注释不齐,是因为我COPY到 记事本里面写的。我的OD打中文有点问题,所以还请谅解。
[注意]传递专业知识、拓宽行业人脉——看雪讲师团队等你加入!