[DASCTF Sept 2021]easy_math


  1. IDA打開之后按下Shift + F12查找到字符串,識別了一些不尋常的字符串
    image

    定位到,並且得到基本偽代碼

    //...
      v3 = sub_41257C(std::cout, "Input:");
      std::ostream::operator<<(v3, sub_412572);
      do
      {
        v19 = std::istream::operator>>(std::cin, v30);
        if ( !(unsigned __int8)std::ios_base::operator bool(*(_DWORD *)(*(_DWORD *)v19 + 4) + v19) )
          break;
        sub_4121B7(v30);
      }
      while ( sub_411F28(v5, v11) != 5 );
      v29 = *(_QWORD *)sub_411F4B(1);
      v28 = *(_QWORD *)sub_411F4B(2);
      v27 = *(_QWORD *)sub_411F4B(3);
      v26 = *(_QWORD *)sub_411F4B(4) - 0x666C616755i64;
      v25 = sub_41218F(v26, HIDWORD(v26));
      if ( sub_411F28(v5, v11) == 5 )
      {
        if ( v29 - v25 == 0x61536369217Di64 )
        {
          if ( v28 - v25 == 0x586531316Fi64 )
          {
            if ( v27 - v25 == 0x5F3631626F4Ei64 )
            {
              if ( v25 + v27 + v28 + v29 == 0xC121F9FCC23Ai64 )
              {
    //...
    

    其中:

    • sub_41257C一定是輸出函數
    • std::istream::operator>>(std::cin, v30);等價於cin>>v30,這里是輸入數據(根據后面的動調可以看出)
    • sub_411F4B(1);是獲取輸入數據的某一行,其實是數組轉換函數

    要特別提出的是這四個方程:

      //...
      v26 = *(_QWORD *)sub_411F4B(4) - 0x666C616755i64;
      //...
        if ( v29 - v25 == 0x61536369217Di64 )
        {
          if ( v28 - v25 == 0x586531316Fi64 )
          {
            if ( v27 - v25 == 0x5F3631626F4Ei64 )
            {
              if ( v25 + v27 + v28 + v29 == 0xC121F9FCC23Ai64 )
       //...
    
  2. 首先對這四個常量重翻譯為字符串

    image

    接下來解下述方程,以滿足if條件(i64后綴代表字面值類型是__int64):

    v29 - v25 == 0x61536369217D
    v28 - v25 == 0x586531316F
    v27 - v25 == 0x5F3631626F4E
    v25 + v27 + v28 + v29 == 0xC121F9FCC23A
    

    解得(這里我對原函數進行了一下重寫,所以變量名稱更改了,但是順序還是對應的):

    v14 = 68719476736
    v16 = 104755080884046
    v17 = 448374321519
    v18 = 107079497490813
    

    使用__int64char腳本轉換上述幾個值:

    int main(int argc, char** argv)
    {
    	int v14[] = { 0x00,0x00,0x00,0x10,0x00,0x00,0x00,0x00 };
    	int v16[] = { 0x00,0x00,0x5f,0x46,0x31,0x62,0x6f,0x4e };
    	int v17[] = { 0x00,0x00,0x00,0x68,0x65,0x31,0x31,0x6f };
    	int v18[] = { 0x00,0x00,0x61,0x63,0x63,0x69,0x21,0x7d };
    	for (int i = 0; i < 5; i++)
    	{
    		printf("%c", v14[i]);
    	}
    	printf("\n");	
    	for (int i = 0; i < 5; i++)
    	{
    		printf("%c", v16[i]);
    	}
    	printf("\n");	
    	for (int i = 0; i < 5; i++)
    	{
    		printf("%c", v17[i]);
    	}
    	printf("\n");	
    	for (int i = 0; i < 5; i++)
    	{
    		printf("%c", v18[i]);
    	}
    	printf("\n");
    	return 0;
    }
    

    獲取字符串為:

    _F1
    he
    acc
    
  3. 合理補充、替換字符串:
    其實就是對應着判斷順序和變量順序將字符串拼出來

    Xe11o
    _61boN
    aSci!}
    flagU
    _F1
    he
    acc
    

    拼接,修正flag后面的U:
    flag{he11o_F1boNacci!}


免責聲明!

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



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