【伪随机数】【搜索】【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中括号里的内容了。

posted @ 2018-09-15 10:29  Reddest  阅读(1226)  评论(0编辑  收藏  举报