吾爱破解 - 52pojie.cn

 找回密码
 注册[Register]

QQ登录

只需一步,快速开始

查看: 1290|回复: 9
收起左侧

[CrackMe] 一个c语言的稍加混淆和反调试的CrackMe

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

本帖最后由 zunmx 于 2026-4-21 12:38 编辑

题目要求:
1. 脱壳(这个壳看起来好像不太对呢,嗯,小样儿,换个马甲我就不认识你了吗?)
2. 如果脱壳有难度,可以试一下CrackMe_Unpack,这个没有加壳
3. 让他输出Congrats!
4. 得到算号器

cm说明:
0. PE结构稍微修改了一些无关紧要的东西1. 为了防止直接字符串搜索,做了一些手段
2. 有一定的花指令和暗桩,触发后就算不对了
3. 没有使用额外的组件、工具、混淆器、纯手工古法编程
4. 初学者也可以尝试一下,借助AI分析试试呢?
5. debug工具插件是个好东西,嗯,虽然不太清楚原理,但是真管用呀。


测试用例:52pojie--UpYxIhQl2jIbAnAv




最后,如果大佬解出了,希望能给出过程,我也想学习一下。

本帖子中包含更多资源

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

x

免费评分

参与人数 1热心值 +1 收起 理由
zhifeiji + 1 用心讨论,共获提升!

查看全部评分

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

囚徒灬 发表于 2026-4-21 14:36
本帖最后由 囚徒灬 于 2026-4-21 14:39 编辑

PS E:\ai\cm\CM> .\crackme_dumped.exe
Hello, Cracker
Can you crack it?
Username: Qiutu
Active Code: OEGfOIEAzfQSEdWC
Congrats!
PS E:\ai\cm\CM>
壳也脱完了




密码是

  Name:   password
  Serial: QC*******Yb

本帖子中包含更多资源

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

x
囚徒灬 发表于 2026-4-21 14:56
zunmx 发表于 2026-4-21 14:54
大佬压缩包密码是什么?

name:
password
你自己计算一下

免费评分

参与人数 1吾爱币 +1 热心值 +1 收起 理由
zunmx + 1 + 1 懂了懂了

查看全部评分

囚徒灬 发表于 2026-4-21 13:09
本帖最后由 囚徒灬 于 2026-4-21 13:10 编辑

笑死 发错了,先把另一个发了
囚徒灬 发表于 2026-4-21 14:01
本帖最后由 囚徒灬 于 2026-4-21 14:09 编辑

PS E:\ai\cm\CM> .\crackme.exe
Hello, Cracker
Can you crack it?
Username: Qiutu
Active Code: OEGfOIEAzfQSEdWC
Congrats!
PS E:\ai\cm\CM>

claude opus 4.6 + ida pro mcp 全自动
 楼主| zunmx 发表于 2026-4-21 14:12
囚徒灬 发表于 2026-4-21 14:01
PS E:\ai\cm\CM> .\crackme.exe
Hello, Cracker
Can you crack it?

直接运行,没有附加调试器的情况下闪退吗?
程序输出结果后会退出,可能是太快了没有捕获到。通过cmd运行下试试?
我刚刚用虚拟机(win10) 没有问题,开发机器是Win11也没问题。
kali wine下运行也没问题呢?

本帖子中包含更多资源

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

x
囚徒灬 发表于 2026-4-21 14:15
zunmx 发表于 2026-4-21 14:12
直接运行,没有附加调试器的情况下闪退吗?
程序输出结果后会退出,可能是太快了没有捕获到。通过cmd运 ...

没闪退了,我环境问题,算出来了
 楼主| zunmx 发表于 2026-4-21 14:54
囚徒灬 发表于 2026-4-21 14:36
PS E:\ai\cm\CM> .\crackme_dumped.exe
Hello, Cracker
Can you crack it?

大佬压缩包密码是什么?
xuanyuzaixian 发表于 2026-4-21 19:43
最后,如果大佬解出了,希望能给出过程,我也想学习一下。
wolfSpicy 发表于 2026-7-2 21:39

这是对用户名加密后得出来的code
[Python] 纯文本查看 复制代码
#!/usr/bin/env python3
"""ZMX crackme keygen: derive 16-byte password from username.

Algorithm location: sub_140001C20 @ 0x140003262..0x140003362
Default params match normal run (dword_14001A05C=1, timing=0, v98=0).
"""


from __future__ import annotations

import argparse
import ctypes
import json
import struct
import sys
import urllib.error
import urllib.request

from pathlib import Path

N10 = 114514
KEY_LEN = 16

_TABLE_BIN = Path(__file__).with_name("tables_14001A080.bin")
TABLE_BLOB = bytearray(_TABLE_BIN.read_bytes() if _TABLE_BIN.exists() else b"\x00" * 256)
if len(TABLE_BLOB) != 256:
    raise RuntimeError(f"expected 256-byte table snapshot: {_TABLE_BIN}")


def c_char(value: int) -> int:
    """Simulate MSVC signed char cast (low 8 bits)."""
    return ctypes.c_int8(value & 0xFF).value


def c_mod(dividend: int, divisor: int) -> int:
    """Simulate MSVC signed integer remainder (trunc toward zero)."""
    if divisor == 0:
        return 0
    return int(ctypes.c_int(dividend).value % ctypes.c_int(divisor).value)


def _table_dword(odd: bool, index: int) -> int:
    base = 0x80 if odd else 0
    offset = base + index * 4
    return struct.unpack_from("<I", TABLE_BLOB, offset)[0]


def _table_byte(odd: bool, index: int) -> int:
    base = 0x80 if odd else 0
    return TABLE_BLOB[base + index * 4]


def _pick_char(value: int, *, second_loop: bool) -> int:
    index = c_mod(c_char(value), 26)
    odd = bool(value & 1)
    n10_sub = (N10 & 0xFF) if second_loop else N10
    table_val = (_table_dword(odd, index) - n10_sub) & 0xFFFFFFFF
    first_byte = _table_byte(odd, index)
    if c_char(first_byte - N10) >= 0:
        return table_val & 0xFF
    return c_mod(-c_char(table_val), 10) + 48


def derive_password(
    username: str,
    *,
    v93: int = 1,
    timing: int = 0,
    v98: int = 0,
) -> str:
    """Return the 16-byte password for *username*."""
    if not username:
        raise ValueError("username must not be empty")
    if len(username) > 16:
        raise ValueError("username must be at most 16 characters (scanf %16s)")

    ulen = len(username)
    v97 = timing + v98
    out = bytearray(KEY_LEN)

    v76 = (N10 * v97) & 0xFFFFFFFF
    first_mix = c_char(ord(username[0]) + v93)
    v77 = (v76 + first_mix) & 0xFFFFFFFF
    denom = c_char(v77)
    v78 = (v77 - c_mod(N10, denom)) & 0xFFFFFFFF
    out[0] = _pick_char(v78, second_loop=False)

    v76 = c_char(v93 + c_char(v76))
    for index in range(1, KEY_LEN):
        v83 = (v76 + ord(username[index % ulen])) & 0xFFFFFFFF
        denom = index + c_char(v83)
        v84 = (v83 - c_mod(N10, denom)) & 0xFFFFFFFF
        out[index] = _pick_char(v84, second_loop=True)

    return out.decode("latin1")


def load_tables_from_debugger(url: str = "http://127.0.0.1:3000/") -> bool:
    """Overwrite TABLE_BLOB with live tables from x64dbg MCP plugin."""
    body = json.dumps(
        {
            "jsonrpc": "2.0",
            "id": 1,
            "method": "tools/call",
            "params": {
                "name": "memory_read",
                "arguments": {
                    "address": "0x14001A080",
                    "size": 256,
                    "encoding": "hex",
                },
            },
        }
    ).encode()
    req = urllib.request.Request(
        url,
        data=body,
        headers={"Content-Type": "application/json"},
    )
    try:
        res = json.loads(urllib.request.urlopen(req, timeout=5).read().decode())
    except (urllib.error.URLError, TimeoutError, json.JSONDecodeError):
        return False

    for item in res.get("result", {}).get("content", []):
        text = item.get("text", "")
        try:
            payload = json.loads(text)
        except json.JSONDecodeError:
            continue
        data = bytes.fromhex(payload["data"])
        TABLE_BLOB[: len(data)] = data
        return True
    return False


def main(argv: list[str] | None = None) -> int:
    parser = argparse.ArgumentParser(
        description="Generate 16-byte crackme password from username.",
    )
    parser.add_argument("username", help="username entered in crackme")
    parser.add_argument(
        "--timing",
        type=int,
        default=0,
        choices=range(0, 11),
        metavar="[0-10]",
        help="GetTickCount delta capped to 0..10 (default: 0)",
    )
    parser.add_argument(
        "--v93",
        type=int,
        default=1,
        help="dword_14001A05C at derivation (default: 1)",
    )
    parser.add_argument(
        "--v98",
        type=int,
        default=0,
        choices=(0, 1),
        help="nonzero if qword_14001A040 was set before derivation (default: 0)",
    )
    parser.add_argument(
        "--live-tables",
        action="store_true",
        help="read ZMX tables from x64dbg @ 127.0.0.1:3000",
    )
    parser.add_argument(
        "--verify",
        metavar="EXPECTED",
        help="exit 1 unless generated key equals EXPECTED",
    )
    args = parser.parse_args(argv)

    if args.live_tables:
        if not load_tables_from_debugger():
            print("warning: could not read live tables, using static defaults", file=sys.stderr)

    password = derive_password(
        args.username,
        v93=args.v93,
        timing=args.timing,
        v98=args.v98,
    )

    if args.verify is not None and password != args.verify:
        print(f"mismatch: got {password!r}, expected {args.verify!r}", file=sys.stderr)
        return 1

    print(password)
    return 0


if __name__ == "__main__":
    raise SystemExit(main())
您需要登录后才可以回帖 登录 | 注册[Register]

本版积分规则

返回列表

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

GMT+8, 2026-7-3 09:52

Powered by Discuz!

Copyright © 2001-2020, Tencent Cloud.

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