首页
社区
课程
招聘
原创]参赛 :)
发表于: 2007-8-25 01:25 5384

原创]参赛 :)

2007-8-25 01:25
5384
VC6 Project 源码 和 keygen.exe 在附件 keygen.rar 里.

// 主要程序: genkey.cpp

#include "stdafx.h"
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include "genkey.h"

typedef int int32_t;
typedef unsigned int uint32_t;
typedef unsigned char uint8_t;

#define MAX_TIMES  4096

static char m_codes[ MAX_TIMES ];
static int m_count = 0;

/**
 * 根据注册名计算出一个整数
 */
static uint32_t sum_name(const char *name)
{
  const char *p;
  int32_t sum = 0x13572468;

  for (p = name; *p; p++)
  {
    sum += (*p);

    sum *= 0x3721273;
    sum += 0x24681357;

    sum = (sum >> 7) | ( ((uint32_t)sum) << 0x19);
  }

  return sum;
}

/**
 * 将 bits数组的第 pos 位取反,也就是 bits[pos] ^= 1.
 *
 * 为将 pos 位取反,必须先:
 * 1. bits[pos - 1] = 1
 * 2. bits[1] 到 bits[pos - 2] 都为 0
 * 这个函数通过递归调用来满足这两个条件.
 *
 * @note 未做递归深度检查. CrackMe2 中序列号最长 4096 (就是前面定义的 MAX_TIMES),这里假设不会超过这个值.
 */
static void xor(uint8_t bits[10],int pos)
{
  int i;

  /// 递归结束条件
  if (pos == 1)
  {
    bits[1] ^= 1;
    m_codes[m_count++] = 1;
    return;
  }

  /// 先递归调用来满足条件 1
  if ( bits[pos - 1] == 0 )
  {
    xor(bits,pos - 1);
  }

  /// 再递归调用来满足条件2
  for (i = pos - 2; i; i--)
  {
    if ( bits[i] != 0 )
    {
      xor(bits,i);
    }
  }
  
  /// 2 个条件满足了,现在可以将第 pos 位取反了
  bits[pos] ^= 1;

  /// 记录第几步改变了第几位,后面根据这个生成序列号
  m_codes[m_count++] = pos;
}

/**
 * 对话框窗口函数调用这个得到序列号
 */
char *genkey(const char *name)
{
  int i,v;
  uint8_t bits[10],tbl[32];
  uint32_t sum;

  m_count = 0;
  memset(bits,0,sizeof(bits));
  memset(m_codes,0,sizeof(m_codes));

  /// 根据 name 计算出一个整数 
  sum = sum_name(name);

  /// 生成 8 个元素的 bit 数组
  for (i = 1; i < 9; i++)
  {
    bits[i] = ( (sum >> i) & 1 );
  }

  bits[9] = 1;

  /// 预先计算出一个转换表
  for (i = 0; i < 0x1F; i++)
  {
    tbl[i] = (sum >> (i % 0x1F)) % 10;
  }

  /**
   * 算法思路是: 依次使 9,8,7,...,1 位变成 0. 因为,假如使第 9 位变成 0 了,
   * 那么再把第 8 位变成 0 时就不需要考虑第 9 位了. 同样,第 8 位变成 0 后,
   * 再改变第 7 位时就不需要考虑 8,9 位. 问题难度将逐步降低,直到最终解决,
   * 而且,这个思路可以递归实现.
   */
  for (i = 9; i; i--)
  {
    if ( bits[i] != 0 )
    {
      xor(bits,i);
    }
  }

  /// 根据每一步改变了第几位,和前面计算出的转换表 (tbl) 计算出序列号
  for (i = 0; i < m_count; i++)
  {
    v = m_codes[i] - tbl[ i % 0x1F ];

    m_codes[i] = '0' + (v >=0 ? v : v + 10);
  }
  m_codes[m_count] = '\0';

  return m_codes;
}

[招生]科锐逆向工程师培训(2024年11月15日实地,远程教学同时开班, 第51期)

上传的附件:
收藏
免费 0
支持
分享
最新回复 (0)
游客
登录 | 注册 方可回帖
返回
//