010Editor漏洞分析

Windows

   此应用程序未加密,可以直接使用idapro或x64dbg进行调试。可以以一些常量字符串作为标志位,检查相关字符串引用的位置,并添加断点进行调试。经过一些调试可以找到下面的代码,这些代码是通过idapro反汇编出来的。

其中第一个if的位置调用了一个函数,这个函数其实就是检查授权的代码位置。

__int64 __fastcall sub_14036EDC0(__int64 a1, unsigned int a2)
{
  int v5; // eax
  int v6; // eax
  int v7; // eax
  unsigned int v8; // ecx
  int v9; // eax
  unsigned int v10; // ecx
  int v11; // eax
  unsigned int v12; // ecx

  if ( *(_DWORD *)(a1 + 60) )  // make this function always return 219 (0xdb)
    return 275i64;
  v5 = sub_1400060D2();
  switch ( v5 )
  {
    case 45:
      return 219i64; // single license 
    case 78:
      v11 = sub_1400091F1(a1, a2);
      v12 = 524;
      if ( v11 != 23 )
        return 237;
      return v12;
    case 231:
      return 375i64;
    default:
      v6 = sub_1400091F1(a1, a2);
      if ( v6 == 23 )
        return 113i64;
      if ( v6 != 42 )
      {
        if ( v6 == 312 )
        {
          v7 = sub_140005AB5(a1);
          v8 = 47;
          if ( v7 == 419 )
            return 249;
          return v8;
        }
        return 375i64;
      }
      v9 = sub_140005AB5(a1);
      v10 = 375;
      if ( v9 == 419 )
        return 249;
      return v10;
  }
}

再结合下面这个代码:

void *__fastcall sub_14036F180(__int64 a1, void *a2, int a3, int *a4, int a5, int a6)
{
  const char *v10; // rdx
  __int64 v11; // rdx
  int v12; // eax
  bool v13; // cf
  const struct QString *v14; // rax
  const struct QString *v15; // rbx
  const struct QString *v16; // rax
  int v17; // eax
  __int64 v18; // rdx
  const struct QString *v19; // rax
  const struct QString *v20; // rbx
  const struct QString *v21; // rax
  const char *v22; // rdx
  int v23; // r14d
  const struct QString *v24; // rax
  const struct QString *v25; // rbx
  const struct QString *v26; // rax
  char v28[8]; // [rsp+28h] [rbp-18h] BYREF
  char v29[8]; // [rsp+30h] [rbp-10h] BYREF
  char v30[8]; // [rsp+38h] [rbp-8h] BYREF

  QString::QString(a2);
  if ( a3 != 219 )  // previous function change a3 to 219, so next segment
  {
    if ( a3 == 47 )
    {
      QString::operator=(a2, "Evaluation Version\n");
      QString::operator+=(a2, "Clock Error");
      v17 = 30;
      goto LABEL_34;
    }
    if ( a3 == 113 )
    {
      v22 = "Evaluation Version\n";
    }
    else
    {
      if ( a3 != 524 )
      {
        if ( a3 == 249 )
        {
          QString::operator=(a2, "Evaluation Version\n");
          v18 = *(unsigned int *)(qword_140D64950 + 52);
          if ( (_DWORD)v18 == 1 )
          {
            QString::operator+=(a2, "1 Use Left");
          }
          else
          {
            v19 = (const struct QString *)QString::number(v29, v18, 10i64);
            v20 = QString::QString((QString *)v28, v19);
            v21 = (const struct QString *)QString::fromUtf8(v30, " Uses Left", 0xFFFFFFFFi64);
            QString::append((QString *)v28, v21);
            QString::~QString(v30);
            QString::append((QString *)a2, v20);
            QString::~QString(v28);
            QString::~QString(v29);
          }
          *a4 = 29;
          return a2;
        }
        if ( a3 == 237 )
        {
          QString::operator=(a2, "Upgrade Required\n");
          QString::operator+=(a2, "Evaluation Version Expired");
        }
        else
        {
          QString::operator=(a2, "Evaluation Version\n");
          QString::operator+=(a2, "Expired");
        }
        v17 = 30;
LABEL_34:
        *a4 = v17;
        return a2;
      }
      v22 = "Upgrade Required\n";
    }
    QString::operator=(a2, v22);
    v23 = *(_DWORD *)(qword_140D64950 + 40) - *(_DWORD *)(qword_140D64950 + 36);
    if ( v23 == 1 )
    {
      QString::operator+=(a2, "1 Day Left");
    }
    else
    {
      v24 = (const struct QString *)QString::number(v29, (unsigned int)v23, 10i64);
      v25 = QString::QString((QString *)v28, v24);
      v26 = (const struct QString *)QString::fromUtf8(v30, " Days Left", 0xFFFFFFFFi64);
      QString::append((QString *)v28, v26);
      QString::~QString(v30);
      QString::append((QString *)a2, v25);
      QString::~QString(v28);
      QString::~QString(v29);
      if ( v23 >= 30 )
        return a2;
    }
    v17 = 30 - v23;
    goto LABEL_34;
  }
  if ( a5 )
    QString::operator=(a2, "Licensed to:\n");
  QString::QString((QString *)v28, (const struct QString *)(qword_140D64950 + 8));
  QString::append((QString *)a2, (const struct QString *)v28);
  QString::~QString(v28);
  v10 = " - ";
  if ( !a6 )
    v10 = "\n";
  QString::operator+=(a2, v10);
  if ( *(_DWORD *)(a1 + 48) == 1 ) // change this code, make it always ++ (a2, "Single User License")....
  {
    QString::operator+=(a2, "Single User License");
    *a4 = 0;
  }
  else
  {
    v11 = *(unsigned int *)(qword_140D64950 + 48);
    v12 = 0;
    if ( *(_DWORD *)(qword_140D64950 + 44) == 1 )
      v13 = (unsigned int)v11 < 0x32;
    else
      v13 = (unsigned int)v11 < 0x3E8;
    LOBYTE(v12) = !v13;
    if ( v12 )
    {
      QString::operator+=(a2, "Site License");
    }
    else
    {
      v14 = (const struct QString *)QString::number(v30, v11, 10i64);
      v15 = QString::QString((QString *)v28, v14);
      v16 = (const struct QString *)QString::fromUtf8(v29, " User License", 0xFFFFFFFFi64);
      QString::append((QString *)v28, v16);
      QString::~QString(v29);
      QString::append((QString *)a2, v15);
      QString::~QString(v28);
      QString::~QString(v30);
    }
    *a4 = 0;
  }
  return a2;
}

 

因此直接将这个函数改成总是返回0xdb(219)就可以啦。

 

原版安装包下载地址:

链接: https://pan.baidu.com/s/1nM1p4YhYUHXVSsYx65NX2w?pwd=g58s 提取码: g58s 

 

MacOS

    macos下可以用hopper disassembler打开。根据windows的经验,可以直接搜索这个代码:

mov eax, 113 (B8 13 01 00 00)

    这个代码改成始终返回0xDB(219),这个id代表"Single User License"。

    查找字符串"Single User License",可以找到有两处引用它的地方,类似:

if ( *(_DWORD *)(a1 + 48) == 1 )
{
    QString::operator+=(a2, "Single User License");
    *a4 = 0;
}

     直接把这个改成if(true)。保存之后会破坏数字签名,建议直接把数字签名数据去除。

 mac原版下载:

链接: https://pan.baidu.com/s/14UidVR4hoMGGy3Wv_XlGiQ?pwd=b126 提取码: b126 

posted @ 2023-04-12 21:09  bodong  阅读(107)  评论(0编辑  收藏  举报