吾爱破解 - 52pojie.cn

 找回密码
 注册[Register]

QQ登录

只需一步,快速开始

查看: 6348|回复: 27
上一主题 下一主题
收起左侧

[KeyGenMe] 新人第一次发一个简单的CM【注册码方式】

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

说明:
今天突发奇想想用纯win32 api做一个窗口程序,又突然想到了吾爱破解论坛上面的破解区,于是就写了个这个CrackMe。
小白第一次做CM,希望大家多多支持,大佬轻点喷。。
这是程序界面,目前账号只支持纯英文输入(本人水平有限,时间不够,才写的这样)



提示:字符串为明码,可通过od字符串查找查看。

欢迎大家踊跃尝试,有什么问题可以联系我讨论交流,当然,每日的1Cb免费的哦(疯狂暗示)
附件:

本帖子中包含更多资源

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

x

免费评分

参与人数 4吾爱币 +8 热心值 +3 收起 理由
Deuez + 1 谢谢@Thanks!
bitpeach + 1 + 1 用心讨论,共获提升!
途院长 + 1 欢迎分析讨论交流,吾爱破解论坛有你更精彩!
CrazyNut + 6 + 1 欢迎分析讨论交流,吾爱破解论坛有你更精彩!

查看全部评分

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

来自 2#
monvvv 发表于 2019-3-24 13:04
稍微弄了一下,这个用的算是挺普遍的算法模式了。

代码:

验证流程:

def GetVerifictionForUsername(username):
    username = str.encode(username)
    for i in range(0, len(username)):
        byte = username[i]
        if byte < 65:
            return 1
        if byte > 90:
            username = username[:i] + bytes([byte - 32]) + username[i+1:]
    username_sum = 0
    for i in range(0, len(username)):
        username_sum += username[i]
    username_verify = username_sum ^ 0x1357
    return username_verify

def GetVerifictionForReg(reg):
    reg_sum = 0
    for i in range(0, len(reg)):
        byte = ord(reg[i]) - 48
        reg_sum = 10 * reg_sum + byte
    reg_verify = reg_sum ^ 0x2468
    return reg_verify

def CheckReg(username, reg):
    return GetVerifictionForUsername(username) == GetVerifictionForReg(reg)

根据上面逆推出的注册机:

def KeyGen(username):
    username_verifiction = GetVerifictionForUsername(username)

    reg_sum = username_verifiction ^ 0x2468

    results = []
    FindReg(results, reg_sum)

    #测试注册码
    for i in range(0, len(results)):
        reg = results[i]
        assert CheckReg(username, reg)
    print("username_verifiction = " + str(username_verifiction))
    print("reg_verifiction = " + str(GetVerifictionForReg(results[0])))

    return results

#其实这段算是暴力枚举
def FindReg(result, reg_sum, n=-1, rs=[]):

    if reg_sum < 0:
        return
    if n != -1:
        #assert (reg_sum - n) % 10 == 0
        reg_sum = (reg_sum - n) // 10  # 可以确定能整除
        rs.append(int(n + 48))
    if reg_sum == 0:
        rs.reverse()
        result.append(bytes(rs).decode())
        return

    singel_digits = reg_sum % 10  # 确保减去最后一位后能被10整除

    # n belongs to [0,78]
    min_digits = 0
    max_digits = 6 if singel_digits > 8 else 7
    for i in range(min_digits, max_digits + 1):
        new_rs = copy.deepcopy(rs)
        FindRegLoop(result, reg_sum, i * 10 + singel_digits, new_rs)
    return

本帖子中包含更多资源

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

x

免费评分

参与人数 2吾爱币 +6 热心值 +2 收起 理由
CrazyNut + 3 + 1 用心讨论,共获提升!
liphily + 3 + 1 欢迎分析讨论交流,吾爱破解论坛有你更精彩!

查看全部评分

推荐
迷雾 发表于 2019-7-4 13:01
本帖最后由 迷雾 于 2019-7-4 13:03 编辑

先上效果
本人渣渣一枚,大神们勿喷,lz的程序没加密我就直接ida f5了.
[C] 纯文本查看 复制代码
INT_PTR __stdcall DialogFunc(HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam)
{
  char v5; // dl
  void (__stdcall *v6)(UINT); // ebx
  int v7; // ecx
  char *v8; // ebx
  char v9; // al
  int v10; // esi
  int v11; // eax
  int v12; // esi
  CHAR v13; // al
  CHAR *v14; // edx
  int v15; // ecx
  CHAR v16; // al
  HWND v17; // eax
  HWND v18; // eax
  HWND v19; // eax
  HWND v20; // eax
  HICON v21; // eax
  signed int v22; // [esp+0h] [ebp-110h]
  CHAR String; // [esp+4h] [ebp-10Ch]
  char Dst[100]; // [esp+68h] [ebp-A8h]
  CHAR String2[16]; // [esp+CCh] [ebp-44h]
  __int16 v26; // [esp+DCh] [ebp-34h]
  CHAR v27[16]; // [esp+E0h] [ebp-30h]
  int v28; // [esp+F0h] [ebp-20h]
  __int16 v29; // [esp+F4h] [ebp-1Ch]
  CHAR v30[16]; // [esp+F8h] [ebp-18h]
  __int16 v31; // [esp+108h] [ebp-8h]
  char v32; // [esp+10Ah] [ebp-6h]

  v26 = 33;
  v28 = 565626318;
  v29 = 33;
  *(_OWORD *)String2 = xmmword_D52128;          // 对应的字符串为 "恭喜你,成功"
  v31 = -24157;
  *(_OWORD *)v27 = xmmword_D5213C;
  v32 = 0;
  *(_OWORD *)v30 = xmmword_D52154;
  memset(Dst, 0, 0x64u);
  memset(&String, 0, 0x64u);
  if ( Msg == 0x10 )                            // WM_CLOSE
  {
    DestroyWindow(hWnd);
    return 0;
  }
  if ( Msg == 272 )                             // WM_INITDIALOG
  {
    v21 = LoadIconA(hInstance, (LPCSTR)0x69);
    SendMessageA(hWnd, 0x80u, 1u, (LPARAM)v21); // WM_SETICON
    SendDlgItemMessageA(hWnd, 1003, 0xC5u, 0x50u, 0);
    return 0;
  }
  if ( Msg != 273 )                             // WM_COMMAND
    return 0;
  if ( (unsigned __int16)wParam == 1007 )
  {
    v22 = GetDlgItemTextA(hWnd, 1003, Dst, 101);// UserName
    GetDlgItemTextA(hWnd, 1004, &String, 101);  // PassWord
    v5 = Dst[0];
    v6 = (void (__stdcall *)(UINT))MessageBeep;
    if ( Dst[0] && v22 >= 5 )                   // if userName[0]!=0 && length(userName)>=5
    {
      v7 = 0;
      v8 = Dst;                                 // userName
      if ( v22 <= 0 )                           // length(userName)
      {
LABEL_15:
        v10 = 0;
        if ( v5 )                               // v5=首字符
        {
          do
          {
            v11 = v5;                           // 移到下一个字符,v5=下一字符
            v5 = *++v8;
            v10 += v11;
          }
          while ( *v8 );
        }
        v12 = v10 ^ 0x1357;                     // v10=所有字符ascii码之和
      }
      else                                      // if userName[0]==0 || length(userName)<5
      {
        while ( 1 )
        {
          v9 = Dst[v7];                         // 如果用户名是数字,跳出循环
          if ( v9 < 65 )
            break;                              // 如果ASCI大于90(判断小写字母?)
          if ( v9 > 90 )                        // 转为大写字母
            Dst[v7] = v9 - 32;
          if ( ++v7 >= v22 )                    // 索引下移,这里应该是v7++吧?,先移动下一再判断是否到达结尾
          {
            v5 = Dst[0];                        // v5=首字符
            goto LABEL_15;
          }
        }                                       // 如果有数字跳出循环设置这个标记
        v12 = 1;
      }
      v13 = String;                             // PassWord
      v14 = &String;                            // Pointer to PassWord
      v15 = 0;
      if ( String )                             // 将每一个密码字符-48('0')转为数字 然后放到缓冲区v14中,v15为每一次转换出的数字加上上一次的转换的数字*10
      {
        do
        {
          v16 = v13 - 48;
          *v14++ = v16;
          v15 = v16 + 10 * v15;
          v13 = *v14;                           // 这个v13好像没什么卵用
        }
        while ( *v14 );
      }
      if ( v12 == (v15 ^ 0x2468) )              // 如果用户名有数字的话这里v12==1
      {
        lstrcpyA(Text, String2);                // 密码正确 "恭喜你,成功"
        v17 = GetDlgItem(hWnd, 1003);
        EnableWindow(v17, 0);
        v18 = GetDlgItem(hWnd, 1004);
        EnableWindow(v18, 0);
      }
      else
      {
        lstrcpyA(Text, v27);                    // 密码错误
      }
      v19 = GetDlgItem(hWnd, 1004);
      SetFocus(v19);
      v6 = (void (__stdcall *)(UINT))MessageBeep;
    }
    else
    {
      lstrcpyA(Text, v30);                      // 长度不对
      v20 = GetDlgItem(hWnd, 1003);
      SetFocus(v20);
      MessageBeep(0);
    }
    v6(0);
    MessageBoxA(hWnd, Text, "CrackMe", 0);
  }
  else if ( (unsigned __int16)wParam == 1008 )
  {
    SendMessageA(hWnd, 0x10u, 0, 0);
    return 1;
  }
  return 1;
}


//根据这个枚举出5位数字下的一个正确密码
[C++] 纯文本查看 复制代码
#include <iostream>
using namespace std;
int func(char *p)
{
        int a=0, b=0, c=0;
        char buf[10] = { 0 };
        int i = 0;
        do
        {
                a = *p - '0';
                buf[i++] = a;
                c = a + 10 * c;
                p++;

        } while (*p);
        return c;
}
int main()
{
        char a, b, c, d, e;
        char buf[7] = { 0 };
        for (a = '0'; a <= '9'; a++)
                for (b = '0'; b <= '9'; b++)
                        for (c = '0'; c <= '9'; c++)
                                for (d = '0'; d <= '9'; d++)
                                        for (e = '0'; e <= '9'; e++)
                                        {
                                                buf[0] = a;
                                                buf[1] = b;
                                                buf[2] = c;
                                                buf[3] = d;
                                                buf[4] = e;

                                                int ret = func(buf);
                                                if ((ret^0x2468) == 1)
                                                {
                                                        cout << "find" << endl;
                                                        cout << a << b << c << d << e << "ret:" << ret << endl;
                                                }
                                                
                                        }
        return 0;
}


find
09321ret:9321

本帖子中包含更多资源

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

x
4#
 楼主| 低调的菜鸡 发表于 2019-3-23 22:11 |楼主
hbwwt 发表于 2019-3-23 22:05
不明白有啥用哦

大佬。。。你都注册这么久了。我实在很难跟你解释这个有啥用。。。
5#
跌宕起伏 发表于 2019-3-24 02:55


直接下了MessageBox断点

本帖子中包含更多资源

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

x

免费评分

参与人数 1热心值 +1 收起 理由
liphily + 1 欢迎分析讨论交流,吾爱破解论坛有你更精彩!

查看全部评分

6#
 楼主| 低调的菜鸡 发表于 2019-3-24 09:20 |楼主
跌宕起伏 发表于 2019-3-24 02:55
直接下了MessageBox断点

哈哈,还能这么玩的么,阔以
7#
 楼主| 低调的菜鸡 发表于 2019-3-24 09:22 |楼主
天阶 发表于 2019-3-23 23:05
感谢楼主辛苦分享!也请楼主给我这样的新人普及下该程序的作用及使用方法!谢谢!

这个东西就是拿着练习逆向技术的。。如何分析程序保护,以及如何破解程序的注册机制,当然,由于编写者都不怎么专业,比起市面上的辅助这些少了很多检测技术,所以适合练手。
8#
 楼主| 低调的菜鸡 发表于 2019-3-24 09:25 |楼主
跌宕起伏 发表于 2019-3-24 02:55
直接下了MessageBox断点

考虑不周了,当时想用个对话框来提示信息的,哈哈,为了省事儿直接用的messagebox,没想到这么容易就被爆破了
9#
l1679668663 发表于 2019-3-24 10:14
不明白有什么用的   看帖子上面的蓝字   那不是有介绍吗
10#
byh3025 发表于 2019-3-24 12:42
那么多的坑让我这样的小白去跳,有意思吗

本帖子中包含更多资源

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

x
11#
 楼主| 低调的菜鸡 发表于 2019-3-24 14:56 |楼主
monvvv 发表于 2019-3-24 13:04
稍微弄了一下,这个用的算是挺普遍的算法模式了。

代码:

很强啊,老哥,哈哈哈,基本上和我写的注册机一样了
您需要登录后才可以回帖 登录 | 注册[Register]

本版积分规则

返回列表

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

GMT+8, 2024-11-24 14:48

Powered by Discuz!

Copyright © 2001-2020, Tencent Cloud.

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