这题很好玩。首先是PEID查壳,32位的无壳程序,拖入IDA,找到关键代码
```

char *sub_401020()
{
  char *result; // eax@19
  char v1; // [sp+Ch] [bp-110h]@1
  char v2; // [sp+4Ch] [bp-D0h]@11
  char *v3; // [sp+50h] [bp-CCh]@1
  char v4; // [sp+54h] [bp-C8h]@1
  char v5; // [sp+5Dh] [bp-BFh]@1
  char v6; // [sp+94h] [bp-88h]@15
  char v7; // [sp+98h] [bp-84h]@1
  char v8; // [sp+99h] [bp-83h]@1
  __int16 v9; // [sp+10Dh] [bp-Fh]@1
  char v10; // [sp+10Fh] [bp-Dh]@1
  char v11; // [sp+110h] [bp-Ch]@11
  char v12; // [sp+114h] [bp-8h]@5
  int v13; // [sp+118h] [bp-4h]@4

  memset(&v1, 0xCCu, 0x110u);
  v7 = 0;
  memset(&v8, 0, 0x74u);
  v9 = 0;
  v10 = 0;
  qmemcpy(&v4, "********* *    ** * ** ** * ** ** * #* ** **** **      *********", 0x41u);
  v3 = &v5;
  printf("Please input your key:\n");
  gets(&v7);
  if ( strlen(&v7) != 22 )                      // 长度为22
  {
    printf("Sorry you are wrong!\n");
    system("pause");
    exit(1);
  }
  v13 = 0;
  do
  {
    v12 = *(&v7 + v13);
    if ( v12 != 107 && v12 != 106 && v12 != 104 && v12 != 108 )  // 只能输入这几个数
    {
      printf("Sorry you are wrong!\n");
      system("pause");
      exit(2);
    }
    v11 = *(&v7 + v13);
    v2 = v11;
    // 不同的输入对应不同的走法
    if ( v11 == 104 )
    {
      if ( --v3 < &v4 || v3 > &v6 || (result = (char *)*v3, result == (char *)42) )
      {
        printf("Sorry you are wrong!\n");
        system("pause");
        exit(3);
      }
      if ( *v3 == 35 )
      {
LABEL_41:
        printf("Good!\n");
        system("pause");
        exit(0);
      }
    }
    else if ( v2 == 106 )
    {
      v3 += 8;
      if ( v3 < &v4 || v3 > &v6 || *v3 == 42 )
      {
        printf("Sorry you are wrong!\n");
        system("pause");
        exit(3);
      }
      result = (char *)*v3;
      if ( result == (char *)35 )
        goto LABEL_41;
    }
    else if ( v2 == 107 )
    {
      v3 -= 8;
      if ( v3 < &v4 || v3 > &v6 || *v3 == 42 )
      {
        printf("Sorry you are wrong!\n");
        system("pause");
        exit(3);
      }
      result = v3;
      if ( *v3 == 35 )
        goto LABEL_41;
    }
    else
    {
      if ( ++v3 < &v4 || v3 > &v6 || *v3 == 42 )
      {
        printf("Sorry you are wrong!\n");
        system("pause");
        exit(4);
      }
      result = v3;
      if ( *v3 == 35 )
        goto LABEL_41;
    }
    ++v13;
  }
  while ( v13 < 25 );
  return result;
}
上面的代码首先给出了一段字符`********* *    ** * ** ** * ** ** * #* ** **** **      *********`,现在要求输入一段字符串,只能包含四种字符,分别是`h`,`j`,`k`,`l`,长度是22位。这四种字符都对应一种走法。现在我们的起始地址在第十位,要求通过这几种走法,不可以经过`*`,走到`#`,我们要找的就是这样一种走法。可以通过深度优先搜索解决(DFS),遍历所有可能走法,最后跳出一种满足条件的走法,给出代码
#include <iostream> 
#include <stdio.h> 
#include <string> 
#include <string.h> 
using namespace std; 
char  num[25]; 
int dfsmap[70]={1,1,1,1,1,1,1,1,1,0,1,0,0,0,0,1,1,0,1,0,1,1,0,1,1,0,1,0,1,1,0,1,1,0,1,0,0,1,0,1,1,0,1,1,1,1,0,1,1,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1}; 
void dfs(int x,int sumn) 
{ 
    int i,j,k; 
    if(sumn==22) 
    { 
        if(x==36) // 满足条件就输出 
        { 
           for(i=0;i<=21;i++) 
           { 
               cout<<num[i]; 
           } 
           cout<<endl; 
        } 
        return; 
    } 
    // 四种走法 
    if(x-1>=0&&dfsmap[x-1]!=1) 
    { 
        num[sumn]='h'; 
        dfs(x-1,sumn+1); 
        num[sumn]=0; 
    } 
    if(x+8<=63&&dfsmap[x+8]!=1) 
    { 
        num[sumn]='j'; 
        dfs(x+8,sumn+1); 
        num[sumn]=0; 
    } 
    if(x-8>=0&&dfsmap[x-8]!=1) 
    { 
        num[sumn]='k'; 
        dfs(x-8,sumn+1); 
        num[sumn]=0; 
    } 
    if(x+1<=63&&dfsmap[x+1]!=1) 
    { 
        num[sumn]='l'; 
        dfs(x+1,sumn+1); 
        num[sumn]=0; 
    } 
    return; 
} 
int main() 
{ 
    dfs(9,0); 
    return 0; 
} 

Flag:

温馨提示: 此处内容需要评论本文后刷新才能查看,支付2元即可直接查看所有Flag。

小广告:关于获取西普实验吧所有Writeup请点击这里查看索引

查看所有Flag需要付费,需要获取所有Flag的童鞋请访问这里成为付费用户,可以自助把自己的注册邮箱加入网站白名单,即可免回复看到本站所有Flag

Flag大全地址:所有Flag

PS:本站不是实验吧的官方站点,纯粹是个人博客,收取Flag费用仅是维持服务器费用,做站不易,且行窃珍惜,如果喜欢我的博客,愿意捐赠的,可以扫描下面的二维码

微信二维码:
支付宝二维码:
打赏
  • 打赏支付宝扫一扫
  • 打赏微信扫一扫