新160个crackme - 016-fty_crkme3

运行分析

在这里插入图片描述

  • 需要输入calc计算结果

PE分析

在这里插入图片描述

  • upx壳,32位

在这里插入图片描述

  • upx -d fty_crkme3.exe脱壳

在这里插入图片描述

  • 重新查壳,发现是Delphi程序

静态分析&动态调试

在这里插入图片描述

  • ida找到关键字符串,进入函数

int sub_444B30()
{
  int v0; // edx
  int i; // ebx
  unsigned __int8 v2; // al
  char *v3; // edx
  int v4; // eax
  int v5; // ebx
  int v6; // ecx
  int v7; // ecx
  int v8; // ecx
  int v9; // ecx
  int v10; // ecx
  int v11; // ecx
  int v12; // esi
  int v13; // eax
  int v14; // edi
  int v15; // eax
  int v16; // edi
  int v17; // eax
  int v18; // edi
  int v19; // eax
  int v20; // edi
  int v21; // eax
  int v22; // edi
  int v23; // eax
  int v24; // edi
  int v25; // eax
  int v26; // ecx
  int v27; // ecx
  int v28; // ecx
  int v29; // ecx
  int v30; // ecx
  int v31; // ecx
  int v32; // ecx
  int v33; // esi
  int v34; // eax
  int v35; // edi
  int v36; // eax
  int v37; // edi
  int v38; // eax
  int v39; // edi
  int v40; // eax
  int v41; // edi
  int v42; // eax
  int v43; // edi
  int v44; // eax
  int v45; // edi
  int v46; // eax
  int v47; // edi
  int v48; // eax
  int v49; // ecx
  int v50; // ecx
  int v51; // ecx
  int v52; // ecx
  int v53; // ecx
  int v54; // ecx
  int v55; // ecx
  int v56; // ecx
  int v57; // esi
  int v58; // eax
  int v59; // edi
  int v60; // eax
  int v61; // edi
  int v62; // eax
  int v63; // edi
  int v64; // eax
  int v65; // edi
  int v66; // eax
  int v67; // edi
  int v68; // eax
  int v69; // edi
  int v70; // eax
  int v71; // edi
  int v72; // eax
  int v73; // edi
  int v74; // eax
  unsigned int v76[2]; // [esp-Ch] [ebp-D0h] BYREF
  int *v77; // [esp-4h] [ebp-C8h]
  int v78; // [esp+Ch] [ebp-B8h] BYREF
  int v79; // [esp+10h] [ebp-B4h] BYREF
  int v80; // [esp+14h] [ebp-B0h] BYREF
  int v81; // [esp+18h] [ebp-ACh] BYREF
  int v82; // [esp+1Ch] [ebp-A8h] BYREF
  int v83; // [esp+20h] [ebp-A4h] BYREF
  int v84; // [esp+24h] [ebp-A0h] BYREF
  int v85; // [esp+28h] [ebp-9Ch] BYREF
  int v86; // [esp+2Ch] [ebp-98h] BYREF
  unsigned __int8 v87[12]; // [esp+30h] [ebp-94h] BYREF
  int v88; // [esp+3Ch] [ebp-88h] BYREF
  int v89; // [esp+40h] [ebp-84h] BYREF
  int v90; // [esp+44h] [ebp-80h] BYREF
  int v91; // [esp+48h] [ebp-7Ch] BYREF
  int v92; // [esp+4Ch] [ebp-78h] BYREF
  int v93; // [esp+50h] [ebp-74h] BYREF
  int v94; // [esp+54h] [ebp-70h] BYREF
  int v95; // [esp+58h] [ebp-6Ch] BYREF
  int v96; // [esp+5Ch] [ebp-68h] BYREF
  unsigned __int8 v97[12]; // [esp+60h] [ebp-64h] BYREF
  int v98; // [esp+6Ch] [ebp-58h] BYREF
  int v99; // [esp+70h] [ebp-54h] BYREF
  int v100; // [esp+74h] [ebp-50h] BYREF
  int v101; // [esp+78h] [ebp-4Ch] BYREF
  int v102; // [esp+7Ch] [ebp-48h] BYREF
  int Serial_4; // [esp+80h] [ebp-44h] BYREF
  int Serial_2; // [esp+84h] [ebp-40h] BYREF
  int Serial_1; // [esp+88h] [ebp-3Ch] BYREF
  unsigned __int8 v106[8]; // [esp+8Ch] [ebp-38h] BYREF
  char v107[8]; // [esp+94h] [ebp-30h] BYREF
  char v108[8]; // [esp+9Ch] [ebp-28h] BYREF
  char v109[8]; // [esp+A4h] [ebp-20h] BYREF
  char v110[4]; // [esp+ACh] [ebp-18h] BYREF
  char v111; // [esp+B0h] [ebp-14h] BYREF
  char v112; // [esp+B1h] [ebp-13h]
  char v113[4]; // [esp+B4h] [ebp-10h] BYREF
  char v114; // [esp+B8h] [ebp-Ch] BYREF
  char v115; // [esp+B9h] [ebp-Bh]
  int System__AnsiString; // [esp+BCh] [ebp-8h] BYREF
  char *v117; // [esp+C0h] [ebp-4h]
  int savedregs; // [esp+C4h] [ebp+0h] BYREF

  v77 = &savedregs;
  v76[1] = (unsigned int)&loc_445382;
  v76[0] = (unsigned int)NtCurrentTeb()->NtTib.ExceptionList;
  __writefsdword(0, (unsigned int)v76);
  TControl::GetText(*(TControl **)(dword_447844 + 720));
  if ( v117 )
  {
    for ( i = 1; i <= length((int)v117); ++i )
    {
      if ( v117[i - 1] != '-' )                 // Serial的每一位是-或者数字[0-9]
      {
        v2 = v117[i - 1];
        if ( v2 < '0' )
          goto LABEL_23;
        v3 = v117;
        if ( v2 > '9' )
          goto LABEL_23;
      }
    }
    v4 = length((int)v117);
    v5 = v4;
    if ( v4 < 9 || v4 > 11 )                    // Serial长度为9-11
      goto LABEL_23;
    if ( v4 != 9 )                              // Serial为10-11时跳转
      goto LABEL_28;
    if ( v117[2] != '-' || v117[6] != '-' )     // Serial的第3位和第7为必须是-
      goto LABEL_23;
    v115 = *v117;
    v114 = 1;
    setstr(v113, &v114);
    v112 = v117[1];
    v111 = 1;
    LOBYTE(v6) = 2;
    System::__linkproc__ PStrNCat(v113, &v111, v6);
    setstr(v110, v113);
    v112 = v117[3];
    v111 = 1;
    LOBYTE(v7) = 3;
    System::__linkproc__ PStrNCat(v110, &v111, v7);
    setstr(v109, v110);
    v112 = v117[4];
    v111 = 1;
    LOBYTE(v8) = 4;
    System::__linkproc__ PStrNCat(v109, &v111, v8);
    setstr(v108, v109);
    v112 = v117[5];
    v111 = 1;
    LOBYTE(v9) = 5;
    System::__linkproc__ PStrNCat(v108, &v111, v9);
    setstr(v107, v108);
    v112 = v117[7];
    v111 = 1;
    LOBYTE(v10) = 6;
    System::__linkproc__ PStrNCat(v107, &v111, v10);
    setstr((char *)v106, v107);
    v112 = v117[8];
    v111 = 1;
    LOBYTE(v11) = 7;
    System::__linkproc__ PStrNCat(v106, &v111, v11);// 上面一系列操作就是将输入的Serial去除-
    copy(&System__AnsiString, v106);
    v12 = Sysutils::StrToInt(System__AnsiString);// str转int,v12 = Serial去除'-'后的16进制数
    v5 = 7;
    first_byte((int)&Serial_1);                 // 取第一位的值
    v13 = Sysutils::StrToInt(Serial_1);
    v14 = pow_Serial_i__5(v13, 7);              // v14 = Serial_2的7次方,以下是一样的
    first_byte((int)&Serial_2);                 // 取第二位的值
    v15 = Sysutils::StrToInt(Serial_2);
    v16 = pow_Serial_i__5(v15, 7) + v14;
    first_byte((int)&Serial_4);                 // 取第四位的值
    v17 = Sysutils::StrToInt(Serial_4);
    v18 = pow_Serial_i__5(v17, 7) + v16;
    first_byte((int)&v102);                     // 取第五位的值
    v19 = Sysutils::StrToInt(v102);
    v20 = pow_Serial_i__5(v19, 7) + v18;
    first_byte((int)&v101);                     // 取第六位的值
    v21 = Sysutils::StrToInt(v101);
    v22 = pow_Serial_i__5(v21, 7) + v20;
    first_byte((int)&v100);                     // 取第八位的值
    v23 = Sysutils::StrToInt(v100);
    v24 = pow_Serial_i__5(v23, 7) + v22;
    first_byte((int)&v99);                      // 取第九位的值
    v25 = Sysutils::StrToInt(v99);
    if ( v12 != pow_Serial_i__5(v25, 7) + v24 ) // 必须跳转
    {
LABEL_28:
      if ( v5 != 10 )
        goto LABEL_19;
      if ( v117[2] != 45 || v117[6] != 45 )
        goto LABEL_23;
      v115 = *v117;
      v114 = 1;
      setstr(v113, &v114);
      v112 = v117[1];
      v111 = 1;
      LOBYTE(v26) = 2;
      System::__linkproc__ PStrNCat(v113, &v111, v26);
      setstr(v110, v113);
      v112 = v117[3];
      v111 = 1;
      LOBYTE(v27) = 3;
      System::__linkproc__ PStrNCat(v110, &v111, v27);
      setstr(v109, v110);
      v112 = v117[4];
      v111 = 1;
      LOBYTE(v28) = 4;
      System::__linkproc__ PStrNCat(v109, &v111, v28);
      setstr(v108, v109);
      v112 = v117[5];
      v111 = 1;
      LOBYTE(v29) = 5;
      System::__linkproc__ PStrNCat(v108, &v111, v29);
      setstr(v107, v108);
      v112 = v117[7];
      v111 = 1;
      LOBYTE(v30) = 6;
      System::__linkproc__ PStrNCat(v107, &v111, v30);
      setstr((char *)v106, v107);
      v112 = v117[8];
      v111 = 1;
      LOBYTE(v31) = 7;
      System::__linkproc__ PStrNCat(v106, &v111, v31);
      setstr((char *)v97, v106);
      v112 = v117[9];
      v111 = 1;
      LOBYTE(v32) = 8;
      System::__linkproc__ PStrNCat(v97, &v111, v32);
      copy(&v98, v97);
      v33 = Sysutils::StrToInt(v98);
      v5 = 8;
      first_byte((int)&v96);
      v34 = Sysutils::StrToInt(v96);
      v35 = pow_Serial_i__5(v34, 8);
      first_byte((int)&v95);
      v36 = Sysutils::StrToInt(v95);
      v37 = pow_Serial_i__5(v36, 8) + v35;
      first_byte((int)&v94);
      v38 = Sysutils::StrToInt(v94);
      v39 = pow_Serial_i__5(v38, 8) + v37;
      first_byte((int)&v93);
      v40 = Sysutils::StrToInt(v93);
      v41 = pow_Serial_i__5(v40, 8) + v39;
      first_byte((int)&v92);
      v42 = Sysutils::StrToInt(v92);
      v43 = pow_Serial_i__5(v42, 8) + v41;
      first_byte((int)&v91);
      v44 = Sysutils::StrToInt(v91);
      v45 = pow_Serial_i__5(v44, 8) + v43;
      first_byte((int)&v90);
      v46 = Sysutils::StrToInt(v90);
      v47 = pow_Serial_i__5(v46, 8) + v45;
      first_byte((int)&v89);
      v48 = Sysutils::StrToInt(v89);
      if ( v33 != pow_Serial_i__5(v48, 8) + v47 )
      {
LABEL_19:
        if ( v5 != 11 )
          goto LABEL_23;
        if ( v117[3] != 45 )
          goto LABEL_23;
        if ( v117[7] != 45 )
          goto LABEL_23;
        v115 = *v117;
        v114 = 1;
        setstr(v113, &v114);
        v112 = v117[1];
        v111 = 1;
        LOBYTE(v49) = 2;
        System::__linkproc__ PStrNCat(v113, &v111, v49);
        setstr(v110, v113);
        v112 = v117[2];
        v111 = 1;
        LOBYTE(v50) = 3;
        System::__linkproc__ PStrNCat(v110, &v111, v50);
        setstr(v109, v110);
        v112 = v117[4];
        v111 = 1;
        LOBYTE(v51) = 4;
        System::__linkproc__ PStrNCat(v109, &v111, v51);
        setstr(v108, v109);
        v112 = v117[5];
        v111 = 1;
        LOBYTE(v52) = 5;
        System::__linkproc__ PStrNCat(v108, &v111, v52);
        setstr(v107, v108);
        v112 = v117[6];
        v111 = 1;
        LOBYTE(v53) = 6;
        System::__linkproc__ PStrNCat(v107, &v111, v53);
        setstr((char *)v106, v107);
        v112 = v117[8];
        v111 = 1;
        LOBYTE(v54) = 7;
        System::__linkproc__ PStrNCat(v106, &v111, v54);
        setstr((char *)v97, v106);
        v112 = v117[9];
        v111 = 1;
        LOBYTE(v55) = 8;
        System::__linkproc__ PStrNCat(v97, &v111, v55);
        setstr((char *)v87, v97);
        v112 = v117[10];
        v111 = 1;
        LOBYTE(v56) = 9;
        System::__linkproc__ PStrNCat(v87, &v111, v56);
        copy(&v88, v87);
        v57 = Sysutils::StrToInt(v88);
        first_byte((int)&v86);
        v58 = Sysutils::StrToInt(v86);
        v59 = pow_Serial_i__5(v58, 9);
        first_byte((int)&v85);
        v60 = Sysutils::StrToInt(v85);
        v61 = pow_Serial_i__5(v60, 9) + v59;
        first_byte((int)&v84);
        v62 = Sysutils::StrToInt(v84);
        v63 = pow_Serial_i__5(v62, 9) + v61;
        first_byte((int)&v83);
        v64 = Sysutils::StrToInt(v83);
        v65 = pow_Serial_i__5(v64, 9) + v63;
        first_byte((int)&v82);
        v66 = Sysutils::StrToInt(v82);
        v67 = pow_Serial_i__5(v66, 9) + v65;
        first_byte((int)&v81);
        v68 = Sysutils::StrToInt(v81);
        v69 = pow_Serial_i__5(v68, 9) + v67;
        first_byte((int)&v80);
        v70 = Sysutils::StrToInt(v80);
        v71 = pow_Serial_i__5(v70, 9) + v69;
        first_byte((int)&v79);
        v72 = Sysutils::StrToInt(v79);
        v73 = pow_Serial_i__5(v72, 9) + v71;
        first_byte((int)&v78);
        v74 = Sysutils::StrToInt(v78);
        if ( v57 != pow_Serial_i__5(v74, 9) + v73 )
        {
LABEL_23:
          Dialogs::ShowMessage((Dialogs *)&str_Nope__Your_calc[1], (const int)v3);// 失败弹窗
          goto LABEL_25;
        }
      }
    }
    Dialogs::ShowMessage((Dialogs *)&str_Good_boy__Now_f[1], (const int)v3);// 成功弹窗
    goto LABEL_25;
  }
  Dialogs::ShowMessage((Dialogs *)&str_Hey__loggerhead[1], v0);// 提示未输入弹窗
LABEL_25:
  __writefsdword(0, v76[0]);
  v77 = (int *)&loc_445389;
  unknown_libname_29(&v78, 9);
  unknown_libname_29(&v88, 9);
  unknown_libname_29(&v98, 8);
  return unknown_libname_29(&System__AnsiString, 2);
}
  • 通过静态分析,想要跳转到成功,if ( v12 != pow_Serial_i__5(v25, 7) + v24 )处必须跳转
  • Serial必须是9位,第3位和第7位是’-',其他是数字

在这里插入图片描述
在这里插入图片描述

  • 通过动态调试发现,System__AnsiString的值是输入Serial去除-后的字符串
  • v12为System__AnsiString转int

在这里插入图片描述
在这里插入图片描述

  • 动调unknown_libname_32函数,发现是取System__AnsiString第n个值传入相应地址

int __fastcall sub_444B20(int result, int a2)
{
  int v2; // ecx
  bool v3; // cc
  int v4; // edx
  int v5; // edx

  v2 = result;
  v3 = a2 < 2;
  v4 = a2 - 2;
  if ( !v3 )
  {
    v5 = v4 + 1;
    do
    {
      result *= v2;
      --v5;
    }
    while ( v5 );
  }
  return result;
}
  • 解析sub_444B20()函数,发现是对输入的数字进行7次方运算

  • 通过以上分析,得到以下结论
  • 一、Serial必须是9位,第3位和第7位是’-',其他是数字
  • 二、v12为Serial去除’-'后的int值
  • 三、Serial每个数字7次方相加的值,要等于v12

算法分析

Serial = ''

for Serial_byte1 in range(0, 10):
    for Serial_byte2 in range(0, 10):
        for Serial_byte4 in range(0, 10):
            for Serial_byte5 in range(0, 10):
                for Serial_byte6 in range(0, 10):
                    for Serial_byte8 in range(0, 10):
                        for Serial_byte9 in range(0, 10):
                            Serial = str(Serial_byte1) + str(Serial_byte2) + '-' + str(Serial_byte4) + str(Serial_byte5) + str(Serial_byte6) + '-' + str(Serial_byte8) + str(Serial_byte9)

                            System__AnsiString = Serial.replace('-','')     # 去除-
                            v12 = hex(int(System__AnsiString))[2:]      # 转16进制数

                            v12_cmp = 0
                            for i in range(len(System__AnsiString)):
                                v12_cmp += pow(int(System__AnsiString[i]),7)        # 7次方
                            v12_cmp = hex(v12_cmp)[2:]

                            if v12 == v12_cmp:
                                print(Serial)

在这里插入图片描述
在这里插入图片描述

  • 运行算法脚本,发现有多个解,一一验证均成功
  • 7
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值