首页
社区
课程
招聘
[原创]crackme的注册码分析(第一次做keygen)
2010-9-5 08:34 6858

[原创]crackme的注册码分析(第一次做keygen)

2010-9-5 08:34
6858
【软件名称】SplishSplash
【使用工具】ollydbg
【作者】IT小小鸟
【声明】我是初学者,报着请教的心愿,希望各位前辈不吝赐教!!!

1.下断点bp GetDlgItemTextA,输入name为starstarstarstar,serial为7474747474747474,断在以下,name和serial都必须为16个字符

0040143D    6A 1F           PUSH 1F
0040143F    68 A6304000     PUSH SplishSp.004030A6
00401444    68 EB030000     PUSH 3EB
00401449    FF75 08         PUSH DWORD PTR SS:[EBP+8]
0040144C    E8 DB010000     CALL <JMP.&user32.GetDlgItemTextA>
00401451    83F8 00         CMP EAX,0
00401454    74 47           JE SHORT SplishSp.0040149D
00401456    8D05 3A304000   LEA EAX,DWORD PTR DS:[40303A]
0040145C    8D1D A6304000   LEA EBX,DWORD PTR DS:[4030A6]
00401462    8038 00         CMP BYTE PTR DS:[EAX],0
00401465    74 0C           JE SHORT SplishSp.00401473
00401467    8A08            MOV CL,BYTE PTR DS:[EAX]
00401469    8A13            MOV DL,BYTE PTR DS:[EBX]
0040146B    38D1            CMP CL,DL
0040146D    75 1A           JNZ SHORT SplishSp.00401489
0040146F    40              INC EAX
00401470    43              INC EBX
00401471  ^ EB EF           JMP SHORT SplishSp.00401462
00401473    6A 00           PUSH 0
00401475    68 56304000     PUSH SplishSp.00403056                   ; hardcoded
0040147A    68 60304000     PUSH SplishSp.00403060                   ; yes, you find the hardcoded serial!
0040147F    FF75 08         PUSH DWORD PTR SS:[EBP+8]
00401482    E8 D5010000     CALL <JMP.&user32.MessageBoxA>
00401487    EB 14           JMP SHORT SplishSp.0040149D
00401489    6A 00           PUSH 0
0040148B    68 56304000     PUSH SplishSp.00403056                   ; hardcoded
00401490    68 84304000     PUSH SplishSp.00403084                   ; this is not the hardcoded serial!
00401495    FF75 08         PUSH DWORD PTR SS:[EBP+8]
00401498    E8 BF010000     CALL <JMP.&user32.MessageBoxA>
0040149D    E9 E7000000     JMP SplishSp.00401589
004014A2    817D 10 EF03000>CMP DWORD PTR SS:[EBP+10],3EF
004014A9    0F85 DA000000   JNZ SplishSp.00401589
004014AF    6A 1F           PUSH 1F
004014B1    68 0F314000     PUSH SplishSp.0040310F                   ; ASCII "2012302020123012"
004014B6    68 ED030000     PUSH 3ED
004014BB    FF75 08         PUSH DWORD PTR SS:[EBP+8]
004014BE    E8 69010000     CALL <JMP.&user32.GetDlgItemTextA>
004014C3    A3 5C314000     MOV DWORD PTR DS:[40315C],EAX //取得name的长度
004014C8    6A 1F           PUSH 1F
004014CA    68 2F314000     PUSH SplishSp.0040312F                   ; ASCII "7474747474747474"
004014CF    68 EE030000     PUSH 3EE
004014D4    FF75 08         PUSH DWORD PTR SS:[EBP+8]
004014D7    E8 50010000     CALL <JMP.&user32.GetDlgItemTextA>
004014DC    A3 60314000     MOV DWORD PTR DS:[403160],EAX //取得serial的长度
004014E1    3B05 5C314000   CMP EAX,DWORD PTR DS:[40315C] //比较name和serial的长度
004014E7    0F85 80000000   JNZ SplishSp.0040156D //不等则死
004014ED    833D 60314000 0>CMP DWORD PTR DS:[403160],0 //serial是否为空
004014F4    74 77           JE SHORT SplishSp.0040156D //跳则死
----------------------------------------------------------------------------------------------------
2.下面是关键算法处
004014F6    60              PUSHAD
004014F7    33C0            XOR EAX,EAX
004014F9    8D35 0F314000   LEA ESI,DWORD PTR DS:[40310F] //取name的地址
004014FF    8B0D 5C314000   MOV ECX,DWORD PTR DS:[40315C] //取name的长度
00401505    33DB            XOR EBX,EBX
00401507    8A4431 FF       MOV AL,BYTE PTR DS:[ECX+ESI-1] //逆序取name的每一位
0040150B    43              INC EBX //EBX自加
0040150C    33C3            XOR EAX,EBX //取出的name每位与EBX异或,code^=b
0040150E    3C 44           CMP AL,44 //与44比较
00401510  ^ 72 F9           JB SHORT SplishSp.0040150B //小于,继续循环
00401512    3C 4D           CMP AL,4D //与4D比较
00401514  ^ 77 F5           JA SHORT SplishSp.0040150B //大于,继续循环
00401516    884431 FF       MOV BYTE PTR DS:[ECX+ESI-1],AL
0040151A    806C31 FF 14    SUB BYTE PTR DS:[ECX+ESI-1],14   //code-=0x14
0040151F    49              DEC ECX
00401520    83F9 00         CMP ECX,0
00401523  ^ 77 E2           JA SHORT SplishSp.00401507
00401525    61              POPAD
00401526    8D05 0F314000   LEA EAX,DWORD PTR DS:[40310F]
0040152C    8D1D 2F314000   LEA EBX,DWORD PTR DS:[40312F]
00401532    8038 00         CMP BYTE PTR DS:[EAX],0 //serial每一位ASCII码与0比较
00401535    74 0C           JE SHORT SplishSp.00401543 //相等则注册成功
00401537    8A08            MOV CL,BYTE PTR DS:[EAX] // 假serial与算出的serial每位比较
00401539    8A13            MOV DL,BYTE PTR DS:[EBX]
0040153B    38D1            CMP CL,DL
0040153D    75 1A           JNZ SHORT SplishSp.00401559 //不等则死
0040153F    40              INC EAX
00401540    43              INC EBX
00401541  ^ EB EF           JMP SHORT SplishSp.00401532
00401543    6A 00           PUSH 0
00401545    68 56304000     PUSH SplishSp.00403056                   ; hardcoded
0040154A    68 D2304000     PUSH SplishSp.004030D2                   ; yes, you got a correct combination
0040154F    FF75 08         PUSH DWORD PTR SS:[EBP+8]
00401552    E8 05010000     CALL <JMP.&user32.MessageBoxA>
00401557    EB 14           JMP SHORT SplishSp.0040156D
00401559    6A 00           PUSH 0
0040155B    68 56304000     PUSH SplishSp.00403056                   ; hardcoded
00401560    68 F5304000     PUSH SplishSp.004030F5                   ; this combination is shit!
00401565    FF75 08         PUSH DWORD PTR SS:[EBP+8]
00401568    E8 EF000000     CALL <JMP.&user32.MessageBoxA>

3.总结
1.name和serial的长度必须都为16个字符
2.F(name)=serial,逆序处理name的每位,与变量ebx异或

此crackme还有两个任务,去掉NAG窗口,找出hardcode,都比较简单。就不赘述了。
【注册机】
因为要求不能用控制台,用的vc,关键代码如下
void CKeygenDlg::OnSerial() 
{
  // TODO: Add your control notification handler code here
  char username[16],serial[16],code=0,b=0;
    int num;
  num=::GetDlgItemText(m_hWnd,IDC_USERNAME,username,31);
  if(num==16)
  {
      // 逆序取name的每一位
      for(int i=16;i>0;i--)
      {
      code=username[i-1];
      do 
      {
        b++;
        code=code^b;
      } while (code<0x44 || code>0x4d);
      code-=0x14;
      serial[i-1]=code;
      }
      serial[16]='\0';
      CString str;
      str.Format("%s",serial);
        AfxMessageBox("注册码为:\n"+str);

    }
  
  else
  {
    AfxMessageBox("name长度为16个字符!");
  }
  
}

此Crackme算法简单,适合新手练兵(比如我),贴上全文,高手莫笑!

[培训]《安卓高级研修班(网课)》月薪三万计划,掌握调试、分析还原ollvm、vmp的方法,定制art虚拟机自动化脱壳的方法

收藏
点赞6
打赏
分享
最新回复 (6)
雪    币: 312
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
felsenlee 2010-9-8 23:23
2
0
文章对我比较合适
雪    币: 97
活跃值: (70)
能力值: ( LV4,RANK:40 )
在线值:
发帖
回帖
粉丝
IT小小鸟 2010-9-9 13:47
3
0
很简单的,就是希望对跟我一样的新手有帮助!
雪    币: 1844
活跃值: (35)
能力值: ( LV3,RANK:30 )
在线值:
发帖
回帖
粉丝
yingyue 2010-9-9 14:00
4
0
精神上支持一下
雪    币: 1163
活跃值: (137)
能力值: ( LV12,RANK:230 )
在线值:
发帖
回帖
粉丝
pencil 5 2010-9-9 14:27
5
0
JNZ SplishSp.0040156D //不等则死

哈哈,你这注释~够劲~
雪    币: 97
活跃值: (70)
能力值: ( LV4,RANK:40 )
在线值:
发帖
回帖
粉丝
IT小小鸟 2010-9-9 16:39
6
0
P哥见笑了,请多多指教我等菜鸟!
雪    币: 97
活跃值: (70)
能力值: ( LV4,RANK:40 )
在线值:
发帖
回帖
粉丝
IT小小鸟 2010-9-9 16:41
7
0
谢谢支持,这两天在接触一些流行的算法,到时再发一篇分析!
游客
登录 | 注册 方可回帖
返回