BUUCTF CrackMe


這道題寫了我將近一周。。還是看着別人博客寫了一周才搞懂的,犯了幾個錯誤:1.沒看題目,2.沒清楚什么樣的代碼是調試

所以看這道題之前先看這個wiki里的前置知識:https://wiki.x10sec.org/reverse/anti-debug/example/了解調試代碼

 

 然后檢查下有沒有加殼,檢查完后發現沒有。

在運行一下這個程序看看,從而做出一些判斷,和通過字符串找到程序入口

 

 打開ida分析

 

 通過分析代碼結構和程序流程可以知道,需要讓代碼中的死循環跳出,那么sub_401830和loc_4011a0需要成立的,但是loc_4011a0這個函數的參數都是0,所以這個函數是不需要去分析的

而其他幾個函數,是檢查字母和數字的,但這個函數時給byte_416050賦值的。

 打開sub_401830函數

 

 該函數是否成功,再於v14是否等於43924,所以打開sub_401470函數

_DWORD *__usercall sub_401470@<eax>(int a1@<ebx>, _BYTE *a2, _DWORD *a3)
{
  int v3; // ST28_4
  int v4; // ecx
  int v6; // edx
  int v8; // ST20_4
  int v9; // eax
  int v10; // edi
  int v11; // ST1C_4
  int v12; // edx
  char v13; // di
  int v14; // ST18_4
  int v15; // eax
  int v16; // ST14_4
  int v17; // edx
  char v18; // al
  int v19; // ST10_4
  int v20; // ecx
  int v23; // ST0C_4
  int v24; // eax
  _DWORD *result; // eax
  int v26; // edx

  if ( *a2 == 100 )
  {
    *a3 |= 4u;
    v4 = *a3;
  }
  else
  {
    *a3 ^= 3u;
  }
  v3 = *a3;
  if ( a2[1] == 98 )
  {
    _EAX = a3;
    *a3 |= 0x14u;
    v6 = *a3;
  }
  else
  {
    *a3 &= 0x61u;
    _EAX = (_DWORD *)*a3;
  }
  __asm { aam }
  if ( a2[2] == 97 )
  {
    *a3 |= 0x84u;
    v9 = *a3;
  }
  else
  {
    *a3 &= 0xAu;
  }
  v8 = *a3;
  v10 = ~(a1 >> -91);
  if ( a2[3] == 112 )
  {
    *a3 |= 0x114u;
    v12 = *a3;
  }
  else
  {
    *a3 >>= 7;
  }
  v11 = *a3;
  v13 = v10 - 1;
  if ( a2[4] == 112 )
  {
    *a3 |= 0x380u;
    v15 = *a3;
  }
  else
  {
    *a3 *= 2;
  }
  v14 = *a3;
  if ( *(_DWORD *)(*(_DWORD *)(__readfsdword(0x30u) + 24) + 12) != 2 )
  {
    if ( a2[5] == 102 )
    {
      *a3 |= 0x2DCu;
      v17 = *a3;
    }
    else
    {
      *a3 |= 0x21u;
    }
    v16 = *a3;
  }
  if ( a2[5] == 115 )
  {
    *a3 |= 0xA04u;
    v18 = (char)a3;
    v20 = *a3;
  }
  else
  {
    v18 = (char)a3;
    *a3 ^= 0x1ADu;
  }
  v19 = *a3;
  _AL = v18 - v13;
  __asm { daa }
  if ( a2[6] == 101 )
  {
    *a3 |= 0x2310u;
    v24 = *a3;
  }
  else
  {
    *a3 |= 0x4Au;
  }
  v23 = *a3;
  if ( a2[7] == 99 )
  {
    result = a3;
    *a3 |= 0x8A10u;
    v26 = *a3;
  }
  else
  {
    *a3 &= 0x3A3u;
    result = (_DWORD *)*a3;
  }
  return result;
}

可以知道這個函數是如果a2滿足所有的if就可以成立,v14也就可以等於43924

所以其值為b=[0x64,0x62,0x61,0x70,0x70,0x73,0x65,0x63]

所以我們知道了v17的值,但需要求v17的值是如何來的

在接着往上看,

 

 這里有兩個反調試的代碼,如果在調試就進行一些別的操作,否則直接讓byte_416050和v15這個字符串進行異或。

接着往上看

 

 也有反調試的代碼,顯然這一部分與密碼有關,並且通過最后一個if可以發現這是將兩個字符串進行合並為一個,第一個if是將字符數轉換為整型數,第二個我沒搞明白是什么意思,但第三個是將字母變成0-15的數字,所以我們可以推測,密碼是字母0-15和數字0-9組成的。例如密碼是"0a",經過合並后就會變為一個字符為'0a'

所以我們只需要求v17對byte_416050這個字符串的異或了,通過動態調試,我們可以知道byte_416050的值為a=[0x2a,0xd7,0x92,0xe9,0x53,0xe2,0xc4,0xcd],與其做異或得出的值就是密碼。

 

 一開始沒看題目,帶了個12345678進去,然后.......解出來了,但不符合題意。。。

得到密碼后,在進行md5 32位小寫加密就行了


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM