码迷,mamicode.com
首页 > 其他好文 > 详细

[小技巧]一款KeygenMe的分析与注册机的编写

时间:2018-05-28 13:41:58      阅读:170      评论:0      收藏:0      [点我收藏+]

标签:span   length   字符转换   长度   技术   string   alt   查看   item   

0x01. PEID查看
 
发现是汇编编写,并未加壳
技术分享图片
 
0x02.修复编辑框只能输1个字符的问题
首先找到窗口回调
在WM_INITDIALOG (0x110)分支处可看到如下信息
技术分享图片

 

获取两个编辑框控件ID
技术分享图片

 

前两个call 通过GetDlgItem 分别获取两个编辑框的控件ID
最后一个call通过 SetWindowPos 设置窗口位置
进入中间call查看
技术分享图片
 
发现修改编辑框属性 代码
回到主回调
技术分享图片
将此call nop掉 然后保存到文件
此时运行修改过的文件,即可以正常输入
 
0x03.分析流程
直接来到回调函数WM_COMMAND 0x111 分支
技术分享图片

 

通过测试发现 0x3F0 是 问号小按钮的控件ID
0x3ED 是 Register 按钮的控件ID
技术分享图片

 

下面从Register 分支处开始分析
 获取name编辑框文本长度
技术分享图片

可见 name文本长度 >0x13  或 <=3 均会失败

 

接下来计算name哈希值

技术分享图片

 

通过GetUserNameA 来获取当前系统用户名

技术分享图片

 

并计算SysUserName字符串 哈希值

再接着计算 name 和 SysUserName 的哈希值

技术分享图片

 

通过把这三个哈希值 都转换成ANSI码 字符串 放入同一个缓冲区 得到一串ANSI码字符串

技术分享图片

 

序列号格式化, 并填充指定位置为指定数据

技术分享图片

 

接下来就是一些对比的操作

 

0x04.注册机的编写

 1 //计算字符串哈希值
 2 DWORD C__02_注册机Dlg::CalcHash_str(PBYTE name, DWORD len)
 3 {
 4     DWORD ret = 0;
 5     int temp_len = len;        //长度参数
 6     DWORD dwTemp = 0;
 7     do
 8     {
 9         *(PBYTE)&dwTemp = (BYTE)*name;                
10         dwTemp = (DWORD)(ret * 72 - dwTemp - 111);
11         ret = dwTemp ^ 0xBACAF;
12         ++name;
13         --temp_len;
14     } while (temp_len);
15 
16     return ret;
17 }
18 
19 //计算两个整形的哈希值
20 DWORD C__02_注册机Dlg::CalcHash_dword(DWORD a1, DWORD a2)
21 {
22     return (a2 ^ a1 ^ 0xFFAC) + (a2 ^ 0x553) - 1 + (a2 ^ 0x553) + a1;
23 }
24 
25 //把哈希值转为字符串
26 bool C__02_注册机Dlg::toAnsi(char* Buffer, DWORD hash)
27 {
28     Buffer += 7;
29     for (int i = 0; i < 8; i++)
30     {
31         DWORD a = hash % 0x10 + 0x30;
32         if (a >= 0x3A)
33         {
34             a += 7;
35         }
36         *Buffer = a;
37         Buffer--;
38         hash /= 0x10;
39     }
40     return true;
41 }
42 
43 //填充格式化序列号
44 void C__02_注册机Dlg::FillSer(char* buff)
45 {
46     *(buff + 4) = 0x2D;
47     *(buff + 4 + 10) = 0x2D;
48     *(buff) = 0x4B;
49     *(buff + 1) = 0x4F;
50     *(buff + 2) = 0x53;
51 }
52 
53 
54 //按钮事件
55 void C__02_注册机Dlg::OnBnClickedButton1()
56 {
57     CString str;
58     m_Edit_Name.GetWindowTextW(str);        //获取用户输入name
59     if (str.IsEmpty())
60     {
61         AfxMessageBox(L"请输入name!");
62         return;
63     }
64     if (str.GetLength() <=3 || str.GetLength() > 19)
65     {
66         AfxMessageBox(L"name长度不合法.(合法长度>3 && <=19)");
67         return;
68     }
69     
70     char szName[MAX_PATH] = { 0 };
71     WideCharToMultiByte(CP_ACP, 0, str.GetBuffer(), str.GetLength(), szName, MAX_PATH, 0, 0);    //宽字符转换多字节
72 
73     DWORD haxi_Name = CalcHash_str((PBYTE)szName, strlen(szName));
74 
75     DWORD pcbBuffer = MAX_PATH;
76     char szUserName[MAX_PATH] = { 0 };
77     GetUserNameA(szUserName, &pcbBuffer);            //获取系统用户名
78 
79     DWORD haxi_UserName = CalcHash_str((PBYTE)szUserName, strlen(szName));
80     DWORD haxi_Double = CalcHash_dword(haxi_Name, haxi_UserName);
81 
82     char szBuf[25] = { 0 };
83     toAnsi(&szBuf[0], haxi_UserName);
84     toAnsi(&szBuf[8], haxi_Double);
85     toAnsi(&szBuf[16], haxi_Name);                  //哈希值转换字符串
86     FillSer(szBuf);                                  //格式化填充序列号
87 
88     str = szBuf;
89     m_Edit_Serial.SetWindowTextW(str);             //计算完毕
90 }

 

 测试成功!

 技术分享图片

[小技巧]一款KeygenMe的分析与注册机的编写

标签:span   length   字符转换   长度   技术   string   alt   查看   item   

原文地址:https://www.cnblogs.com/wensday/p/9099557.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!