吾爱破解 - 52pojie.cn

 找回密码
 注册[Register]

QQ登录

只需一步,快速开始

查看: 744|回复: 5
收起左侧

[CrackMe] 一道c++编写的求解flag的题目,欢迎求解

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

一道c++编写的求解flag的题目,欢迎求解,无壳无混淆。

本帖子中包含更多资源

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

x

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

geesehoward 发表于 2026-3-6 10:25
本帖最后由 geesehoward 于 2026-3-6 10:26 编辑


总体来说难度不太大,c++的IDA的伪代码比C要复杂一些。
[C++] 纯文本查看 复制代码
// Hidden C++ exception states: #wind=1
int __fastcall main(int argc, const char **argv, const char **envp)
{
  int v3; // edi
  __int64 v4; // r8
  __int64 v5; // rax
  __int64 v6; // r8
  __int64 v7; // rax
  __int64 v8; // r8
  __int64 v9; // rax
  __int64 v10; // r8
  __int64 v11; // rax
  __int64 v12; // r8
  __int64 v13; // rdx
  unsigned __int8 v14; // al
  size_t v15; // r8
  size_t v16; // rax
  __int64 v17; // rax
  void *v18; // rcx
  void *v19; // rcx
  void **v20; // rdx
  void **v21; // rcx
  size_t v22; // rbx
  void *v23; // rcx
  void *v24; // rcx
  __int64 v25; // rax
  __int64 v26; // r8
  __int64 v27; // rax
  __int64 v28; // r8
  __int64 v29; // rax
  __int64 v30; // r8
  void *v31; // rcx
  void **v32; // rsi
  char *v33; // rsi
  void **v34; // rbx
  size_t v35; // rsi
  void **v36; // rdx
  char *v37; // rbx
  void *v38; // rcx
  void **v39; // rdx
  void **v40; // rcx
  char *v41; // rbx
  unsigned __int64 v42; // rsi
  char *v43; // rax
  void *v44; // rcx
  void *v45; // rcx
  __int64 v46; // rax
  __int64 v47; // r8
  __int64 v48; // rax
  __int64 v49; // r8
  __int64 v50; // rax
  char *v51; // rax
  void *v52; // rcx
  void *Block[2]; // [rsp+38h] [rbp-71h] BYREF
  __m128i si128; // [rsp+48h] [rbp-61h]
  void *v56[2]; // [rsp+58h] [rbp-51h] BYREF
  __int64 v57; // [rsp+68h] [rbp-41h]
  void *Buf1[2]; // [rsp+70h] [rbp-39h] BYREF
  size_t Size; // [rsp+80h] [rbp-29h]
  unsigned __int64 v60; // [rsp+88h] [rbp-21h]
  __int128 v61; // [rsp+90h] [rbp-19h] BYREF
  __int128 v62; // [rsp+A0h] [rbp-9h]
  __int128 v63; // [rsp+B0h] [rbp+7h]
  __int128 v64; // [rsp+C0h] [rbp+17h]
  void *v65[2]; // [rsp+D0h] [rbp+27h] BYREF
  size_t v66; // [rsp+E0h] [rbp+37h]
  unsigned __int64 v67; // [rsp+E8h] [rbp+3Fh]

  v3 = 0;
  sub_7FF72D611C40(std::cout, &unk_7FF72D614478, envp);
  v5 = sub_7FF72D611C40(std::cout, &unk_7FF72D614480, v4);
  std::ostream::operator<<(v5, sub_7FF72D611E20);
  v7 = sub_7FF72D611C40(std::cout, &unk_7FF72D6144D8, v6);
  std::ostream::operator<<(v7, sub_7FF72D611E20);
  v9 = sub_7FF72D611C40(std::cout, &unk_7FF72D614510, v8);
  std::ostream::operator<<(v9, sub_7FF72D611E20);
  std::ostream::operator<<(std::cout, sub_7FF72D611E20);
  *(_OWORD *)Buf1 = 0;
  Size = 0;
  v60 = 15;
  LOBYTE(Buf1[0]) = 0;
  v11 = sub_7FF72D611C40(std::cout, &unk_7FF72D614568, v10);
  std::ostream::operator<<(v11, sub_7FF72D611E20);
  sub_7FF72D611C40(std::cout, "Enter the  flag: ", v12);
  LOBYTE(v13) = 10;
  v14 = std::ios::widen((char *)&std::cin + *(int *)(std::cin + 4LL), v13);
  sub_7FF72D611FD0(std::cin, Buf1, v14);
  v16 = Size;
  if ( !Size )
  {
    v17 = sub_7FF72D611C40(std::cout, "[-] Input cannot be empty!", v15);
    std::ostream::operator<<(v17, sub_7FF72D611E20);
    std::ostream::operator<<(std::cout, sub_7FF72D611E20);
    v16 = Size;
  }
  if ( v16 != 25 )
    goto LABEL_28;
  v61 = 0;
  v62 = 0;
  v63 = 0;
  v64 = 0;
  *(_OWORD *)v56 = 0;
  v57 = 0;
  *(_OWORD *)Block = 0;
  si128 = _mm_load_si128((const __m128i *)&xmmword_7FF72D614790);
  LOBYTE(Block[0]) = 0;
  sub_7FF72D6121E0(&v61, Block, (__int64)v56);
  if ( si128.m128i_i64[1] > 0xFuLL )
  {
    v18 = Block[0];
    if ( (unsigned __int64)(si128.m128i_i64[1] + 1) >= 0x1000 )
    {
      v18 = (void *)*((_QWORD *)Block[0] - 1);
      if ( (unsigned __int64)((char *)Block[0] - (char *)v18 - 8) > 0x1F )
        invalid_parameter_noinfo_noreturn();
    }
    j_j_free(v18);
  }
  v19 = v56[0];
  if ( v56[0] )
  {
    if ( v57 - (unsigned __int64)v56[0] >= 0x1000 )
    {
      v19 = (void *)*((_QWORD *)v56[0] - 1);
      if ( (unsigned __int64)((char *)v56[0] - (char *)v19 - 8) > 0x1F )
        goto LABEL_66;
    }
    j_j_free(v19);
  }
  v20 = &Buf2;
  if ( *((_QWORD *)&xmmword_7FF72D6177B8 + 1) > 0xFu )
    v20 = (void **)Buf2;
  v21 = Buf1;
  if ( v60 > 0xF )
    v21 = (void **)Buf1[0];
  v22 = Size;
  if ( Size == (_QWORD)xmmword_7FF72D6177B8 && (!Size || !memcmp(v21, v20, Size)) )
  {
    v23 = (void *)*((_QWORD *)&v63 + 1);
    if ( *((_QWORD *)&v63 + 1) )
    {
      if ( *((_QWORD *)&v64 + 1) - *((_QWORD *)&v63 + 1) >= 0x1000u )
      {
        v23 = *(void **)(*((_QWORD *)&v63 + 1) - 8LL);
        if ( (unsigned __int64)(*((_QWORD *)&v63 + 1) - (_QWORD)v23 - 8LL) > 0x1F )
          goto LABEL_75;
      }
      j_j_free(v23);
      *((_QWORD *)&v63 + 1) = 0;
      v64 = 0;
    }
    if ( *((_QWORD *)&v62 + 1) <= 0xFu )
    {
LABEL_28:
      v25 = sub_7FF72D611C40(std::cout, &unk_7FF72D6145E0, v15);
      std::ostream::operator<<(v25, sub_7FF72D611E20);
      v27 = sub_7FF72D611C40(std::cout, &unk_7FF72D614668, v26);
      std::ostream::operator<<(v27, sub_7FF72D611E20);
      v29 = sub_7FF72D611C40(std::cout, &unk_7FF72D614510, v28);
      std::ostream::operator<<(v29, sub_7FF72D611E20);
      std::ostream::operator<<(std::cout, sub_7FF72D611E20);
      sub_7FF72D611C40(std::cout, "\nPress Enter to exit...", v30);
      std::istream::get(std::cin);
      v3 = 1;
      goto LABEL_29;
    }
    v24 = (void *)v61;
    if ( (unsigned __int64)(*((_QWORD *)&v62 + 1) + 1LL) < 0x1000
      || (v24 = *(void **)(v61 - 8), (unsigned __int64)(v61 - (_QWORD)v24 - 8) <= 0x1F) )
    {
LABEL_27:
      j_j_free(v24);
      goto LABEL_28;
    }
    goto LABEL_75;
  }
  v32 = Buf1;
  if ( v60 > 0xF )
    v32 = (void **)Buf1[0];
  v33 = (char *)v32 + v22;
  v34 = Buf1;
  if ( v60 > 0xF )
    v34 = (void **)Buf1[0];
  *(_OWORD *)v56 = 0;
  v57 = 0;
  v35 = v33 - (char *)v34;
  if ( v35 )
  {
    sub_7FF72D612950(v56, v35);
    v36 = v34;
    v37 = (char *)v56[0];
    memmove(v56[0], v36, v35);
    v56[1] = &v37[v35];
  }
  sub_7FF72D6123D0(&v61, v65, v56);
  v38 = v56[0];
  if ( v56[0] )
  {
    if ( v57 - (unsigned __int64)v56[0] >= 0x1000 )
    {
      v38 = (void *)*((_QWORD *)v56[0] - 1);
      if ( (unsigned __int64)((char *)v56[0] - (char *)v38 - 8) > 0x1F )
        goto LABEL_66;
    }
    j_j_free(v38);
  }
  v39 = &::Block;
  if ( *((_QWORD *)&xmmword_7FF72D6177D8 + 1) > 0xFu )
    v39 = (void **)::Block;
  v40 = v65;
  v41 = (char *)v65[0];
  v42 = v67;
  if ( v67 > 0xF )
    v40 = (void **)v65[0];
  v15 = v66;
  if ( v66 != (_QWORD)xmmword_7FF72D6177D8 || v66 && memcmp(v40, v39, v66) )
  {
    if ( v42 > 0xF )
    {
      v51 = v41;
      if ( v42 + 1 >= 0x1000 )
      {
        v41 = (char *)*((_QWORD *)v41 - 1);
        if ( (unsigned __int64)(v51 - v41 - 8) > 0x1F )
          goto LABEL_66;
      }
      j_j_free(v41);
    }
    v66 = 0;
    v67 = 15;
    LOBYTE(v65[0]) = 0;
    v52 = (void *)*((_QWORD *)&v63 + 1);
    if ( *((_QWORD *)&v63 + 1) )
    {
      if ( *((_QWORD *)&v64 + 1) - *((_QWORD *)&v63 + 1) >= 0x1000u )
      {
        v52 = *(void **)(*((_QWORD *)&v63 + 1) - 8LL);
        if ( (unsigned __int64)(*((_QWORD *)&v63 + 1) - (_QWORD)v52 - 8LL) > 0x1F )
          goto LABEL_75;
      }
      j_j_free(v52);
      *((_QWORD *)&v63 + 1) = 0;
      v64 = 0;
    }
    if ( *((_QWORD *)&v62 + 1) <= 0xFu )
      goto LABEL_28;
    v24 = (void *)v61;
    if ( (unsigned __int64)(*((_QWORD *)&v62 + 1) + 1LL) < 0x1000 )
      goto LABEL_27;
    v24 = *(void **)(v61 - 8);
    if ( (unsigned __int64)(v61 - (_QWORD)v24 - 8) <= 0x1F )
      goto LABEL_27;
LABEL_75:
    invalid_parameter_noinfo_noreturn();
  }
  if ( v42 <= 0xF )
    goto LABEL_54;
  v43 = v41;
  if ( v42 + 1 >= 0x1000 )
  {
    v41 = (char *)*((_QWORD *)v41 - 1);
    if ( (unsigned __int64)(v43 - v41 - 8) > 0x1F )
LABEL_66:
      invalid_parameter_noinfo_noreturn();
  }
  j_j_free(v41);
LABEL_54:
  v66 = 0;
  v67 = 15;
  LOBYTE(v65[0]) = 0;
  v44 = (void *)*((_QWORD *)&v63 + 1);
  if ( *((_QWORD *)&v63 + 1) )
  {
    if ( *((_QWORD *)&v64 + 1) - *((_QWORD *)&v63 + 1) >= 0x1000u )
    {
      v44 = *(void **)(*((_QWORD *)&v63 + 1) - 8LL);
      if ( (unsigned __int64)(*((_QWORD *)&v63 + 1) - (_QWORD)v44 - 8LL) > 0x1F )
        goto LABEL_75;
    }
    j_j_free(v44);
    *((_QWORD *)&v63 + 1) = 0;
    v64 = 0;
  }
  if ( *((_QWORD *)&v62 + 1) > 0xFu )
  {
    v45 = (void *)v61;
    if ( (unsigned __int64)(*((_QWORD *)&v62 + 1) + 1LL) >= 0x1000 )
    {
      v45 = *(void **)(v61 - 8);
      if ( (unsigned __int64)(v61 - (_QWORD)v45 - 8) > 0x1F )
        goto LABEL_75;
    }
    j_j_free(v45);
  }
  v46 = sub_7FF72D611C40(std::cout, &unk_7FF72D6145E0, v15);
  std::ostream::operator<<(v46, sub_7FF72D611E20);
  v48 = sub_7FF72D611C40(std::cout, &unk_7FF72D614638, v47);
  std::ostream::operator<<(v48, sub_7FF72D611E20);
  v50 = sub_7FF72D611C40(std::cout, &unk_7FF72D614510, v49);
  std::ostream::operator<<(v50, sub_7FF72D611E20);
LABEL_29:
  if ( v60 > 0xF )
  {
    v31 = Buf1[0];
    if ( v60 + 1 >= 0x1000 )
    {
      v31 = (void *)*((_QWORD *)Buf1[0] - 1);
      if ( (unsigned __int64)((char *)Buf1[0] - (char *)v31 - 8) > 0x1F )
        invalid_parameter_noinfo_noreturn();
    }
    j_j_free(v31);
  }
  return v3;
}

main函数中,96行确定flag长度是25,137行有个迷惑项,但输入和base64字符串比较,显然无视就可以。
核心校验在195行和216行,216行是和目标字符串比对,查看函数sub_7FF72D6123D0
[C++] 纯文本查看 复制代码
// Hidden C++ exception states: #wind=1
_QWORD *__fastcall sub_7FF72D6123D0(__int64 *a1, _QWORD *a2, _QWORD *a3)
{
  _QWORD *v3; // r9
  unsigned __int64 v6; // r13
  unsigned __int64 v7; // r12
  unsigned __int64 v8; // r14
  int v9; // r8d
  unsigned __int8 *v10; // rcx
  unsigned __int64 v11; // rdx
  unsigned int v12; // r8d
  char v13; // r9
  char v14; // r10
  char v15; // r11
  unsigned __int64 v16; // r15
  char v17; // r8
  __int64 v18; // rsi
  __int64 v19; // rbp
  unsigned __int64 v20; // rsi
  unsigned __int8 *v21; // rbp
  unsigned __int64 v22; // rsi
  __int64 v23; // r15
  __int64 *v24; // rcx
  char v25; // r9
  __int64 v26; // r9
  __int64 *v27; // rax
  unsigned __int64 v28; // rdx
  unsigned __int64 v29; // rcx
  _QWORD *v30; // rax
  unsigned __int64 v31; // rcx
  unsigned __int64 v32; // rdx
  _QWORD *v33; // rax
  unsigned __int64 v34; // rcx
  unsigned __int64 v35; // rdx
  _QWORD *v36; // rax
  _BYTE v38[4]; // [rsp+20h] [rbp-58h] BYREF
  int v39; // [rsp+24h] [rbp-54h]
  _QWORD *v40; // [rsp+28h] [rbp-50h]
  _QWORD *v41; // [rsp+30h] [rbp-48h]

  v3 = a3;
  v40 = a3;
  v41 = a2;
  *(_OWORD *)a2 = 0;
  a2[2] = 0;
  a2[3] = 0;
  a2[2] = 0;
  a2[3] = 15;
  *(_BYTE *)a2 = 0;
  v39 = 1;
  v6 = a3[1] - *a3;
  v7 = 0;
  if ( v6 )
  {
    while ( 1 )
    {
      v8 = 3;
      if ( v6 - v7 < 3 )
        v8 = v6 - v7;
      v9 = 0;
      if ( v8 )
      {
        v10 = (unsigned __int8 *)(v7 + *v3);
        v11 = v8;
        do
        {
          v9 = *v10++ | (v9 << 8);
          --v11;
        }
        while ( v11 );
      }
      v12 = v9 << (8 * (3 - v8));
      v13 = (v12 >> 12) & 0x3F;
      v14 = (v12 >> 6) & 0x3F;
      v15 = v12 & 0x3F;
      v16 = a2[2];
      v17 = (v12 >> 18) & 0x3F;
      v18 = a1[6];
      v19 = a1[5];
      if ( v19 != v18 )
      {
        v20 = v18 - v19;
        v17 = v16 ^ *(_BYTE *)(v16 % v20 + v19) ^ __ROR1__(v17, 7);
        v13 = (v16 + 1) ^ *(_BYTE *)((v16 + 1) % v20 + v19) ^ __ROR1__(v13, 7);
        v14 = (v16 + 2) ^ *(_BYTE *)((v16 + 2) % v20 + v19) ^ __ROR1__(v14, 7);
        v15 = (v16 + 3) ^ *(_BYTE *)((v16 + 3) % v20 + v19) ^ __ROR1__(v15, 7);
      }
      v38[2] = v14;
      v38[1] = v13;
      v38[0] = v17;
      v38[3] = v15;
      v21 = v38;
      v22 = 0;
      v23 = 4;
      do
      {
        if ( v22 > v8 )
        {
          if ( *((_BYTE *)a1 + 33) )
          {
            v26 = rand() % 64;
            v27 = a1;
            if ( (unsigned __int64)a1[3] > 0xF )
              v27 = (__int64 *)*a1;
            v25 = *((_BYTE *)v27 + v26);
          }
          else
          {
            v25 = *((_BYTE *)a1 + 32);
          }
        }
        else
        {
          v24 = a1;
          if ( (unsigned __int64)a1[3] > 0xF )
            v24 = (__int64 *)*a1;
          v25 = *((_BYTE *)v24 + *v21);
        }
        v28 = a2[3];
        v29 = a2[2];
        if ( v29 >= v28 )
        {
          sub_7FF72D611E60(a2);
        }
        else
        {
          a2[2] = v29 + 1;
          v30 = a2;
          if ( v28 > 0xF )
            v30 = (_QWORD *)*a2;
          *((_BYTE *)v30 + v29 + 1) = 0;
          *((_BYTE *)v30 + v29) = v25;
        }
        ++v22;
        ++v21;
        --v23;
      }
      while ( v23 );
      if ( !*((_BYTE *)a1 + 33) || v8 >= 3 )
        goto LABEL_39;
      if ( v8 == 1 )
        break;
      if ( v8 == 2 )
      {
        v34 = a2[2];
        v35 = a2[3];
        if ( v34 < v35 )
        {
          a2[2] = v34 + 1;
          v36 = a2;
          if ( v35 > 0xF )
            v36 = (_QWORD *)*a2;
          *(_WORD *)((char *)v36 + v34) = 64;
          goto LABEL_39;
        }
LABEL_38:
        sub_7FF72D611E60(a2);
      }
LABEL_39:
      v7 += 3LL;
      v3 = v40;
      if ( v7 >= v6 )
        return a2;
    }
    v31 = a2[2];
    v32 = a2[3];
    if ( v31 < v32 )
    {
      a2[2] = v31 + 1;
      v33 = a2;
      if ( v32 > 0xF )
        v33 = (_QWORD *)*a2;
      *(_WORD *)((char *)v33 + v31) = 33;
      goto LABEL_39;
    }
    goto LABEL_38;
  }
  return a2;
}

明显是个base64编码,但码表不是默认的,而是通过第一个参数传入的,[@WP!3C75LfM8iwR2UO;(N>A6*&ut%#SIBhY1$j|kD{]0lx,.md9<4HayrzbXsg_
目标结果是*jmB*alk6A@.#Nsx*A%S#>NBt$Xd8P5HS2==
写一个base64解码过程就可以。
[C] 纯文本查看 复制代码
unsigned char revchar(char ch)
{
        for (int i = 0; i < 64; i++)
    {
        if (ch == charset[i])
            return i;
    }
    return 0;
}
size_t base64_decode(const char in[], unsigned char out[], size_t len)
{
    size_t idx, idx2, blks, blk_ceiling, left_over;

    if (in[len - 1] == '=')
        len--;
    if (in[len - 1] == '=')
        len--;

    blks = len / 4;
    left_over = len % 4;

    if (out == nullptr) {
        if (len >= 77 && in[NEWLINE_INVL] == '\n')   // Verify that newlines where used.
            len -= len / (NEWLINE_INVL + 1);
        blks = len / 4;
        left_over = len % 4;

        idx = blks * 3;
        if (left_over == 2)
            idx++;
        else if (left_over == 3)
            idx += 2;
    }
    else {
        blk_ceiling = blks * 4;
        for (idx = 0, idx2 = 0; idx2 < blk_ceiling; idx += 3, idx2 += 4) {
            if (in[idx2] == '\n')
                idx2++;
            out[idx] = (revchar(in[idx2]) << 2) | ((revchar(in[idx2 + 1]) & 0x30) >> 4);
            out[idx + 1] = (revchar(in[idx2 + 1]) << 4) | (revchar(in[idx2 + 2]) >> 2);
            out[idx + 2] = (revchar(in[idx2 + 2]) << 6) | revchar(in[idx2 + 3]);
        }

        if (left_over == 2) {
            out[idx] = (revchar(in[idx2]) << 2) | ((revchar(in[idx2 + 1]) & 0x30) >> 4);
            idx++;
        }
        else if (left_over == 3) {
            out[idx] = (revchar(in[idx2]) << 2) | ((revchar(in[idx2 + 1]) & 0x30) >> 4);
            out[idx + 1] = (revchar(in[idx2 + 1]) << 4) | (revchar(in[idx2 + 2]) >> 2);
            idx += 2;
        }
    }

    return(idx);
}


int main(int argc, char** argv) {
    system("chcp 65001");
        size_t decode_len = base64_decode("*jmB*alk6A@.#Nsx*A%S#>NBt$Xd8P5HS2==", NULL, 37);
        unsigned char* decode_buf = (unsigned char*)malloc(decode_len);
    if (decode_buf)
    {
        base64_decode("*jmB*alk6A@.#Nsx*A%S#>NBt$Xd8P5HS2==", decode_buf, 37);
printf("%s\n", decode_buf);
        free(decode_buf);
        }
    system("pause");
    return 0;
}


运行获得flag

本帖子中包含更多资源

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

x
LittleK 发表于 2026-3-5 23:07
本帖最后由 LittleK 于 2026-3-5 23:09 编辑

这个还有点难度
ZhangYixiSuccee 发表于 2026-3-6 09:19
大概是属于什么难度的题目,中级还是高级,太难就不搞了,没那水平
 楼主| onedayismyway 发表于 2026-3-6 09:21
ZhangYixiSuccee 发表于 2026-3-6 09:19
大概是属于什么难度的题目,中级还是高级,太难就不搞了,没那水平

初级高一点,中级够不上吧
lizongde 发表于 2026-3-7 00:11
谢谢楼主分享辛苦了&#128077;

免费评分

参与人数 1吾爱币 -15 违规 +1 收起 理由
bian96 -15 + 1 警告:CM区等技术板块禁止回复与主题无关非技术内容,违者重罚!

查看全部评分

您需要登录后才可以回帖 登录 | 注册[Register]

本版积分规则

返回列表

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

GMT+8, 2026-3-10 07:44

Powered by Discuz!

Copyright © 2001-2020, Tencent Cloud.

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