1 实现打开软件熟悉下
先分析第一个 注册码和名称
发现不正确会提示
2 x96Dbg附加 将MessageBox -A -W -ExA -ExW 全都下断点 注意下到返回的地方
在MessageBoxA 断下了 然后我们F7
我们到了这个地方
先观察下 发现并没有检测
3 然后 ctrl+F9 跳到上一级
明显是判断的 #1 简单方法直接nop
`0042FAFE | E8 F93EFDFF | call acid burn.4039FC` |
2 分析下名称和注册码
edx 是我写的 猜测eax=CW-4018-CRACKED 是注册码 在之前改调edx的内容改为 eax 发现也成功的 然后我们改变名称 发现 注册码不一样了
4 在这一级观察发现 注册码是在上面得出 在这一级的头部下断点
F8往下跟 看传参和返回
这里出现的4018注册码 进来函数发现是得到eax的
确定eax=431750然后高亮[431750]
重新来一遍 在42F9B5下断点 在内存查看431750 记得刷新 可以使用CE 和内存断点’ 这边使用的是内存断点 #define [431750] 值
值=41
这里开始 movzx一般用于将较小值拷贝到较大值中 eax=0x31 ==‘1’ imul 有符号乘法,将被乘数与乘数均作为有符号数
值=值*第一个字符 =2009 本例中 第一个字符是'1'=0x31=49
mov eax, 50dword ptr ds:[0x00431750]
add dword ptr ds:[0x00431750], eax
这二句应该都看得懂 就是 值=值+值 就是值*2
完整得出答案
检验
第一个字符是’2’==50 (41*50)*2=4100
成功
算法 注册码=CW-(string_name[0]*41)*2-CRACKED
5 我们最后做个一键填写名称和注册码的注册机
下面源码
#include <Windows.h>
#include <iostream>
#include <atlstr.h>
using namespace std;
int main()
{
srand(time(NULL));
HWND Handle = FindWindowW(L"TNS", L"Name Serial");
HWND HandleRegistration = FindWindowExW(Handle, NULL, L"TEdit", NULL);
HWND HandleName = FindWindowExW(Handle, HandleRegistration, L"TEdit", NULL);
HWND HandleCliek = FindWindowExW(Handle, NULL, L"TBitBtn",L"&Check it Baby !");
CString str = L"天晨";
int Name = rand();
CString str2;
str2.Format(L"%d", Name);
CString str3;
str3.Format(L"CW-%d-CRACKED", (str2[0] * 41) * 2);
SendMessageW(Handle, WM_SETTEXT, 0, (LPARAM)str.GetBuffer());
SendMessageW(HandleName, WM_SETTEXT, 0, (LPARAM)str2.GetBuffer());
SendMessageW(HandleRegistration, WM_SETTEXT, 0, (LPARAM)str3.GetBuffer());
SendMessageW(HandleCliek, WM_LBUTTONDOWN, 0, NULL);
Sleep(10);
SendMessageW(HandleCliek, WM_LBUTTONUP, 0, NULL);
int erro=GetLastError();
system("pause");
}
运行即
7 第二个简单提下 仿造上面即可 serial=Hello Dude!
|