首页 > 学院 > 开发设计 > 正文

cm练习-2017-0217

2019-11-08 03:05:05
字体:
来源:转载
供稿:网友

前言

今天做了一个cm, 用了好长时间, 扒出算法后, 尝试穷举注册码, 居然没有找到. 后来发现, 还是注册算法细节上扒错了, 要循环移位时, 不能用算术移位. 如果不好表达,可以用内联汇编或做汇编函数和C联合编译. 如果不知道注册码位数和格式, 用穷举不行啊. 超过1分钟出不来, 心里慌:)

UI

这里写图片描述

注册机

// KeyGen.cpp : for cm19//#include "stdafx.h"#include <windows.h>#include <stdlib.h>#include <crtdbg.h>DWord g_dw403168_HdInfo = 0; // 注册码比对值2DWORD g_dw40316D_UserInputInfo = 0; // 注册码比对值1DWORD g_dw403172 = 0; // 中间值, cm里会用到DWORD g_dw403177 = 0; // 中间值, cm里会用到DWORD GetHdInfo();DWORD CalcSn(/*OUT*/char* PRegSn, int iLen);BOOL TryToFindRegSn(DWORD* pdwUserInput, DWORD dwHdInfo);int main(int argc, char* argv[]){ char szSn[0x100] = {'/0'}; DWORD dwRc = 0; DWORD dwUserInput = 0; // 从代码逻辑看, 用户输入的注册码都是数字 printf("g_dw403168_HdInfo = 0x%8.8X/r/n", GetHdInfo()); // 先按照8位的注册码试试, 能否找到和硬件信息匹配的注册码 // "99999999" 计算出的数, 也比硬件信息的值小, 可以不用穷举的 // 用反推, 硬件信息的值 ror 2, 列出10进制值就是用户要输入的注册码 // 最后的注册码是"1268698068", 在不知道注册码长度的情况下, 穷举不好玩啊. if (TryToFindRegSn(&dwUserInput, g_dw403168_HdInfo)) { printf("find RegSn = %u = 0x%X/r/n", dwUserInput, dwUserInput); } sprintf(szSn, "%u", dwUserInput); dwRc = CalcSn(szSn, strlen(szSn)); printf("pwd = %s , verify code = 0x%X/r/n", szSn, dwRc); if (dwRc == g_dw403168_HdInfo) { printf("find reg sn : %s/r/n", szSn); } system("pause"); return 0;}DWORD GetHdInfo(){ BOOL bRc = FALSE; DWORD dwVolumeSerialNumber = 0; DWORD dwParam1 = 0; DWORD dwParam2 = 0; DWORD dwBuildIn = 0; char szVolumeName[0x21] = {'/0'}; char szFileSystemName[0x21] = {'/0'}; // 这里简单的拿文件系统名称("NTFS")和卷号(0x66a668f9), 做硬件绑定码 // 虽然简单, 也可以叫做和硬件识别码进行绑定 :) bRc = GetVolumeInformation( NULL, // IN LPCWSTR lpRootPathName, szVolumeName, // OUT LPWSTR lpVolumeNameBuffer, sizeof(szVolumeName) - 1, // IN DWORD nVolumeNameSize, &dwVolumeSerialNumber, // OUT LPDWORD lpVolumeSerialNumber, NULL, // OUT LPDWORD lpMaximumComponentLength, NULL, // OUT LPDWORD lpFileSystemFlags, szFileSystemName, // OUT LPWSTR lpFileSystemNameBuffer, sizeof(szFileSystemName) - 1 // IN DWORD nFileSystemNameSize ); _ASSERT(bRc); /** + szFileSystemName 0x0018fd8c "NTFS" + szVolumeName 0x0018fdb0 "dat" dwVolumeSerialNumber 0x66a668f9 */ printf("szVolumeName = %s/r/n", szVolumeName); printf("dwVolumeSerialNumber = 0x%X/r/n", dwVolumeSerialNumber); printf("szFileSystemName = %s/r/n", szFileSystemName); dwParam1 = dwVolumeSerialNumber; dwParam2 = *(DWORD*)szFileSystemName; dwParam1 += dwParam2; g_dw403168_HdInfo = (dwParam1 >> 2); __asm { // DWORD值字节逆序 push eax mov eax, g_dw403168_HdInfo bswap eax mov g_dw403177, eax pop eax } dwBuildIn = dwParam1; dwBuildIn -= 0x44464347; dwBuildIn <<= 2; __asm { // DWORD值字节逆序 push eax mov eax, dwBuildIn bswap eax mov dwBuildIn, eax pop eax } dwBuildIn ^= 0x7479; dwBuildIn += 0x313233; printf("dwBuildIn = 0x%X/r/n", dwBuildIn); return g_dw403168_HdInfo;}BOOL TryToFindRegSn(DWORD* pdwUserInput, DWORD dwHdInfo){ int i = 0; DWORD dwCurCharValue = 0; DWORD dwRc = 0; if (NULL != pdwUserInput) { __asm { push eax mov eax, dwHdInfo ror eax, 2 mov dwRc, eax pop eax } *pdwUserInput = dwRc; return TRUE; } return FALSE;}DWORD CalcSn(/*OUT*/char* pRegSn, int iLen){ int i = 0; DWORD dwRc = 0; DWORD dwCurCharValue = 0; if (NULL != pRegSn) { for (i = 0; i < iLen; i++) { dwCurCharValue = (DWORD)pRegSn[i]; dwCurCharValue -= 0x30/*'0'*/; dwRc = dwCurCharValue + dwRc * 10; } // dwRc ^= 0; // 这里有个不可达分支, 初始值为0 // 这里是循环左移2位!, 数据不会丢 __asm { push eax mov eax, dwRc rol eax, 2 mov dwRc, eax pop eax } g_dw40316D_UserInputInfo = dwRc; dwRc += 0x7479; dwRc ^= 0x313233; dwRc <<= 6; g_dw403172 = dwRc; } // g_dw40316D 和 g_dw403168 必须相等, 这是注册成功的第一个条件 // 这里成立后, 就没再往下看了, 先试了一下, 这个条件成立时,就已经注册成功了 return g_dw40316D_UserInputInfo;}
发表评论 共有条评论
用户名: 密码:
验证码: 匿名发表