这道题提取码(cuiy)用到了:C++STL std::back_inserter back_inserter函数:配合copy函数,把[a, b)区间的数据插入到(string对象)的末尾,如果容量不够,动态扩容。
反编译之后的代码含有大量的STL语句,了解过STL vector大致用法后,可以理解:
输入16个数字:生成了16个斐波那契数:
v24begin经过加一操作后进行了transform函数:参数(v10,v9头尾指针,v25空容器)
进入函数:
就是一个从first-》last的循环,里面进行了lambda操作,进入lambda:
a1是输入的数据的第一个,a2是数据从第二个开始的指针,他两个值相加,就是说输入的16个数的每一位(从第二位开始,因为之前first+1)和第一位相加,返回结果。
第二个函数accumulate:参数(v24begin/end是输入的16个数,begin/end是经过transform后的16个数)
进入函数:
发现里面是对transform结果进行了操作,但具体是啥,有点复杂,里面有个copy函数:
上图是vector内std::begin、std::end的取值情况,copy函数总是将v24的最后一个元素复制到v25的第一个,然后返回最后一个元素pointer,之后更新v24end,再取最后一个的前一个,,,,,,,,
可以动态调试,直观:在accumulate函数后面下断点0x00400FF4:
b *0x0x00400FF4
x/10gx $rsp+0x90
0x7fffffffdff0: 0x0000000000618560 0x00000000006185a0
0x7fffffffe000: 0x00000000006185a0 0x00007ffff7b48ee6
0x7fffffffe010: 0x0000000000000000 0x0000000000000000
0x7fffffffe020: 0x0000000000000000 0x00007ffff7b492a0
0x7fffffffe030: 0x0000000000000000 0x0000000000000000
gdb-peda$ x/16wx 0x0000000000618560
0x618560: 0x00000011 0x00000010 0x0000000f 0x0000000e
0x618570: 0x0000000d 0x0000000c 0x0000000b 0x0000000a
0x618580: 0x00000009 0x00000008 0x00000007 0x00000006
0x618590: 0x00000005 0x00000004 0x00000003 0x00000001
可以看到数据都被反过来了
总结一下加密流程
1.接受16个数字输入
2.计算斐波那契数列前16项
3.把16个数字输入从第二个元素开始,都加上第一个元素
4.将3的结果反向
5.将4的结果和2的结果比较,完全相同则输入的是flag
所以最后脚本:
fib = [1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89, 144, 233, 377, 610, 987][::-1]
x = fib[0]
for i in range(1,len(fib)):
print (fib[i]-fib[0])
链接: 提取码:ryoh
知识:base58、base64
看到关键的比较函数:
经过排序可得到result结果是:D9cS9N9iHjMLTdA8YSMRMp
往上看,一大堆代码,不过result是经过V11索引在'123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz'中得到的,而v11是经过下图这个运算得到的
对输入的数据,进行了操作,有mod58 /58,而刚才的那张可见字符表很像base加密,这里又mod58,应该是base58,试着解密一下:
import base58 as bs
bs.b58decode('D9cS9N9iHjMLTdA8YSMRMp')
#output: base58_is_boring
得到flag。