西湖论剑初赛easyCpp探究

2019-04-22 约 1250 字 预计阅读 3 分钟

声明:本文 【西湖论剑初赛easyCpp探究】 由作者 ret2nullptr 于 2019-04-22 09:51:00 首发 先知社区 曾经 浏览数 14 次

感谢 ret2nullptr 的辛苦付出!

最近在学C++底层的相关知识,又拿出了当时西湖论剑初赛的easyCpp,当时做题的时候没做出来,再研究一下代码

另外感觉最近C++的逆向越来越多,不熟悉这块的话分析很费力,但熟悉之后大概就知道关键代码在哪了

静态分析

后来复现时发现动态调试很容易看出程序逻辑,不过有一点猜的成分,本文主要详细地进行静态分析

输入16个数

程序交互一开始输入16个数,然后把它们依次push_backvector input

程序中还有一个vector存了fib数列的前16项,fib就是普通的fibonacci数列

transform

接下来主要是一个std::transform,改了一下变量名

可以看到,主要是对vector input实施一个函数操作,从第二项(begin),到最后一项(end),都应用一个一元操作,并且将结果保存在vector v25中,命名为back_insert

模板声明如下:

template <class InputIterator, class OutputIterator, class UnaryOperation>
  OutputIterator transform (InputIterator first1, InputIterator last1,
                            OutputIterator result, UnaryOperation op);

点开可以看到一大堆iterator相关的代码,但关键是其中的lambda函数,也就是关键的一元操作

发现关键的lambda函数

其实只是做了一个简单的加法

也就是说,到这一步

输入的16个数字,后15个都加上了第一项,保存到v25这个vector中

accumulate

接下来的关键是std::accumulate,这是折叠函数,代码比较复杂

举个例子,用std::accumulate对一个vector求和,迭代器设置头尾,操作(函数)设置成加法,设定初始累加值为0,就会将整个vector加到累加值上

总之,std::accumulate是用来把这个数据集通过某一操作折叠起来获得结果的函数,可以加,可以乘,等等

不过这个accumulate中的函数看起来不太好理解...改一下变量名字

注意到std::copy,把begin到end都插入到result的尾部

变量a1result,因为是折叠函数,每次push_back当前数后,再把begin到end插入到尾部

再作为返回值返回result

也就是说,比如本来是1 2 3

第一轮就是简单的 push_back(1)

第二轮,vector一开始只有2,再copy上之前的1,就是2 1

第三轮,vector一开始是3,copy上之前的2 1,也就是3 2 1

这个accumulate实际上做的事是反转vector

自己写一个代码试一下

vec1 = std::accumulate(vec2.begin(), vec2.end(), std::vector<int>(),
        [](std::vector<int>acc, int num)->std::vector<int> {
        std::vector<int>result; result.push_back(num);
        std::copy(acc.begin(), acc.end(), std::back_inserter(__));
        return result;
    });

逻辑基本相同,测试结果也正是反转vector

解题

总结一下程序流程

  1. 输入16个数,后15个每个加上第一个数
  2. 16个数倒序后,要求相等fib数列的前16项

最后会通过std::copy_if输出我们输入的一部分数值

解题代码比较简单

#include<stdio.h>
#include<stdlib.h>

int fib(int n) {
    if (n == 0 || n == 1)return 1;
    else return fib(n - 1) + fib(n - 2);
}

int main(){
    for (int i = 15; i >= 0; i--){
        printf("%d ", fib(i) - fib(15));
    }
}

输入这16个数就得到了flag

题目的逻辑很简单,但是代码比较费解

甚至有一点...混淆的感觉?

还是得多熟悉C++

关键词:[‘安全技术’, ‘CTF’]

相关文章:


author

旭达网络

旭达网络技术博客,曾记录各种技术问题,一贴搞定.
本文采用知识共享署名 4.0 国际许可协议进行许可。

We notice you're using an adblocker. If you like our webite please keep us running by whitelisting this site in your ad blocker. We’re serving quality, related ads only. Thank you!

I've whitelisted your website.

Not now