【伪随机数】【搜索】【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这个函数过后,我输入的字符串发生了有规律的改变: