DHCP
DHCP
Published on 2023-10-31 / 11 Visits
0
0

递归函数 异或 爆破推测数值

递归函数 异或 爆破推测数值

使用Exeinfo PE查看一下xysz.exe多少位

发现是64位,没有壳
用x64_ida打开看一下
找到主函数,查看一下伪代码

int __cdecl main(int argc, const char **argv, const char **envp)
{
  int v4; // ebx
  unsigned int v5; // eax
  unsigned __int8 cmp_data[41]; // [rsp+20h] [rbp-60h] BYREF
  unsigned int k; // [rsp+54h] [rbp-2Ch] BYREF
  int lenth; // [rsp+58h] [rbp-28h]
  int i; // [rsp+5Ch] [rbp-24h]

  _main(argc, argv, envp);
  qmemcpy(cmp_data, "\r\a", 2);
  cmp_data[2] = 29;
  cmp_data[3] = 37;
  cmp_data[4] = 29;
  cmp_data[5] = 110;
  cmp_data[6] = 48;
  cmp_data[7] = 57;
  cmp_data[8] = 44;
  cmp_data[9] = 63;
  cmp_data[10] = 42;
  cmp_data[11] = 43;
  cmp_data[12] = 50;
  cmp_data[13] = 63;
  cmp_data[14] = 42;
  cmp_data[15] = 55;
  cmp_data[16] = 110;
  cmp_data[17] = 48;
  cmp_data[18] = 48;
  cmp_data[19] = 48;
  cmp_data[20] = 48;
  cmp_data[21] = 45;
  cmp_data[22] = 1;
  cmp_data[23] = 7;
  cmp_data[24] = 49;
  cmp_data[25] = 43;
  cmp_data[26] = 1;
  cmp_data[27] = 57;
  cmp_data[28] = 31;
  cmp_data[29] = 59;
  cmp_data[30] = 45;
  cmp_data[31] = 45;
  cmp_data[32] = 27;
  cmp_data[33] = 58;
  cmp_data[34] = 1;
  cmp_data[35] = 12;
  qmemcpy(&cmp_data[36], "o96*#", 5);
  printf(&Format);
  scanf("%u", &k);
  if ( k <= 0x3E7 )
  {
    lenth = 41;
    puts(&Buffer);
    for ( i = 0; i < lenth; ++i )
    {
      v4 = cmp_data[i];
      v5 = result(k);
      printf("%c", v4 ^ (v5 % 0xD3));
    }
    return 0;
  }
  else
  {
    printf(&byte_40401C);
    return 0;
  }
}

发现定义了一个数组'cmp_data'先添加了"\r\a"又添加了33个数字后又添加了'o96*#'
所以总长度为41
scanf("%u", &k);
然后接收一个变量'k'
if ( k <= 0x3E7 )
判断k是否小于999
for ( i = 0; i < lenth; ++i )
开始循环41次
v4 = cmp_data[i]; v5 = result(k);
v4为cmp_data的i下标所对应的值,v5值为将'k'传入'result'的返回值
接下来查看'result'函数:

unsigned int __cdecl result(unsigned int k)
{
 if ( k )
   return result(k - 1) + k;
 else
   return 0;
}

可见'result'函数的函数的功能为将传入的'k'递归相加
printf("%c", v4 ^ (v5 % 0xD3));
然后先将v5于211求余后再于v4进行异或
所以我们可知,v4就是上面的数组循环的取值,v5为我们输入的数进行递归的值,但是v5又于211进行了一次求余,所以我们可知和v4求余的值肯定不会大于211。
所以我们现在的思路为循环211次再与v4进行异或来得到flag:
exp:

cmp_data=['' for i in range(41)]
cmp_data[0]=ord('\r')
cmp_data[1]=ord('\a')
cmp_data[2] = 29;
cmp_data[3] = 37;
cmp_data[4] = 29;
cmp_data[5] = 110;
cmp_data[6] = 48;
cmp_data[7] = 57;
cmp_data[8] = 44;
cmp_data[9] = 63;
cmp_data[10] = 42;
cmp_data[11] = 43;
cmp_data[12] = 50;
cmp_data[13] = 63;
cmp_data[14] = 42;
cmp_data[15] = 55;
cmp_data[16] = 110;
cmp_data[17] = 48;
cmp_data[18] = 48;
cmp_data[19] = 48;
cmp_data[20] = 48;
cmp_data[21] = 45;
cmp_data[22] = 1;
cmp_data[23] = 7;
cmp_data[24] = 49;
cmp_data[25] = 43;
cmp_data[26] = 1;
cmp_data[27] = 57;
cmp_data[28] = 31;
cmp_data[29] = 59;
cmp_data[30] = 45;
cmp_data[31] = 45;
cmp_data[32] = 27;
cmp_data[33] = 58;
cmp_data[34] = 1;
cmp_data[35] = 12;
cmp_data[36]=ord('o')
cmp_data[37]=9
cmp_data[38]=6
cmp_data[39]=ord('*')
cmp_data[40]=ord('#')
for i in range(211):
    for j in cmp_data:
        print(chr(j^i),end='')
    print(i)


所以当'k'=94,得到flag


Comment