zoukankan      html  css  js  c++  java
  • 【伪随机数】【搜索】【RE】【bugku】mountainclimbing WriteUp

    Mountain Climbing WP

      拿到题首先熟练地查个壳再用各种脱壳工具脱个壳。

      脱壳之后熟练地双击感受一下出题者的恶意:

      根据字面意思得知,是要根据一系列的操作来得到收益最大值,于是用ida打开并f5出来研究出题者是想让我们如何操作:

      76和82分别是“L”和“R”的ASCII码值,所以联想到操作只有左移和右移。在来看看这段代码的其他部分:

      这一部分相当于利用伪随机数构造了一个直角三角形的数表。由于是伪随机数,只要随机数种子srand()的值一样,构造出来的数表也是一样的。这里的随机数种子是srand(0xCu)也就是srand(12),自行写脚本构造出来一个一样的随机数表:

     

      这样就很明了了,题目意图是让我们从三角形数表的“山顶”开始一步步往下走,每次选择上一个节点的左子节点或右子节点下山,找出路线上所有数字和最大的那一条路线。于是利用随便一种搜索算法搜最优路线即可,这里用深度优先搜索举个例子:

      

     1 #include <cstdio>
     2 #include <ctime>
     3 #include <windows.h>
     4 using namespace std;
     5 int mt[100][100];
     6 int save[30],ans[30];
     7 int MAXN = -1;
     8 void dfs(int h,int l,int sum){
     9     sum += mt[h][l];
    10     if(h == 20){
    11         if(sum >= MAXN){
    12             MAXN = sum;
    13             memcpy(ans,save,sizeof(save));
    14         }
    15         return ;
    16     }
    17     save[h] = 0;
    18     dfs(h + 1,l,sum);
    19     save[h] = 1;
    20     dfs(h + 1,l + 1,sum);
    21 }
    22 int main(){
    23     srand(12);
    24     for(int i = 1;i <= 20;++i)
    25         for(int j = 1;j <= i;++j)
    26             mt[i][j] = rand() % 100000;
    27     dfs(1,1,0);
    28     for(int i = 1;i <= 19;++i)
    29         if(ans[i])
    30             printf("R");
    31         else printf("L");    
    32     return 0;
    33 }

      当我把搜索到的最优解输进去之后...

      嗯???error是什么情况???在反复确认搜索脚本无误后决定打开ollydbg一探究竟。在我试验性地输入字符串LLLLLLLLLLRRRRRRRRR后,字符串被原封不动的保存下来:

      

      而当我调试经过004114F这个函数过后,我输入的字符串发生了有规律的改变:

      

      再试验几个由“H”和“V”构成的字符串后发现,004114F这个加密函数是将偶数位的L与H互换,偶数位的R与V互换。于是将原来深搜的结果进行相应的转换,便是flag中括号里的内容了。

  • 相关阅读:
    初学Cocos2dx
    炸弹人NABCD分析
    求二维整数数组中最大联通子数组的和
    大道之简读书笔记1
    求首位相连二维数组最大子矩阵的和
    求首位相连一维数组最大子数组的和
    求二维数组最大子数组的和
    程序员修炼之道读后感3
    电梯调度需求分析
    课堂作业第四周课上作业二
  • 原文地址:https://www.cnblogs.com/reddest/p/9650175.html
Copyright © 2011-2022 走看看