攻防世界notesequence_018-n

ida反编译主函数
在这里插入图片描述

需要满足三个条件,两个check函数和最后的v2==20,第一个函数内容为

signed int __cdecl sub_80486CD(int a1)
{
  int j; // [esp+0h] [ebp-14h]
  int v3; // [esp+4h] [ebp-10h]
  int i; // [esp+8h] [ebp-Ch]
  int v5; // [esp+Ch] [ebp-8h]
 
  v5 = 0;
  for ( i = 0; i <= 1024 && *(_DWORD *)(4 * i + a1); i = v5 * (v5 + 1) / 2 )
  {
    v3 = 0;
    for ( j = 0; j <= v5; ++j )
      v3 += *(_DWORD *)(4 * (j + i) + a1);
    if ( 1 << v5 != v3 )
      return -1;
    ++v5;
  }
  return v5;
}

翻译成c++代码就是

int sub_80486CD(int a1[]) //传入的参数就是输入的数组
{
    int j;
    int v3;
    int i;
    int v5;
 
    v5=0;
    for(i=0;i<=1024&&a1[i];i=v5*(v5+1)/2)  //i的值就是前v5项和 0,1,3,...
    {
        v3=0;
        for(j=0;j<=v5;j++)
            v3+=a1[j+i];    //v3代表a1数组中第i项之后v5+1个数之和 sum(a1[i],a[i+1],...,a[i+v5])
        if(1<<v5 != v3)    //必须要满足2的v5次方==v3
            return -1;
        ++v5;              //v5的值  0,1,2,3,...
    }
    return v5;
}

这就可以分行看,当v5=0时,v3就等于a1[0],v5=1时,v3就等于a1[1]+a1[2],…

a[0]
a[1]+a[2]
a[3]+a[4]+a[5]
a[6]+a[7]+a[8]+a[9]

每一行的值都必须等于行号从0开始,2的行号次方,再看第二个函数

signed int __cdecl sub_8048783(int a1, signed int a2)
{
  int v3; // [esp+10h] [ebp-10h]
  int v4; // [esp+14h] [ebp-Ch]
  signed int i; // [esp+18h] [ebp-8h]
  int v6; // [esp+1Ch] [ebp-4h]
 
  v6 = 0;
  for ( i = 1; i < a2; ++i )
  {
    v4 = 0;
    v3 = i - 1;
    if ( !*(_DWORD *)(4 * i + a1) )
      return 0;
    while ( a2 - 1 > v3 )
    {
      v4 += *(_DWORD *)(4 * (v3 * (v3 + 1) / 2 + v6) + a1);
      ++v3;
    }
    if ( *(_DWORD *)(4 * (v3 * (v3 + 1) / 2 + i) + a1) != v4 )
      return 0;
    ++v6;
  }
  return 1;
}

翻译成c++代码

int sub_8048783(int a1[],int a2)
{
    int v3;
    int v4;
    int i;
    int v6;
 
    v6=0;
    for(i=1;i<a2;i++)
    {
        v4=0;
        v3=i-1;
        if(!a1[i])
            return 0;
        while(a2-1>v3)
        {
            v4+=a1[v3*(v3+1)/2+v6];
            ++v3;
        }
        if(a1[v3*(v3+1)/2+i]!=v4)
            return 0;
        ++v6;
    }
    return 1;
}

这里我们可以添加一些代码打印一下v4求和时a1的下标是哪些值

#include <iostream>
#include <string.h>
#include <algorithm>
#include <math.h>
#include <cstdio>
using namespace std;
int main()
{
    int a1[4000]={0};
    int a2=20;
    int v3;
    int v4;
    int i;
    int v6;
 
    v6=0;
    for(i=1;i<a2;i++)
    {
        v4=0;
        v3=i-1;
        if(!a1[i])
            //return 0;
        while(a2-1>v3)
        {
            v4+=a1[v3*(v3+1)/2+v6];
            cout<<v3*(v3+1)/2+v6<<endl;
            ++v3;
        }
        cout<<"\n判断时的下标为:"<<v3*(v3+1)/2+i<<endl<<endl;
        if(a1[v3*(v3+1)/2+i]!=v4){
            //return 0;
        }
        ++v6;
    }
    return 0;
}

在这里插入图片描述

这些数字乍看之下仿佛没什么规律,但如果我们像上面那样列一下就会发现规律,这里我们只列下标看

0 //0
1 2 //1
3 4 5 //2
6 7 8 9 //3

171 172 … 189 //18
190 191 192 … 209 //19
这里会发现要求就是每一列的和等于一列中最后一行斜下角(后一列,后一行)那个数字

两个要求都符合杨辉三角的性质(https://baike.baidu.com/item/%E6%9D%A8%E8%BE%89%E4%B8%89%E8%A7%92/215098?fr=aladdin 第11、12条)

在这里插入图片描述

在这里插入图片描述

判断条件v2==20的条件就是杨辉三角的层数等于20,最后附上生成输入的杨辉三角(无空格)的c++代码

#include <iostream>
#include <string.h>
#include <algorithm>
#include <math.h>
#include <cstdio>
using namespace std;
int main()
{
    int a[200][200]={0};
    int j=1;
    for(int i=1;i<=20;i++)
        a[i][1]=1;
    for(int i=2;i<=20;i++)
        for(int j=1;j<=i;j++)
            a[i][j]=a[i-1][j-1]+a[i-1][j];
    for(int i=1;i<=20;i++)
        for(int j=1;j<=i;j++)
            cout<<a[i][j];
    cout<<endl;
    return 0;
}

得到字符串

1111211331146411510105116152015611721353521711828567056288119368412612684369111045120210252210120451011115516533046246233016555111112662204957929247924952206612111378286715128717161716128771528678131114913641001200230033432300320021001364911411151054551365300350056435643550053003136545510515111612056018204368800811440128701144080084368182056012016111713668023806188123761944824310243101944812376618823806801361711181538163060856818564318244375848620437583182418564856830608161531811191719693876116282713250388755829237892378755825038827132116283876969171191

到md5在线网站加密一下,得到密文,包裹上RCTF{},得到flag:RCTF{37894beff1c632010dd6d524aa9604db}

————————————————
版权声明:本文为CSDN博主「臭nana」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/weixin_43784056/article/details/101153650

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值