吾爱破解 - 52pojie.cn

 找回密码
 注册[Register]

QQ登录

只需一步,快速开始

查看: 2619|回复: 7
收起左侧

[CrackMe] 萌新的第一个CM

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

本帖最后由 H1ghker 于 2019-5-21 22:57 编辑

如题,萌新的第一个CM,希望大佬们在破解的同时附上图文,让菜鸡楼主再学习一波,感谢了~
输入正确key后会弹出如下字符串

更新一下字符表,纯爆破没啥营养
zyxwvutsrqponmlkjihgfedcba
ABCDEFGHIJKLMNOPQRSTUVWXYZ

本帖子中包含更多资源

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

x

免费评分

参与人数 3吾爱币 +8 热心值 +3 收起 理由
CrazyNut + 6 + 1 欢迎分析讨论交流,吾爱破解论坛有你更精彩!
ezkengdie + 1 + 1 1
梦呓233 + 1 + 1 我很赞同!

查看全部评分

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

lizhirui 发表于 2019-5-21 23:28

这题有相当多的解,应当至少是65^23组解
算法如下:
首先是楼主的main函数:
[C] 纯文本查看 复制代码
int main_0()
{
  char v1; // [sp+Ch] [bp-110h]@1
  int curchar; // [sp+4Ch] [bp-D0h]@3
  char encryptedstr; // [sp+50h] [bp-CCh]@57
  int i; // [sp+B4h] [bp-68h]@1
  char inputstr[100]; // [sp+B8h] [bp-64h]@1

  memset(&v1, 0xCCu, 0x110u);
  i = 0;
  printf("start your crack!\n");
  scanf("%s", inputstr);
  while ( inputstr[i] )
  {
    curchar = inputstr[i];
    curchar -= 65;
    switch ( curchar )
    {
      case 0:
        inputstr[i] = 122;
        break;
      case 1:
        inputstr[i] = 121;
        break;
      case 2:
        inputstr[i] = 120;
        break;
      case 3:
        inputstr[i] = 119;
        break;
      case 4:
        inputstr[i] = 118;
        break;
      case 5:
        inputstr[i] = 117;
        break;
      case 6:
        inputstr[i] = 116;
        break;
      case 7:
        inputstr[i] = 115;
        break;
      case 8:
        inputstr[i] = 114;
        break;
      case 9:
        inputstr[i] = 113;
        break;
      case 10:
        inputstr[i] = 112;
        break;
      case 11:
        inputstr[i] = 111;
        break;
      case 12:
        inputstr[i] = 110;
        break;
      case 13:
        inputstr[i] = 109;
        break;
      case 14:
        inputstr[i] = 108;
        break;
      case 15:
        inputstr[i] = 107;
        break;
      case 16:
        inputstr[i] = 106;
        break;
      case 17:
        inputstr[i] = 105;
        break;
      case 18:
        inputstr[i] = 104;
        break;
      case 19:
        inputstr[i] = 103;
        break;
      case 20:
        inputstr[i] = 102;
        break;
      case 21:
        inputstr[i] = 101;
        break;
      case 22:
        inputstr[i] = 100;
        break;
      case 23:
        inputstr[i] = 99;
        break;
      case 24:
        inputstr[i] = 98;
        break;
      case 25:
        inputstr[i] = 97;
        break;
      case 57:
        inputstr[i] = 65;
        break;
      case 56:
        inputstr[i] = 66;
        break;
      case 55:
        inputstr[i] = 67;
        break;
      case 54:
        inputstr[i] = 68;
        break;
      case 53:
        inputstr[i] = 69;
        break;
      case 52:
        inputstr[i] = 70;
        break;
      case 51:
        inputstr[i] = 71;
        break;
      case 50:
        inputstr[i] = 72;
        break;
      case 49:
        inputstr[i] = 73;
        break;
      case 48:
        inputstr[i] = 74;
        break;
      case 47:
        inputstr[i] = 75;
        break;
      case 46:
        inputstr[i] = 76;
        break;
      case 45:
        inputstr[i] = 77;
        break;
      case 44:
        inputstr[i] = 78;
        break;
      case 43:
        inputstr[i] = 79;
        break;
      case 42:
        inputstr[i] = 80;
        break;
      case 41:
        inputstr[i] = 81;
        break;
      case 40:
        inputstr[i] = 82;
        break;
      case 39:
        inputstr[i] = 83;
        break;
      case 38:
        inputstr[i] = 84;
        break;
      case 37:
        inputstr[i] = 85;
        break;
      case 36:
        inputstr[i] = 86;
        break;
      case 35:
        inputstr[i] = 87;
        break;
      case 34:
        inputstr[i] = 88;
        break;
      case 33:
        inputstr[i] = 89;
        break;
      case 32:
        inputstr[i] = 90;
        break;
      default:
        break;
    }
    ++i;
  }
  j_TextEncrypt((int)inputstr, (int)&encryptedstr);
  printf("%s\n", &encryptedstr);
  if ( !strcmp(&encryptedstr, "Th1s_crAcKme_1s_S0_juNk") )
    printf("you_got_it!\n");
  else
    printf("nonono\n");
  system("pause");
  return 0;
}

可见一开始做了个字符替换
然后是楼主的TextEncrypt函数:
[C] 纯文本查看 复制代码
int __cdecl TextEncrypt(int inputstr, int resultstr)
{
  char strbuf; // [sp+Ch] [bp-58h]@1
  int ch1; // [sp+4Ch] [bp-18h]@1
  int ch2; // [sp+50h] [bp-14h]@1
  int ch3; // [sp+54h] [bp-10h]@1
  int ch4; // [sp+58h] [bp-Ch]@1
  int j; // [sp+5Ch] [bp-8h]@1
  int i; // [sp+60h] [bp-4h]@1

  memset(&strbuf, 0xCCu, 0x58u);
  i = 0;
  j = 0;
  ch1 = 0;
  ch2 = 0;
  ch3 = 0;
  ch4 = 0;
  while ( *(_BYTE *)(i + inputstr) )
  {
    ch1 = GetCharOffset(CharList, *(_BYTE *)(i + inputstr));
    ch2 = GetCharOffset(CharList, *(_BYTE *)(i + inputstr + 1));
    *(_BYTE *)(j++ + resultstr) = (ch2 >> 4) & 3 | 4 * ch1 & 0xFC;
    if ( *(_BYTE *)(i + inputstr + 2) != 61 )   // 61是等号
    {
      ch3 = GetCharOffset(CharList, *(_BYTE *)(i + inputstr + 2));
      *(_BYTE *)(j++ + resultstr) = (ch3 >> 2) & 0xF | 16 * ch2 & 0xF0;
      if ( *(_BYTE *)(i + inputstr + 3) != 61 )
      {
        ch4 = GetCharOffset(CharList, *(_BYTE *)(i + inputstr + 3));
        *(_BYTE *)(j++ + resultstr) = ch4 & 0x3F | ((_BYTE)ch3 << 6) & 0xC0;
      }
    }
    i += 4;
  }
  *(_BYTE *)(j + resultstr) = 0;
  return 0;
}

做了一些神秘的二进制运算

然后是楼主的GetCharOffset函数
[C] 纯文本查看 复制代码
int __cdecl sub_401220(char *a1, char a2)
{
  int result; // eax@2
  char v3; // [sp+Ch] [bp-44h]@1
  char *v4; // [sp+4Ch] [bp-4h]@1

  memset(&v3, 0xCCu, 0x44u);
  v4 = strchr(a1, a2);
  if ( v4 )
    result = v4 - a1;
  else
    result = -1;
  return result;
}


就是在一个给定的串中获取字符的索引
串为:ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/

上面的算法很明显了,直接暴力求解即可:
[C#] 纯文本查看 复制代码
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace _20190521
{
    class Program
    {
        static string strlist = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=";
        static int GetCharOffset(string str,char ch)
        { 
            return str.IndexOf(ch);    
        }

        static string TextEncrypt(string str)
        {
            char ch1,ch2,ch3,ch4;
            string r = "";

            ch1 = (char)GetCharOffset(strlist,str[0]);
            ch2 = (char)GetCharOffset(strlist,str[1]);
            ch3 = (char)GetCharOffset(strlist,str[2]);
            ch4 = (char)GetCharOffset(strlist,str[3]);
            r += (char)((ch2 >> 4) & 3 | 4 * ch1 & 0xFC); 

            if(str[2] != '=')
            { 
                r += (char)((ch3 >> 2) & 0xF | 16 * ch2 & 0xF0);   
                
                if(str[3] != '=')
                {
                    r += (char)(ch4 & 0x3F | (ch3 << 6) & 0xC0);   
                }
            }
            
            return r;
        }


        static void Main(string[] args)
        {
            string target = "Th1s_crAcKme_1s_S0_juNk";
            string result = "";
            int i,j,k,l;
            int index;
            string str1 = "zyxwvutsrqponmlkjihgfedcbaABCDEFGHIJKLMNOPQRSTUVWXYZ";
            string str2 = "ABCDEFGHIJKLMNOPQRSTUVWXYZzyxwvutsrqponmlkjihgfedcba";
            var map = new Dictionary<char,char>();

            for(i = 0;i < str1.Length;i++)
            {
                map[str1[i]] = str2[i];
            }

            for(index = 0;index < target.Length;)
            {
                bool flag = false;

                for(i = 0;i < strlist.Length;i++)
                { 
                    for(j = 0;j < strlist.Length;j++)
                    {
                        //for(k = 0;k < strlist.Length;k++)
                        {
                            //for(l = 0;l < strlist.Length;l++)
                            {
                                string str = TextEncrypt("" + strlist[i] + strlist[j] + "==");//后面两个字符直接取等于号即可,使用前面两个字符就能凑出全部的字符

                                if(((target.Length - index) >= str.Length) && (str == target.Substring(index,str.Length)))
                                {
                                    result += "" + strlist[i] + strlist[j] + "==";
                                    index += str.Length;
                                    flag = true;
                                    goto next;   
                                }
                            }
                        }
                    }
                }

                next:
                    if(flag == false)
                    {
                        throw new Exception();
                    }
                    else
                    {
                        Console.WriteLine(result);
                    }
            }

            Console.WriteLine(result);

            var result2 = "";

            for(i = 0;i < result.Length;i++)
            {
                if(map.ContainsKey(result[i]))
                {
                    result2 += map[result[i]];
                }
                else
                {
                    result2 += result[i];
                }
            }

            Console.WriteLine(result2);
            while(true);
        }
    }
}

本帖子中包含更多资源

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

x

免费评分

参与人数 3吾爱币 +6 热心值 +3 收起 理由
梦游枪手 + 2 + 1 看起来是base64,换了码表,再替换一次字符串?
CrazyNut + 3 + 1 李大佬出来欺负人啦
苏紫方璇 + 1 + 1 膜拜

查看全部评分

repobor 发表于 2019-5-21 22:31
这样吗?

本帖子中包含更多资源

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

x
 楼主| H1ghker 发表于 2019-5-21 22:33
cdevil 发表于 2019-5-22 12:34
lizhirui 发表于 2019-5-21 23:28
这题有相当多的解,应当至少是65^23组解
算法如下:
首先是楼主的main函数:

变形的base64编码

点评

ch1 = GetCharOffset(CharList, *(_BYTE *)(i + inputstr)); ch2 = GetCharOffset(CharList, *(_BYTE *)(i + inputstr + 1)); *(_BYTE *)(j++ + resultstr) = (ch2 >> 4) & 3 | 4 * ch1 & 0xFC; if  详情 回复 发表于 2019-5-22 14:47
原来如此  详情 回复 发表于 2019-5-22 14:46
lizhirui 发表于 2019-5-22 14:46
cdevil 发表于 2019-5-22 12:34
变形的base64编码

原来如此
lizhirui 发表于 2019-5-22 14:47
cdevil 发表于 2019-5-22 12:34
变形的base64编码

ch1 = GetCharOffset(CharList, *(_BYTE *)(i + inputstr));
    ch2 = GetCharOffset(CharList, *(_BYTE *)(i + inputstr + 1));
    *(_BYTE *)(j++ + resultstr) = (ch2 >> 4) & 3 | 4 * ch1 & 0xFC;
    if ( *(_BYTE *)(i + inputstr + 2) != 61 )   // 61是等号
    {
      ch3 = GetCharOffset(CharList, *(_BYTE *)(i + inputstr + 2));
      *(_BYTE *)(j++ + resultstr) = (ch3 >> 2) & 0xF | 16 * ch2 & 0xF0;
      if ( *(_BYTE *)(i + inputstr + 3) != 61 )
      {
        ch4 = GetCharOffset(CharList, *(_BYTE *)(i + inputstr + 3));
        *(_BYTE *)(j++ + resultstr) = ch4 & 0x3F | ((_BYTE)ch3 << 6) & 0xC0;
      }
    }

没研究出来这块怎么直接逆向
所以就直接暴力枚举了
52lxw 发表于 2019-5-27 00:11
变形base64的话,那还是挺简单的
您需要登录后才可以回帖 登录 | 注册[Register]

本版积分规则

返回列表

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

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

Powered by Discuz!

Copyright © 2001-2020, Tencent Cloud.

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