[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!}

posted @ 2021-09-25 21:35  二氢茉莉酮酸甲酯  阅读(191)  评论(0编辑  收藏  举报