PEDIY Crackme 競賽 2007---第一回

    閒來無事,就找看雪2007Crackeme比賽的Crackme來練習一下~~~函數

    拿到的第一個程序,「crackme_by_topmint.exe」,首先打開它熟悉一下。調試

    

    

連續輸入2次,獲得以上結果,咱們能夠得知,key的格式必須爲xxxx-xxxx-xxxx-xxxx-xxxx-xxxx-xxxx-xxxx,以及一些提示字符串。code

    既然有了提示,那麼就用IDA尋找一下String的位置。字符串

    

運氣挺好,在String-View中直接獲得明文提示,轉到IDA-View中,Ctrl+x回溯,往上滑動幾下後來到關鍵函數StartAddress(),嘗試F5分析一波~~~class

    

DWORD __stdcall StartAddress(LPVOID lpThreadParameter)
{
  HWND v1; // eax@1
  int len_of_name; // ebx@1
  HWND v4; // eax@3
  int len_of_serial; // ebp@3
  HWND v6; // eax@5
  HWND v7; // eax@5
  int sum_of_char; // edx@5
  int j; // ecx@5
  CHAR x; // al@6
  signed int i; // edx@13
  const CHAR *v12; // [sp-Ch] [bp-11Ch]@25
  HWND v13; // [sp-8h] [bp-118h]@4
  const CHAR *v14; // [sp-8h] [bp-118h]@25
  CHAR name[256]; // [sp+10h] [bp-100h]@1
  __int16 v16; // [sp+10Ch] [bp-4h]@1
  char v17; // [sp+10Eh] [bp-2h]@1

  EnableWindow(hWnd, 0);
  memset(name, 0, 0xFCu);
  v16 = 0;
  v17 = 0;
  v1 = GetDlgItem(hDlg, 1000);
  len_of_name = GetWindowTextLengthA(v1);
  if ( (unsigned int)len_of_name > 0xFF )                    //name長度和255比較,大於則彈出錯誤提示
  {
    MessageBoxA(hDlg, aTheLengthOfThe, aError, 0x10u);
    EnableWindow(hWnd, 1);
    return 0;
  }
  v4 = GetDlgItem(hDlg, 1001);
  len_of_serial = GetWindowTextLengthA(v4);
  if ( len_of_serial )                                 //serial不爲空
  {
    v6 = GetDlgItem(hDlg, 1000);
    GetWindowTextA(v6, name, 255);
    v7 = GetDlgItem(hDlg, 1001);
    GetWindowTextA(v7, String, 100);
    sum_of_char = 0;
    j = 0;
    if ( len_of_name <= 0 )                         //serial長度小於等於0
    {
LABEL_13:
      for ( i = sum_of_char + 1; i > 7040; i >>= 2 )
        ;
      dword_40AAB0 = i;
      //進行serial格式對比
      if ( len_of_serial == 39
        && byte_40AA08 == '-'
        && byte_40AA0D == '-'
        && byte_40AA12 == '-'
        && byte_40AA17 == '-'
        && byte_40AA1C == '-'
        && byte_40AA21 == '-'
        && byte_40AA26 == '-' )
      {
        sub_401640();
        if ( dword_40AAB0 == dword_40AB5C )       //關鍵比較
        {
          MessageBoxA(hDlg, aWelcomeToHarbi, aWelcome, 0x40u);
          v13 = hWnd;
        }
        else
        {
          MessageBoxA(hDlg, aTryAgainNeverG, aSorry, 0x10u);
          v13 = hWnd;
        }
        goto LABEL_29;
      }
      v14 = aError;
      v12 = aTheKeyMustBeXx;
    }
    else
    {
      while ( 1 )
      {
        //x遍歷name,累加到sum_of_char
        x = name[j];
        if ( (x < '0' || x > '9') && (x < 'A' || x > 'Z') && (x < 'a' || x > 'z') )
          break;
        sum_of_char += x;
        //當遍歷name完成,則跳轉到LABEL_13
        if ( ++j >= len_of_name )
          goto LABEL_13;
      }
      v14 = aError;
      v12 = aTheNameContain;
    }
    MessageBoxA(hDlg, v12, v14, 0x10u);
    v13 = hWnd;
  }
  else
  {
    MessageBoxA(hDlg, aPleaseInputThe, aError, 0x10u);
    v13 = hWnd;
  }
LABEL_29:
  EnableWindow(v13, 1);
  return 0;
}

F5分析得已經很明顯了。程序首先判斷name長度是否超過255,不超過則遍歷name將其中的字符累加到sum_of_char中,而後跳轉到LABEL_13。LABEL_13中,首先賦值i=sum_of_char+1,若是i>7040,i=i/4,不然i不變。接下來,將i賦值給dword_40AAB0,再進行serial格式判斷,若是serial格式合格,最後再判斷dword_40AAB0==dword_40AB5C,等於則成功。變量

    由以上分析可知,咱們目前不知道的是dword_40AB5C這個變量,因此上(OD)動態調試觀察此處。遍歷

能夠清楚的看到,通過004017ED   .  E8 4EFEFFFF   call crackme_.00401640以後,40AB5C=0x1B80(7040),而40AAB0處依然是「Fucker」的累加之和+1---0x261。綜上,最後須要name的累加之和=7039。程序

    因此,得出一組code,name:xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxOim

                                       serial:1234-1234-1234-1234-2134-8520-7894-9632(serial隨意)call

相關文章
相關標籤/搜索