飄云閣(PYG官方)

 找回密碼
 快速注冊

QQ登錄

只需一步,快速開始

查看: 1242|回復: 23
打印 上一主題 下一主題

[原創] Affinic Debugger純靜態分析編寫注冊機

  [復制鏈接]
  • TA的每日心情
    開心
    2020-1-1 17:46
  • 簽到天數: 6 天

    [LV.2]偶爾看看I

    跳轉到指定樓層
    樓主
    發表于 2019-12-13 21:25:46 | 只看該作者 |只看大圖 回帖獎勵 |倒序瀏覽 |閱讀模式
    本帖最后由 BinCrack 于 2019-12-13 21:28 編輯

    飄云閣全網首發,未經許可,禁止轉載。
    雙十二買了幾本書,其中一本書提到了gdb調試器得GUI前端工具——AffinicDebugger。用慣了OD、IDA等可視化界面得調試器,實在受不了命令行方式調試的gdb。另一個問題是IDA不支持安卓調試中設置硬件斷點,在修改內核標志后,gdb可以勝任設置硬件斷點得工作。于是花了半下午時間純靜態分析這款商業軟件得注冊機制,在完全不運行軟件的情況下,分析出軟件注冊邏輯,希望給不太了解IDA用法的朋友提供一點參考,起到拋磚引玉的作用。
    軟件界面如下,更多軟件介紹以及商業版(提供免費下載,正版授權七百人民幣)下載鏈接請自行瀏覽官網http://www.affinic.com/?page_id=109
    直接將主程序拖入IDA,通過字符串可以很快定位到關鍵驗證函數。

    接下來自然關注v13變量,sub_4766D0函數返回字符串‘001’即可成功。
    如上圖所示,而這個函數里面都是一堆偏移,因此需要借助IDA的結構體功能輔助我們靜態分析,這里僅以一處代碼為例。
    [C++] 純文本查看 復制代碼
    QDate::QDate(
            (QDate *)&v13,
            *(unsigned __int16 *)(v2 + 30),
            *(unsigned __int16 *)(v2 + 32),
            *(unsigned __int16 *)(v2 + 34));
    
    因此偏移30處為year變量,32處為month變量,34處為day變量。以此類推,根據瑣碎的上下文代碼邏輯,我們可以還原出整個結構體,這里直接給出全部結構體。
    還原出結構體后,IDA的F5偽代碼接近于源碼,可以與上圖未處理的對照,注釋很清楚,就不過多解釋了。
    接著是verifyDate函數,也沒什么好分析的,從sn中指定位置逐個獲取一個字符,最后用于日期以及上圖true,false變量的設置。
    [C++] 純文本查看 復制代碼
    int __thiscall verifyDate(myStruc *this, int a2)
    {
      myStruc *v2; // ebx
      char *v3; // esi
      char *v4; // eax
      char *v5; // eax
      char v6; // cl
      char *v7; // eax
      char v8; // cl
      char *v9; // eax
      char v10; // cl
      unsigned __int16 v11; // ax
      char *v12; // eax
      char v13; // cl
      unsigned __int16 v14; // ax
      char *v15; // eax
      char v16; // cl
      unsigned __int16 v17; // ax
      unsigned int year_l; // ebp
      char *v19; // eax
      char v20; // cl
      unsigned __int16 v21; // ax
      unsigned int year_h; // edi
      char v23; // al
      __int16 true_; // ax
      unsigned int day_h; // edx
      char day_l; // si
      unsigned int month_; // ecx
      unsigned __int16 v29; // [esp+14h] [ebp-2Ch]
      char v30; // [esp+1Ah] [ebp-26h]
      char sn; // [esp+1Ch] [ebp-24h]
      int false_; // [esp+20h] [ebp-20h]
      unsigned int month__; // [esp+24h] [ebp-1Ch]
      unsigned int day_h_; // [esp+28h] [ebp-18h]
      int day_l_; // [esp+2Ch] [ebp-14h]
      int v36; // [esp+30h] [ebp-10h]
      int v37; // [esp+3Ch] [ebp-4h]
    
      v2 = this;
      v3 = &this->sn;
      v36 = 0;
      QString::QString(&sn, &this->sn);
      v4 = *v3;
      v37 = 1;
      if ( *(v4 + 1) == '0' )
      {
        v5 = QString::at(&sn, &v30, 47);
        if ( *v5 <= 0xFFu )
        {
          v6 = *v5;
          if ( (*v5 - '0') <= 9u )
          {
            false_ = (v6 - '0');
    LABEL_6:
            QString::remove(&sn, 47, 1);
            v7 = QString::at(&sn, &v30, 39);
            if ( *v7 <= 0xFFu )
            {
              v8 = *v7;
              if ( (*v7 - 48) <= 9u )
              {
                day_l_ = (v8 - '0');
    LABEL_9:
                QString::remove(&sn, 39, 1);
                v9 = QString::at(&sn, &v30, 31);
                if ( *v9 <= 0xFFu )
                {
                  v10 = *v9;
                  if ( (*v9 - 48) <= 9u )
                  {
                    v11 = v10 - 48;
    LABEL_12:
                    day_h_ = v11;
                    QString::remove(&sn, 31, 1);
                    v12 = QString::at(&sn, &v30, 23);
                    if ( *v12 <= 0xFFu )
                    {
                      v13 = *v12;
                      if ( (*v12 - 48) <= 9u )
                      {
                        v14 = v13 - 48;
    LABEL_15:
                        month__ = v14;
                        QString::remove(&sn, 23, 1);
                        v15 = QString::at(&sn, &v30, 15);
                        if ( *v15 <= 0xFFu )
                        {
                          v16 = *v15;
                          if ( (*v15 - 48) <= 9u )
                          {
                            v17 = v16 - '0';
    LABEL_18:
                            year_l = v17;
                            QString::remove(&sn, 15, 1);
                            v19 = QString::at(&sn, &v30, 7);
                            if ( *v19 <= 0xFFu )
                            {
                              v20 = *v19;
                              if ( (*v19 - 48) <= 9u )
                              {
                                v21 = v20 - 48;
    LABEL_21:
                                year_h = v21;
                                QString::remove(&sn, 7, 1);
                                QString::at(&sn, &v29, 0);
                                QString::remove(&sn, 0, 1);
                                v23 = v29;
                                if ( v29 <= 0xFFu )
                                {
                                  if ( (v29 - 48) <= 9u )
                                  {
                                    true_ = v29 - 48;
                                    goto LABEL_24;
                                  }
                                }
                                else
                                {
                                  v23 = 0;
                                }
                                true_ = v23 - '7';
    LABEL_24:
                                day_h = day_h_;
                                day_l = day_l_;
                                v2->true = true_;
                                v2->false = false_;
                                month_ = month__;
                                v2->year = 16 * (year_h & 0xF) + 2010 + (year_l & 0xF);
                                v2->month = month_ & 0xF;
                                v2->day = (day_l & 0x1F) + 32 * (day_h & 0xF);
                                v2->field_26 = ((day_h >> 4) & 1)
                                             + ((month_ >> 3) & 2)
                                             + ((year_l >> 2) & 4)
                                             + ((year_h >> 1) & 8);
                                QString::QString(a2, &sn);
                                goto LABEL_25;
                              }
                            }
                            else
                            {
                              v20 = 0;
                            }
                            v21 = v20 - 55;
                            goto LABEL_21;
                          }
                        }
                        else
                        {
                          v16 = 0;
                        }
                        v17 = v16 - 55;
                        goto LABEL_18;
                      }
                    }
                    else
                    {
                      v13 = 0;
                    }
                    v14 = v13 - 55;
                    goto LABEL_15;
                  }
                }
                else
                {
                  v10 = 0;
                }
                v11 = v10 - 55;
                goto LABEL_12;
              }
            }
            else
            {
              v8 = 0;
            }
            day_l_ = (v8 - '7');
            goto LABEL_9;
          }
        }
        else
        {
          v6 = 0;
        }
        false_ = (v6 - 55);
        goto LABEL_6;
      }
      v2->true = 0;
      QString::QString(a2, &sn);
    LABEL_25:
      v36 = 1;
      LOBYTE(v37) = 0;
      QString::~QString(&sn);
      return a2;
    }
    接著分析最后一個函數finalEncrypt
    [C++] 純文本查看 復制代碼
    int __thiscall finalEncrypt(myStruc *this, int a2)
    {
      myStruc *v2; // ebp
      QString *email; // ebx
      int v4; // eax
      QString *name; // edi
      int v6; // eax
      int v7; // eax
      const struct QString *suc_001; // ebp
      int v9; // eax
      int v10; // eax
      int v11; // eax
      QString *v12; // eax
      QString *v13; // eax
      signed int cur; // edi
      __int16 v15; // si
      char *v16; // ebx
      unsigned int tmp; // eax
      char v18; // al
      int v20; // [esp+8Ch] [ebp-5Ch]
      char v21; // [esp+90h] [ebp-58h]
      char totalStr; // [esp+94h] [ebp-54h]
      int v23; // [esp+98h] [ebp-50h]
      int v24; // [esp+9Ch] [ebp-4Ch]
      const struct QString *fail_DG; // [esp+A0h] [ebp-48h]
      char v26; // [esp+A4h] [ebp-44h]
      char v27; // [esp+A8h] [ebp-40h]
      const struct QString *suc_001_; // [esp+ACh] [ebp-3Ch]
      int v29; // [esp+B0h] [ebp-38h]
      char v30[35]; // [esp+B4h] [ebp-34h]
      char v31; // [esp+D7h] [ebp-11h]
      int v32; // [esp+E4h] [ebp-4h]
    
      v2 = this;
      v24 = a2;
      v29 = a2;
      v23 = 0;
      QString::QString(&v21);
      email = &v2->email;
      v32 = 1;
      v4 = QString::trimmed(&v2->email, &v20);
      LOBYTE(v32) = 2;
      QString::operator=(&v2->email, v4);
      LOBYTE(v32) = 1;
      QString::~QString(&v20);
      name = &v2->name;
      v6 = QString::trimmed(&v2->name, &v20);
      LOBYTE(v32) = 3;
      QString::operator=(&v2->name, v6);
      LOBYTE(v32) = 1;
      QString::~QString(&v20);
      if ( *(v2->email + 4) && *(*name + 4) )
      {
        fail_DG = &v2->DG;
        v7 = QString::left(&v2->DG, &v20, 2);
        LOBYTE(v32) = 4;
        QString::operator=(&v2->DG, v7);
        LOBYTE(v32) = 1;
        QString::~QString(&v20);
        suc_001 = &v2->succeed;
        suc_001_ = suc_001;
        v9 = QString::left(suc_001, &v20, 3);
        LOBYTE(v32) = 5;
        QString::operator=(suc_001, v9);
        LOBYTE(v32) = 1;
        QString::~QString(&v20);
        while ( *(*name + 4) < 25 )
          QString::append(name, name);              // 將name擴展至25個字符
        v10 = QString::left(name, &v20, 25);
        LOBYTE(v32) = 6;
        QString::operator=(name, v10);
        LOBYTE(v32) = 1;
        QString::~QString(&v20);
        while ( *(*email + 4) < 40 )
          QString::append(email, email);            // 將email擴展至40個字符
        v11 = QString::left(email, &v20, 40);
        LOBYTE(v32) = 7;
        QString::operator=(email, v11);
        LOBYTE(v32) = 1;
        QString::~QString(&v20);
        v12 = sub_E63F90(&v27, fail_DG, name);      // 字符串拼接函數,將第二、三個參數拼接
        LOBYTE(v32) = 8;
        v13 = sub_E63F90(&v26, v12, suc_001_);      // 字符串拼接
        LOBYTE(v32) = 9;
        sub_E63F90(&totalStr, v13, email);          // 字符串拼接
        LOBYTE(v32) = 11;
        QString::~QString(&v26);
        LOBYTE(v32) = 12;
        QString::~QString(&v27);
        cur = 0;
        do
        {
          v15 = *QString::at(&totalStr, &fail_DG, cur);// 最終拼成了totalStr,為DG+name+001+email
          v16 = &v30[cur];
          tmp = ((v15 + *QString::at(&totalStr, &v20, &v30[cur + 35 - v30])) % 34);// (totalStr[cur]+totalStr[cur+35])%34
          if ( tmp >= 10 )
            v18 = tmp + 55;
          else
            v18 = tmp + 48;
          ++cur;
          *v16 = v18;
        }
        while ( cur < 35 );
        v31 = 0;
        QString::operator=(&v21, v30);
        v20 = QString::fromAscii_helper("-", 1);
        LOBYTE(v32) = 13;
        QString::insert(&v21, 30, &v20);            // 在指定位置插入‘-’
        LOBYTE(v32) = 12;
        QString::~QString(&v20);
        v20 = QString::fromAscii_helper("-", 1);
        LOBYTE(v32) = 14;
        QString::insert(&v21, 25, &v20);
        LOBYTE(v32) = 12;
        QString::~QString(&v20);
        v20 = QString::fromAscii_helper("-", 1);
        LOBYTE(v32) = 15;
        QString::insert(&v21, 20, &v20);
        LOBYTE(v32) = 12;
        QString::~QString(&v20);
        v20 = QString::fromAscii_helper("-", 1);
        LOBYTE(v32) = 16;
        QString::insert(&v21, 15, &v20);
        LOBYTE(v32) = 12;
        QString::~QString(&v20);
        v20 = QString::fromAscii_helper("-", 1);
        LOBYTE(v32) = 17;
        QString::insert(&v21, 10, &v20);
        LOBYTE(v32) = 12;
        QString::~QString(&v20);
        v20 = QString::fromAscii_helper("-", 1);
        LOBYTE(v32) = 18;
        QString::insert(&v21, 5, &v20);
        LOBYTE(v32) = 12;
        QString::~QString(&v20);
        QString::QString(v24, &v21);
        v23 = 1;
        LOBYTE(v32) = 1;
        QString::~QString(&totalStr);
      }
      else
      {
        QString::QString(v24, &v21);
        v23 = 1;
      }
      LOBYTE(v32) = 0;
      QString::~QString(&v21);
      return v24;
    }
    至此分析完畢,注冊成功效果圖。
    最后上注冊機源代碼
    [Python] 純文本查看 復制代碼
    # -*- coding: UTF-8 -*-
    name='bin'*25
    email='[email protected]'*40
    totalStr = 'DG' + name[:25] + '001' + email[:40]
    sn=[]
    for i in range(35):
        tmp = (ord(totalStr[i]) + ord(totalStr[i+35]))%34
        if tmp>=10:
            sn.append(chr(tmp + 55))
        else:
            sn.append(chr(tmp + 48))
    sn.insert(30,'-')
    sn.insert(25,'-')
    sn.insert(20,'-')
    sn.insert(15,'-')
    sn.insert(10,'-')
    sn.insert(5,'-')
    #固定到期時間
    sn.insert(0,'1')
    sn.insert(7,'4')
    sn.insert(15,'>')
    sn.insert(23,'8')
    sn.insert(31,'0')
    sn.insert(39,'8')
    sn.insert(47,'0')
    print "".join(sn)

    9.png (58.05 KB, 下載次數: 6)

    9.png

    評分

    參與人數 12威望 +25 飄云幣 +30 收起 理由
    gagmeng + 5 + 5 感謝發布原創作品,PYG有你更精彩!
    sw081 + 1 + 1
    gaosld + 1 + 1 感謝發布原創作品,PYG有你更精彩!
    cjteam + 1 + 1 PYG有你更精彩!
    Rooking + 5 + 10 原創精品 感謝分享!
    南柱赫 + 1 + 1 PYG有你更精彩!
    Dweling + 1 + 1 吃水不忘打井人,給個評分懂感恩!
    wkxq + 2 + 2 原創精品 感謝分享!
    llh001 + 1 + 1 PYG有你更精彩!
    samvon + 1 PYG有你更精彩!

    查看全部評分

    分享到:  QQ好友和群QQ好友和群 QQ空間QQ空間 騰訊微博騰訊微博 騰訊朋友騰訊朋友
    收藏收藏14 轉播轉播 分享分享 分享淘帖 頂1 踩 掃碼贊助微信 微信分享
  • TA的每日心情
    開心
    2020-2-13 00:57
  • 簽到天數: 19 天

    [LV.4]偶爾看看III

    藤椅
    發表于 2019-12-13 21:42:23 | 只看該作者
    學習學習,感謝分享
    回復 支持 反對

    使用道具 舉報

  • TA的每日心情
    擦汗
    13 小時前
  • 簽到天數: 81 天

    [LV.6]常住居民II

    板凳
    發表于 2019-12-13 21:49:32 | 只看該作者
    前來捧場哈哈
    回復 支持 反對

    使用道具 舉報

  • TA的每日心情
    無聊
    2019-12-27 22:14
  • 簽到天數: 10 天

    [LV.3]偶爾看看II

    報紙
    發表于 2019-12-13 22:50:59 | 只看該作者
    看著這分析確實非常流利呀
    回復 支持 反對

    使用道具 舉報

  • TA的每日心情
    開心
    2020-2-13 00:57
  • 簽到天數: 19 天

    [LV.4]偶爾看看III

    地板
    發表于 2019-12-13 23:09:55 | 只看該作者

    學習學習,感謝分享 ,頂頂更健康
    回復 支持 反對

    使用道具 舉報

  • TA的每日心情
    開心
    4 天前
  • 簽到天數: 831 天

    [LV.10]以壇為家III

    7#
    發表于 2019-12-14 11:31:59 | 只看該作者
    感謝分享 ,頂頂更健康
    回復 支持 反對

    使用道具 舉報

  • TA的每日心情
    開心
    3 天前
  • 簽到天數: 12 天

    [LV.3]偶爾看看II

    8#
    發表于 2019-12-14 14:20:20 | 只看該作者
    這個真是厲害,非常感謝
    回復 支持 反對

    使用道具 舉報

  • TA的每日心情
    奮斗
    前天 09:29
  • 簽到天數: 56 天

    [LV.5]常住居民I

    9#
    發表于 2019-12-14 15:23:01 | 只看該作者
    不明覺厲!飄云加油!
    回復 支持 反對

    使用道具 舉報

  • TA的每日心情
    奮斗
    13 小時前
  • 簽到天數: 563 天

    [LV.9]以壇為家II

    10#
    發表于 2019-12-14 18:32:04 | 只看該作者
    學習了,感謝分享!
    回復 支持 反對

    使用道具 舉報

    您需要登錄后才可以回帖 登錄 | 快速注冊

    本版積分規則

    關閉

    站長推薦上一條 /1 下一條

    小黑屋|手機版|Archiver|飄云閣安全論壇 ( 粵ICP備15107817號-2 )|掃碼贊助

    Powered by Discuz! X3.3© 2001-2017 Comsenz Inc.

      
    快速回復 返回頂部 返回列表
    北单赔率为什么高