吾爱破解 - 52pojie.cn

 找回密码
 注册[Register]

QQ登录

只需一步,快速开始

查看: 76|回复: 1
上一主题 下一主题
收起左侧

[CrackMe] c++写的Crackme

[复制链接]
跳转到指定楼层
楼主
UnionKG 发表于 2026-9-16 19:21 回帖奖励
CM是什么?Crackme是什么?这是什么东西?楼主发的什么?
他们都是一些公开给别人尝试破解的小程序,制作 Crackme 的人可能是程序员,想测试一下自己的软件保护技术,也可能是一位 Cracker,想挑战一下其它 Cracker 的破解实力,也可能是一些正在学习破解的人,自己编一些小程序给自己破解,KeyGenMe是要求别人做出它的 keygen (序号产生器), ReverseMe 要求别人把它的算法做出逆向分析, UnpackMe 是要求别人把它成功脱壳,本版块禁止回复非技术无关水贴。

使用c++写的,之前也阅读过站上的一些crackme文章,程序加做了控制流混淆和字符串的加密,没有套壳

这个是一个成功示例
机器码:MC1-E739A245499F0EDC0569E95E479795F51C39BCD6AFEE7C659096967AD262467F
Key:VC1-47BF32FF553C12AF6323AC701DB981FF4F68516682DE18B3EA888C80465691F565DD2BA16D4F208FD747B86465122FDA3629B8410670252DBF84565B0D6A247D
机器码根据不同机器生成

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有帐号?注册[Register]

x

发帖前要善用论坛搜索功能,那里可能会有你要找的答案或者已经有人发布过相同内容了,请勿重复发帖。

沙发
qq465881818 发表于 2026-9-18 20:49
本帖最后由 qq465881818 于 2026-9-18 20:51 编辑

我换个公钥 还不行吗?哈哈哈哈哈哈
[Python] 纯文本查看 复制代码
# -*- coding: utf-8 -*-

import hashlib
import struct
import os
import random
import ctypes
import subprocess
import sys
import tkinter as tk
from tkinter import ttk, messagebox, filedialog


P  = 0xffffffff00000001000000000000000000000000ffffffffffffffffffffffff
A  = P - 3
B  = 0x5ac635d8aa3a93e7b3ebbd55769886bc651d06b0cc53b0f63bce3c3e27d2604b
GX = 0x6b17d1f2e12c4247f8bce6e563a440f277037d812deb33a0f4a13945d898c296
GY = 0x4fe342e2fe1a7f9b8ee7eb4a7c0f9e162bce33576b315ececbb6406837bf51f5
N  = 0xffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc632551

def inv(x, m=P):
    return pow(x, -1, m)

def ec_add(p1, p2):
    if p1 is None:
        return p2
    if p2 is None:
        return p1
    x1, y1 = p1
    x2, y2 = p2
    if x1 == x2 and (y1 + y2) % P == 0:
        return None
    if p1 == p2:
        l = (3 * x1 * x1 + A) * inv(2 * y1) % P
    else:
        l = (y2 - y1) * inv(x2 - x1) % P
    x3 = (l * l - x1 - x2) % P
    return (x3, (l * (x1 - x3) - y1) % P)

def ec_mul(k, pt=(GX, GY)):
    r = None
    while k:
        if k & 1:
            r = ec_add(r, pt)
        pt = ec_add(pt, pt)
        k >>= 1
    return r

def sign(d, z, k=None):
    k = k or random.randrange(1, N)
    R = ec_mul(k)
    r = R[0] % N
    s = inv(k, N) * (z + r * d) % N
    return r, s


OFF_BLOB  = 0x1880
OFF_SEAL  = 0x2000
OFF_HASH  = 0x2018

def seal_hash(data: bytes) -> bytes:
    tmp = bytearray(data)
    tmp[OFF_HASH:OFF_HASH+32] = b"\x00" * 32
    return hashlib.sha256(tmp).digest()

def patch_pubkey(data: bytes, Q) -> bytes:
    out = bytearray(data)
    x, y = Q
    blob = b"ECS1" + struct.pack("<I", 32) + x.to_bytes(32,"big") + y.to_bytes(32,"big")
    out[OFF_BLOB:OFF_BLOB+72] = blob
    out[OFF_HASH:OFF_HASH+32] = seal_hash(bytes(out))
    return bytes(out)


SIG_PREFIX = b"Crackme/Verify/v1"
MC_PREFIX  = "MC1-"
VC_PREFIX  = "VC1-"

def get_local_machine_code():
    import winreg
    k = winreg.OpenKey(winreg.HKEY_LOCAL_MACHINE, r"SOFTWARE\Microsoft\Cryptography")
    guid, _ = winreg.QueryValueEx(k, "MachineGuid")
    buf = ctypes.create_string_buffer(260)
    ctypes.windll.kernel32.GetWindowsDirectoryA(buf, 260)
    root = buf.value[:3].encode() if isinstance(buf.value, str) else buf.value[:3]
    vol = ctypes.c_ulong(0)
    ctypes.windll.kernel32.GetVolumeInformationA(root, None, 0, ctypes.byref(vol), None, None, None, 0)
    fp = hashlib.sha256(b"Crackme/Machine/v1" + guid.lower().encode() + struct.pack("<I", vol.value)).digest()
    return MC_PREFIX + fp.hex().upper(), fp

def parse_mc_input(mc_text):
    mc_text = mc_text.strip()
    if not mc_text.startswith(MC_PREFIX):
        return False, "", "机器码必须以 MC1- 开头"
    fp_hex = mc_text[len(MC_PREFIX):].strip()
    if len(fp_hex) != 64:
        return False, "", f"FP&#8209;hex 需要64位,实际 {len(fp_hex)}"
    try:
        bytes.fromhex(fp_hex)
    except ValueError:
        return False, "", "包含非法十六进制字符"
    return True, fp_hex.upper(), ""

def keygen_from_d_and_mc(d: int, mc_text: str):
    ok, fp_hex, err = parse_mc_input(mc_text)
    if not ok:
        raise Exception(err)
    digest = hashlib.sha256(SIG_PREFIX + fp_hex.encode()).digest()
    z = int.from_bytes(digest, "big")
    r, s = sign(d, z)
    lic = VC_PREFIX + r.to_bytes(32,"big").hex().upper() + s.to_bytes(32,"big").hex().upper()
    return {
        "fp_hex": fp_hex,
        "digest_hex": digest.hex(),
        "z": z,
        "r": r,
        "s": s,
        "license": lic
    }


class KeygenGUI:
    def __init__(self, root):
        self.root = root
        root.title("Crackme 公钥补丁 + 注册机GUI")
        root.geometry("860x640")
        self.private_d = None   
        self.patched_exe_path = ""

        main = ttk.Frame(root, padding=10)
        main.pack(fill=tk.BOTH, expand=True)

        
        file_frm = ttk.LabelFrame(main, text="EXE 文件路径")
        file_frm.pack(fill=tk.X, pady=4)
        self.var_src = tk.StringVar()
        self.var_patch = tk.StringVar()
        ttk.Label(file_frm, text="原始Crackme.exe:").grid(row=0, column=0, sticky="w", padx=4, pady=3)
        ttk.Entry(file_frm, textvariable=self.var_src, width=70).grid(row=0, column=1, padx=4)
        ttk.Button(file_frm, text="选择", command=self.browse_src).grid(row=0, column=2)

        ttk.Label(file_frm, text="输出补丁exe:").grid(row=1, column=0, sticky="w", padx=4, pady=3)
        ttk.Entry(file_frm, textvariable=self.var_patch, width=70).grid(row=1, column=1, padx=4)
        ttk.Button(file_frm, text="另存", command=self.browse_patch).grid(row=1, column=2)

       
        key_frm = ttk.LabelFrame(main, text="密钥与公钥补丁")
        key_frm.pack(fill=tk.X, pady=4)
        ttk.Button(key_frm, text="生成新P&#8209;256密钥对并打公钥补丁", command=self.do_patch).pack(side=tk.LEFT, padx=4, pady=4)
        ttk.Label(key_frm, text="当前私钥d(hex):").pack(side=tk.LEFT, padx=(12,2))
        self.var_dhex = tk.StringVar()
        ttk.Entry(key_frm, textvariable=self.var_dhex, width=52, font=("Consolas",9)).pack(side=tk.LEFT)

        
        mc_frm = ttk.LabelFrame(main, text="机器码 MC1&#8209; (支持本机读取 / 自定义粘贴)")
        mc_frm.pack(fill=tk.X, pady=4)
        self.var_mc = tk.StringVar()
        ttk.Entry(mc_frm, textvariable=self.var_mc, font=("Consolas",9)).pack(side=tk.LEFT, fill=tk.X, expand=True, padx=4, pady=4)
        ttk.Button(mc_frm, text="读取本机机器码", command=self.fill_local_mc).pack(side=tk.LEFT)
        ttk.Button(mc_frm, text="用当前私钥生成授权码", command=self.do_keygen).pack(side=tk.LEFT, padx=6)

       
        out_frm = ttk.LabelFrame(main, text="输出日志")
        out_frm.pack(fill=tk.BOTH, expand=True, pady=6)
        self.txt_log = tk.Text(out_frm, font=("Consolas",9))
        self.txt_log.pack(fill=tk.BOTH, expand=True)

       
        bot_frm = ttk.Frame(main)
        bot_frm.pack(fill=tk.X)
        ttk.Button(bot_frm, text="运行补丁exe测试授权码", command=self.run_patched_test).pack(side=tk.LEFT)
        ttk.Button(bot_frm, text="清空日志", command=self.clear_log).pack(side=tk.LEFT, padx=8)

    def log(self, s):
        self.txt_log.insert(tk.END, s+"\n")
        self.txt_log.see(tk.END)
        self.root.update_idletasks()

    def clear_log(self):
        self.txt_log.delete("1.0", tk.END)

    def browse_src(self):
        p = filedialog.askopenfilename(filetypes=[("exe","*.exe"),("all","*.*")])
        if p:
            self.var_src.set(p)

    def browse_patch(self):
        p = filedialog.asksaveasfilename(defaultextension=".exe", filetypes=[("exe","*.exe")])
        if p:
            self.var_patch.set(p)

    def fill_local_mc(self):
        try:
            mc,_ = get_local_machine_code()
            self.var_mc.set(mc)
            self.log(f"[+] 本机机器码已填入: {mc}")
        except Exception as e:
            messagebox.showerror("错误", str(e))
            self.log(f"[!] 获取本机机器码失败: {e}")

    def do_patch(self):
        src_path = self.var_src.get().strip()
        dst_path = self.var_patch.get().strip()
        if not os.path.isfile(src_path):
            messagebox.showerror("错误","原始exe不存在,请选择源文件")
            return
        if not dst_path:
            messagebox.showerror("错误","请设置补丁exe输出路径")
            return
        try:
            data = open(src_path,"rb").read()
            # 校验 seal模型
            orig_seal = seal_hash(data)
            embedded = data[OFF_HASH:OFF_HASH+32]
            if orig_seal != embedded:
                self.log("[!] 警告:原文件 seal_hash 校验不匹配,文件可能不是原版Crackme.exe")
            # 生成密钥对
            d = random.randrange(1, N)
            Q = ec_mul(d)
            patched_bytes = patch_pubkey(data, Q)
            open(dst_path,"wb").write(patched_bytes)
            self.private_d = d
            self.patched_exe_path = dst_path
            self.var_dhex.set(hex(d))
            self.log(f"[+] 补丁完成 -> {dst_path}")
            self.log(f"[+] 新私钥 d = {hex(d)}")
            self.log(f"[+] 公钥 Qx={Q[0]:064x}")
            self.log(f"[+] 公钥 Qy={Q[1]:064x}")
        except Exception as e:
            messagebox.showerror("打补丁异常", str(e))
            self.log(f"[!] patch exception: {e}")

    def do_keygen(self):
        mc_text = self.var_mc.get().strip()
        if self.private_d is None:
            messagebox.showerror("错误","请先生成密钥并打公钥补丁!")
            return
        if not mc_text:
            messagebox.showerror("错误","请输入机器码 MC1&#8209;...")
            return
        try:
            res = keygen_from_d_and_mc(self.private_d, mc_text)
            self.log("\n==== 注册机计算结果 ====")
            self.log(f"输入机器码  : {mc_text}")
            self.log(f"FP hex      : {res['fp_hex']}")
            self.log(f"Digest hex  : {res['digest_hex']}")
            self.log(f"z(int)      : {res['z']:x}")
            self.log(f"r           : {res['r']:x}")
            self.log(f"s           : {res['s']:x}")
            self.log(f"授权License : {res['license']}")
        except Exception as e:
            messagebox.showerror("注册机失败", str(e))
            self.log(f"[!] keygen error: {e}")

    def run_patched_test(self):
        lic_line = None
        for line in self.txt_log.get("1.0", tk.END).splitlines():
            if line.startswith("授权License : "):
                lic_line = line.split(":",1)[1].strip()
                break
        if not lic_line:
            messagebox.showinfo("提示","日志中未找到授权码,请先生成License")
            return
        exe = self.patched_exe_path
        if not exe or not os.path.isfile(exe):
            messagebox.showerror("错误","补丁exe路径无效,请先打补丁")
            return
        try:
            proc = subprocess.run(
                [exe],
                input=(lic_line+"\n").encode("utf&#8209;8"),
                capture_output=True,
                timeout=25
            )
            stdout = proc.stdout.decode(errors="replace")
            stderr = proc.stderr.decode(errors="replace")
            self.log("\n==== 补丁EXE运行输出 ====")
            self.log(stdout)
            if stderr:
                self.log(f"STDERR:{stderr}")
            if "Success" in stdout:
                self.log(" 结果:&#9989; Success 验证通过")
            else:
                self.log(" 结果:&#10060; Error 验证失败")
        except Exception as e:
            self.log(f"[!] run test exception: {e}")


if __name__ == "__main__":
    root = tk.Tk()
    app = KeygenGUI(root)
    root.mainloop()
您需要登录后才可以回帖 登录 | 注册[Register]

本版积分规则

返回列表

RSS订阅|小黑屋|处罚记录|联系我们|吾爱破解 - 52pojie.cn ( 京ICP备16042023号 | 京公网安备 11010502030087号 )

GMT+8, 2026-9-18 21:17

Powered by Discuz!

Copyright © 2001-2020, Tencent Cloud.

快速回复 返回顶部 返回列表