【crackmes.one】———— keygenme90

Language: c/c++ | Arch: x86 | Platform: Windows |Tech: keygenme,base64,xor
在WinMain函数中找到这一行

 WndClass.lpfnWndProc = sub_401046;

这个函数是回调函数,用于处理窗口消息,
进入该子函数,找到CreateWindowExA函数,把他们的返回值重命名,以增加可读性,像下面这样:

name_hWnd = CreateWindowExA(
                  dwExStyle: 0,
                  lpClassName: "EDIT",
                  lpWindowName: byte_4250C8,
                  dwStyle: 0x50800080u,
                  X: 110,
                  Y: 20,
                  nWidth: 180,
                  nHeight: 20,
                  hWndParent,
                  hMenu: (HMENU)1,
                  hInstance: nullptr,
                  lpParam: nullptr);
pwd_hWnd =  CreateWindowExA(
                 dwExStyle: 0,
                 lpClassName: "EDIT",
                 lpWindowName: byte_4250C8,
                 dwStyle: 0x50800080u,
                 X: 110,
                 Y: 60,
                 nWidth: 180,
                 nHeight: 20,
                 hWndParent,
                 hMenu: (HMENU)2,
                 hInstance: nullptr,
                 lpParam: nullptr);

后面GetWindowTextA用于获取输入的name和password

GetWindowTextA(hWnd: name_hWnd, lpString: Name, nMaxCount: 256);
GetWindowTextA(hWnd: pwd_hWnd, lpString: password, nMaxCount: 256);

对应的参数也进行重命名
下面两个是string对象的构造函数,从这里开始切到反汇编视图会比较方便

sub_4010E1(a1: Name, a2: v6);
sub_4010E1(a1: password, a2: v5);

紧接着代码对name进行了处理,然后把处理的结果与password做比较,这里把sub_4010A0的另一个参数注释为obj_expected

;   try {
mov     byte ptr [ebp+var_4], 1
lea     eax, [ebp+obj_Name]
push    eax
lea     ecx, [ebp+obj_expected]
push    ecx
call    sub_4010A0
add     esp, 8
;   } // starts at 401966
;   try {
mov     byte ptr [ebp+var_4], 2
lea     edx, [ebp+obj_expected]
push    edx
lea     eax, [ebp+obj_password]
push    eax
call    sub_40108C

具体如何处理,进入sub_4010A0一探究竟
sub_4010A0

其中edx是下标,sub_401078用于获取Name[i],然后把字符与0x5A异或。
循环完成后,sub_40109B对字符串进行进一步处理
从其中部分代码,如

v14 = (v18 & 0xFC) >> 2;
      v15 = ((v19 & 0xF0) >> 4) + 16 * (v18 & 3);
      v16 = ((v20 & 0xC0) >> 6) + 4 * (v19 & 0xF);
      v17 = v20 & 0x3F;

可以看出有许多移位指令和掩码,这是典型的base64加密算法
因此可以知道,程序对输入的字符串进行了按位xor和base64编码
解密脚本如下

import base64

xor_key = 0x5A


def keygen(Name):
    xored = bytes(ord(c) ^ xor_key for c in Name)
    return base64.b64encode(xored).decode("ascii")


if __name__ == "__main__":
    name = str(input("Please input name: "))
    password = keygen(name)
    print(f"Your password is: {password}")
posted on 2026-11-07 22:35  %HuTao%  阅读(2)  评论(0)    收藏  举报