首页 > 技术文章 > 一个有趣的crack注册机

distanceblog 2016-03-29 21:00 原文

多个checkbox,选中一部分当作密码。直接上注册机原码然后简单说下道理。

  1 // ChechkBoxReverse.cpp : Defines the entry point for the console application.
  2 //
  3 
  4 #include "stdafx.h"
  5 #include "windows.h"
  6 
  7 DWORD getGroupSize(int All, int SelectItem);//组合数个数
  8 void addToArry(char *p, char *Positions, char count);
  9 void GetGroupMain(char *Group, char *Ppositions, int GroupMaxItem, int SelectItems, int CurrentPosition, int CurrentIdex);//组合集合数组,集合最大值,排列个数,集合默认从0开始
 10 char checkID[] = { 0x16, 0x49, 0x5e, 0x15, 0x27, 0x26, 0x21, 0x25, 0x1d, 0x59, 0x53, 0x37, 0x31, 0x48, 0x5d, 0x0c, 0x61, 0x52, 0x4d };
 11 bool isFirst = true;
 12 int _tmain(int argc, _TCHAR* argv[])
 13 {
 14     DWORD CheckSum[20] = {0};
 15     int length = strlen(checkID);
 16     for (int i = 0; i < length-1; i++)
 17     {
 18         CheckSum[i] = (DWORD)(checkID[i])*(i + 1)*checkID[i + 1];
 19     }
 20     DWORD ResualtSum = 0xf35466 / 0x4d;
 21     for (int i = 1; i <= 17; i++)
 22     {
 23         DWORD GroupCount = getGroupSize(17, i);
 24         char *Group = (char *)malloc(i*GroupCount);
 25         GetGroupMain(Group, NULL, 16, i, -1, 0);
 26 
 27         /*
 28         for (int j = 0; j < GroupCount; j++)
 29         {
 30             for (int k = 0; k < i; k++)
 31             {
 32                 printf_s("%d  ", *(char *)(j*i + k + Group));
 33             }
 34         }
 35         printf_s("\n");
 36         int a = 1;
 37         */
 38         
 39         for (int j = 0; j < GroupCount; j++)
 40         {
 41             DWORD tempSum = 0;
 42             for (int k = 0; k < i; k++)
 43             {
 44                 tempSum = tempSum + CheckSum[*(char *)(j*i + k +Group)];
 45             }
 46             if (tempSum == ResualtSum)
 47             {
 48                 int counts = 0;
 49                 for (int l = 0; l < i; l++)
 50                 {
 51                     printf_s("%d\n", *(char *)(j*i + l + Group));
 52                 }
 53                 printf_s("count=%d,index is\n", i);
 54                 system("pause");
 55                 return 0;
 56             }
 57         }
 58         
 59         isFirst = true;
 60         free(Group);
 61     }
 62     system("pause");
 63     return 0;
 64 }
 65 void GetGroupMain(char *Group,char *Ppositions ,int GroupMaxItem, int SelectItems,int CurrentPosition,int CurrentIdex)//组合集合数组,集合最大值,排列个数,集合默认从0开始
 66 {
 67     
 68     for (int i = CurrentPosition + 1; i <= GroupMaxItem-SelectItems+1+CurrentIdex; i++)
 69     {
 70         if (CurrentIdex == SelectItems - 1)
 71         {
 72             if (CurrentIdex == 0)
 73             {
 74                 char a = i;
 75                 addToArry(Group, &a, SelectItems);
 76             }
 77             else
 78             {
 79                 *(Ppositions + CurrentIdex) = i;
 80                 addToArry(Group, Ppositions, SelectItems);
 81             }
 82         }
 83         else
 84         {
 85             char* PointPositions = (char*)malloc(CurrentIdex + 2);
 86             if (CurrentIdex!=0)
 87             memcpy(PointPositions, Ppositions, CurrentIdex);
 88             *(PointPositions + CurrentIdex) = i;
 89             GetGroupMain(Group, PointPositions, GroupMaxItem, SelectItems, i, CurrentIdex + 1);
 90         }
 91     }
 92     free(Ppositions);
 93     return;
 94 }
 95 
 96 char* CurrentOffset=0;
 97 void addToArry(char *p, char *Positions,char count)
 98 {
 99     if (isFirst)
100     CurrentOffset = p;
101     isFirst = false;
102     for (int i = 0; i < count; i++)
103     {
104         char a = *(Positions + i);
105         *(CurrentOffset++) = a;
106     }
107 }
108 DWORD getGroupSize(int All, int SelectItem)//组合数个数
109 {
110     UINT64 sum = 1;
111     for (int i = All; i> All - SelectItem; i--)
112     {
113         sum = sum *i;
114     }
115     for (int i = SelectItem; i >= 1; i--)
116     {
117         sum = sum /i;
118     }
119     return sum;
120 }

每个checkbox都有一个ID对应,然后索引从0开始遍历,遇到选中的box择将他的ID乘下个box再乘下个的索引,一直到最后连加起来再将最后的和做一个简单运算,再与一个固定值比较,正确则完成。

那么通过逆向简单运算得到最后的和。再假设所有box被选中算出值,这个问题就变成了先这么多值中选出一些相加,看最后和是否等于一个值。

于是这个算法的主要部分在于怎么选出这几个值。于是我在GetGroupMain这个函数中列出了不同个数的所有可能索引取值,最后去试。主要思路就是这样。用了一个递归算法选和组合数公式。在free运用上要比较注意,指针在不停的传递,肯定有更好的办法,但是不细想了。

推荐阅读