来自Keymaker中的cm例子
最近是技术退步了还是技术退步了,竟分析了一天毫无头绪{:1_906:}好在是ASM编写的,正在努力暴力分析
拿上来网友试试 本帖最后由 JuncoJet 于 2024-6-13 09:20 编辑
研究出来了
因为是ASM写的CM所以代码全是汇编指令
没有什么特征,而且指令用的比较冷门
比如求字符串长度,还有比较字符串的代码 暴力破解:
`401A46` 是主要窗口事件处理函数,其中:
处理 `WM_INITDIALOG` 时,为机器码控件注册了个自己的事件处理函数:
```c
gControlHwnd = GetDlgItem(hWnd, 101); // gControlHwnd = 机器码控件句柄
unknown = j_SetWindowLongA(gControlHwnd, GWL_WNDPROC, (LONG)sub_401EBA);
j_SetWindowLongA(gControlHwnd, GWL_USERDATA, unknown);
```
当处理的窗口事件为 `WM_COMMAND` (按下按钮)时,利用 `PostMessageA` 通知机器码控件的事件处理函数进行序列号验证处理:
```c
if ( lParam )
{
if ( lParam >= 0xB )
PostMessageA(gControlHwnd, 1123u, 1u, lParam); // 第一次进入
else
MessageBoxA(hWnd, "错误的注册码!请确认你输入的大小写是否正确。", 0, 0x10u);
}
else
{
MessageBoxA(hWnd, "注册成功!谢谢你的注册。", "完成", 0);
}
```
(`lParam` 存储按钮控件句柄,永不为 `0`)
继续到 `401EBA` 分析 `1123` 号事件即可:
```c
SendMessageA(gCodeFieldHandle, WM_GETTEXT, 100u, (LPARAM)code);
SendMessageA(hWnd_machine_code, WM_GETTEXT, 260u, (LPARAM)machine_code);
b64_decode(code, decoded);
len = strlen(machine_code) + 1;
v7 = machine_code;
v8 = decoded;
do
{
if ( !len )
break;
v9 = *v7++ == *(_BYTE *)v8;
v8 = (int *)((char *)v8 + 1);
--len;
}
while ( v9 );
PostMessageA(gMainWndHandle, WM_COMMAND, 1u, len);
```
`004023B8` 看起来就是个标准的 `base64` 解密过程,然后将机器码与序列号解码后的内容进行比对。
相同则 `len = 0`,否则 `len = 其他值`。
---
Python 做的注册机:
```py
import base64
def keygen(machine_code: str) -> str:
return base64.b64encode(machine_code.encode()).decode().rstrip('=')
# machine_code: 123456789
# serial : MTIzNDU2Nzg5
```
页:
[1]