0x15 Simple-machine

Author Avatar
张Mini Nov 21, 2018
  • Read this article on other devices

Simple-machine

纯靠自己硬怼。。。。

扔进IDA后发现输入flag进入两个函数后进行比较

sub_8048633

  • 修改后的伪代码如下,最开始前面的函数没想到是什么意思,后来联想汇编时函数进行的那几个操作才恍然小悟。。。脑子不够用于是一条一条备注
  • 函数大概进行的操作就是将输入与字符串进行input[i] ^ text[i % len(text)]的操作
int __cdecl sub_8048633(int input, unsigned int len)
{
  unsigned int v2; // eax
  int v3; // eax

  push(ebp_);
  ebp_ = esp_;
  push(n1);
  push(n2);
  esp_ -= 48;                                    //开辟一个栈空间
  *(_DWORD *)(ebp_ - 29) = 'deef';
  *(_DWORD *)(ebp_ - 25) = 'daed';
  *(_DWORD *)(ebp_ - 21) = 'feeb';
  *(_DWORD *)(ebp_ - 17) = 'efac';
  *(_BYTE *)(ebp_ - 13) = 0;
  for ( *(_DWORD *)(ebp_ - 12) = 0; ; ++*(_DWORD *)(ebp_ - 12) )      //循环len(input)次
  {
    n_i = *(_DWORD *)(ebp_ - 12);               //n_i = *(ebp_ - 12)
    if ( n_i >= len )                           //判断n_i和len
      break;
    i = *(_DWORD *)(ebp_ - 12);                 //i = *(ebp_ - 12)
    n_i = input;                                //n_i = &input
    n1 = i + input;                             //n1 = &input[i]
    i = *(_DWORD *)(ebp_ - 12);                 //i = *(ebp_ - 12)
    n_i = i + input;                            //n_i = &input[i]
    n_i = *(unsigned __int8 *)(i + input);      //n_i = input[i]
    bt_64 = n_i;                                //bt_64 = input[i]
    *(_BYTE *)(ebp_ - 41) = n_i;                //*(ebp_ - 41)=input[i]
    n2 = *(_DWORD *)(ebp_ - 12);                //n2 = *(ebp_ - 12)
    esp_ -= 12;                                 //esp -= 12
    n_i = ebp_ - 29;                            //n_i = &(ebp_ - 29)
    push(ebp_ - 29);                            //把字符串入栈
    v2 = strlen(*(const char **)esp_);          //v2 = len(esp_)
    esp_ += 16;                                 //esp_ += 16
    dd_48 = v2;                                 //dd_48 = len(esp_)
    n_i = n2;                                   //n_i = *(ebp_ - 12)
    i = 0;                                      //i = 0
    sub_80485AB(v2);                            //len(esp_)
{ unsigned int result; // eax

  i = n_i % v2;                                 //i = *(ebp_ - 12) % len(esp_)
  result = n_i / v2;                            //result = *(ebp - 12) / len(esp_)
  n_i /= v2;                                    //*(ebp - 12) /= len(esp_)
  return result;
}
    n_i = i;
    n_i = *(unsigned __int8 *)(i - 29 + ebp_);  //text[i%len(text)]
    bt_64 = n_i;                                //bt_64 = text[i%len(text)]
    bt_64 = *(_BYTE *)(ebp_ - 41) ^ n_i;        //bt_64=input[i] ^ text[i%len(text)]
    *(_BYTE *)n1 = bt_64;                       //n1 = input[i] ^ text[i % len(text)]
    v3 = n_i;
    LOBYTE(v3) = 0;
    n_i = v3 + (unsigned __int8)bt_64;
  }
  sub_80485A5();
  esp_ = ebp_ - 8;
  pop(&n2);
  pop(&n1);
  return pop(&ebp_);
}

sub_80488C7

  • 这个函数有两层循环,里面循环的次数在循环中可以找到,最开始一直不知道len(input)的长度,还尝试爆破。。。后来才发现已经给出了len的长度。。。得到内循环的次数18
  • 其次这个函数的功能就是置换,前一个函数对输入的flag进行加密后,进入这个函数置换后放入新的空间里最后进行比较
int __cdecl sub_80488C7(int input, int flag_en, int len)
{
  sub_8048567(ebp_);
  ebp_ = esp_;
  esp_ -= 16;
  for ( *(_DWORD *)i = 0; *(_DWORD *)i <= 2u; ++*(_DWORD *)i )          //for(i = 0;i <= 2;i ++)   外循环两次 
  {
    for ( *(_DWORD *)j = 0; ; ++*(_DWORD *)j )                          //for(j = 0;;j++)
    {
      dd_48 = len;                                                      //dd_48 = len
      dd_4C = 1431655766;                                               //dd_4C = 1431655766
      dd_40 = len;                                                      //dd_40 = len
      sub_80485DB(1431655766);
      {
     __int64 result; // rax

        dd_4C = (unsigned __int64)(a1 * (signed __int64)dd_40) >> 32;   //dd_4C = (1431655766 * len) >> 32
        result = (unsigned int)(a1 * dd_40);                            //result = 1431655766 * len
        dd_40 *= a1;                                                    //dd_40 = len * 1431655766
        return result;                                                  //return result
        }
      dd_4C -= (unsigned int)dd_48 >> 31;                               //dd_4C = ((1431655766 * len) >> 32) - (len >> 31)
      dd_40 = dd_4C;                                                    //dd_40 =  ((1431655766 * len) >> 32) - (len >> 31)
      if ( *(_DWORD *)j >= (unsigned int)dd_4C )                        //j >= 18 说明内层循环18次
        break;
      dd_48 = len;                                                      //dd_48 = len
      dd_4C = 1431655766;                                               //dd_4C = 1431655766
      dd_40 = len;                                                      //dd_40 = len
      sub_80485DB(1431655766);
      {
        __int64 result; // rax

        dd_4C = (unsigned __int64)(a1 * (signed __int64)dd_40) >> 32;   //dd_4C = (1431655766 * len) >> 32
        result = (unsigned int)(a1 * dd_40);                            //result = 1431655766 * len
        dd_40 *= a1;                                                    //dd_40 = len * 1431655766
        return result;                                                  //return result
        }
      dd_4C -= (unsigned int)dd_48 >> 31;                               //dd_4C = ((1431655766 * len) >> 32) - (len >> 31) = 18
      dd_40 = dd_4C;                                                    //dd_40 = 18
      dd_40 = dd_4C * *(_DWORD *)i;                                     //dd_40 = 18*i
      dd_4C = dd_40;                                                    //dd_4C = dd_40
      dd_40 = *(_DWORD *)j;                                             //dd_40 = j
      dd_40 += dd_4C;                                                   //dd_40 = j + 18*i
      dd_4C = dd_40;                                                    //dd_4C = dd_40
      dd_40 = flag_en;                                                  //dd_40 = flag_en
      dd_48 = dd_4C + flag_en;                                          //dd_48 = flag_en[j+18*i]
      dd_4C = *(_DWORD *)j;                                             //dd_4C = j
      dd_40 = 2 * dd_4C;                                                //dd_40 = 2*j
      dd_4C *= 3;                                                       //dd_4C = j*3
      dd_40 = *(_DWORD *)i;                                             //dd_40 = i
      dd_40 += dd_4C;                                                   //dd_40 = i+j*3
      dd_4C = dd_40;                                                    //dd_4C = i+j*3
      dd_40 += input;                                                   //dd_40 = input[i+3*j]
      dd_40 = *(unsigned __int8 *)(input + dd_4C);                      //dd_40 = input[i+3*j]
      byte_804B164 = dd_40;                                             //bt = input[i+3*j]
      *(_BYTE *)dd_48 = dd_40;                                          //dd_48 = input[i+3*j]
    }                                                                   //flag_en[j+18*i] = input[i+3*j]
  }
}

脚本

flag_en=[0,3,9,58,5,14,2,22,15,31,18,86,59,11,81,80,57,0,9,31,80,4,20,87,59,18,7,60,28,58,21,5,11,8,6,1,4,18,22,57,5,11,80,87,9,18,10,39,19,23,14,2,85,24]
text="feeddeadbeefcafe"
flag_en0=[0]*54
flag=""
for i in range(0,3):
    for j in range(0,18):
        flag_en0[i+3*j] = flag_en[18*i+j]
for i in range(0,54):
    flag+=chr(ord(text[i%len(text)])^flag_en0[i])
print(flag)