zzhwaxy 发表于 2020-5-14 22:19

一个娱乐向CM

本帖最后由 zzhwaxy 于 2020-5-15 10:43 编辑

## 娱乐向CM

闲着无聊,写了一个CM。

是用VC++6.0编译的win32控制台程序。



## 题目本身并没有难度

感兴趣的可以来挑战一下。

如果做出来了可以分享一下你的答案。

GOOD LUCK!


---

分割线

---


## 下面介绍一下我的设计思路和开放源代码

平时做逆向题目的时候,总会碰到各种循环,所以我就利用跳转难以读懂的特性,稍微动了点手脚。

### 程序的流程

以输入的字符串长度作为switch分支语句的入口点。

难点在于字符串长度不知道,难以预测一开始走的是哪一个。

对每一位输入做判断,每一个判断有两个跳转。

这里使用了 count 来验证最后的跳转。

考虑不周,存在多解的情况。

### 源代码

```c
#include<stdio.h>
#include<string.h>
int main()
{
int len;
int i=0,count=0;
char name;
printf("Please input key:\n");
scanf("%s",name);

len=strlen(name);
if(len<0 || len > 10 )
    {
    goto end;
    }

switch(len){
case 0:
Label0:
    if(name=='z')
      {
      i++;
      count-=1;
      goto Label1;
      }else if(name=='q')
      {
      i++;
      count+=1;
      goto Label2;
      }
case 1:
Label2:

    if(name=='w')
      {
      i++;
      count+=2;
      goto Label3;
      }else if(name=='r')
      {
      i++;
      count+=1;
      goto Label4;
      }
case 2:
Label4:
    if(name=='x')
      {
      i++;
      count+=1;
      goto Label5;
      }else if(name=='e')
      {
      i++;
      count+=4;
      goto Label6;
      }
case 3:
Label6:
   
    if(name=='!')
      {
      i++;
      count+=1;
      goto Label7;
      }else if(name=='+')
      {
      i++;
      count+=1;
      goto Label0;
      }
case 4:
Label8:
    if(count==9)
    {
                printf("Success!");
          getchar();
                getchar();
                return 0;
        }
    else
        {
      getchar();
          getchar();
          printf("Failed");
          break;
        }
   
case 5:
Label7:

    if(name=='<')
      {
      i++;
      count-=1;
      goto Label8;
      }else if(name=='+')
      {
      i++;
      count+=1;
      goto Label2;
      }
case 6:
Label5:
    if(name=='y')
      {
      i++;
      count+=1;
      goto Label6;
      }else if(name=='p')
      {
      i++;
      count+=1;
      goto Label7;
      }
case 7:
Label3:
    if(name=='a')
      {
      i++;
      count+=3;
      goto Label4;
      }else if(name=='x')
      {
      i++;
      count+=2;
      goto Label5;
      }
case 8:
Label1:
    if(name=='h')
      {
      i++;
      count+=2;
      goto Label2;
      }else if(name=='r')
      {
      i++;
      count+=1;
      goto Label3;
      }
case 9:
    if(name=='z')
      {
      i++;
      count+=1;
    goto Label0;
      }
    else if(name=='/')
      {
      i++;
      goto Label1;
      count-=1;
      }
    break;
   


}
end:
printf("Failed");
getchar();
getchar();
return 0;
}

```

玖公子 发表于 2020-5-15 10:05

本帖最后由 玖公子 于 2020-5-15 10:08 编辑

赤座灯里 发表于 2020-5-14 22:52
#include
#include


大佬太强了,我OD跟了半天,没找出正确的流程,用了你的,发现成功了。
flag是9位数:zzhwaxy!<



0040119F|>837D F4 09    cmp ,0x9;判断长度是否等于9
004011A3|. |0F85 A5000000 jnz trick.0040124E
004011A9|. |68 24504200   push trick.00425024                      ;Success!
004011AE|. |E8 CD080000   call trick.00401A80

玖公子 发表于 2020-5-15 09:53



我以为码追出来了,然后发现不对,必须要取9个字符出来......,找不到正确的流程,只能爆破了!

赤座灯里 发表于 2020-5-14 22:52

本帖最后由 赤座灯里 于 2020-5-15 02:17 编辑

#include <stdio.h>
#include <string.h>

int main() {
    char input;
    int ret;
    int i;
    int len;
    i = 0;
    ret = 0;
    printf("Please input key:\n");
    scanf("%s", input);
    len = strlen(input);
    if (len < 0 || len > 10) {
      LABEL_56:
      printf("Failed");
      return 0;
    }
    switch (len) {
      case 0:
            goto LABEL_5;
      case 1:
            goto LABEL_9;
      case 2:
            goto LABEL_13;
      case 3:
            goto LABEL_17;
      case 4:
            goto LABEL_21;
      case 5:
            goto LABEL_36;
      case 6:
            goto LABEL_40;
      case 7:
            goto LABEL_44;
      case 8:
            goto LABEL_48;
      case 9:
            break;
      default:
            goto LABEL_56;
    }
    while (input != 'z') {
      if (input != '/')
            goto LABEL_56;
      ++i;
      while (1) {
            LABEL_48:
            if (input == 'h') {
                ++i;
                ret += 2;
                goto LABEL_9;
            }
            if (input != 'r')
                break;
            ++i;
            ++ret;
            LABEL_44:
            if (input == 'a') {
                ++i;
                ret += 3;
                goto LABEL_13;
            }
            if (input == 'x') {
                ++i;
                ret += 2;
                LABEL_40:
                while (input != 'y') {
                  if (input != 'p')
                        goto LABEL_44;
                  ++i;
                  ++ret;
                  LABEL_36:
                  if (input == '<') {
                        --ret;
                        goto LABEL_21;
                  }
                  if (input == '+') {
                        ++i;
                        ++ret;
                        goto LABEL_9;
                  }
                }
                ++i;
                ++ret;
                goto LABEL_17;
            }
      }
    }
    ++i;
    ++ret;
    while (1) {
      LABEL_5:
      if (input == 'z') {
            ++i;
            --ret;
            goto LABEL_48;
      }
      if (input == 'q') {
            ++i;
            ++ret;
      }
      LABEL_9:
      if (input == 'w') {
            ++i;
            ret += 2;
            goto LABEL_44;
      }
      if (input == 'r') {
            ++i;
            ++ret;
      }
      LABEL_13:
      if (input == 'x') {
            ++i;
            ++ret;
            goto LABEL_40;
      }
      if (input == 'e') {
            ++i;
            ret += 4;
      }
      LABEL_17:
      if (input == '!') {
            ++i;
            ++ret;
            goto LABEL_36;
      }
      if (input != '+')
            break;
      ++i;
      ++ret;
    }
    LABEL_21:
    if (ret != 9) {
      printf("Failed");
      goto LABEL_56;
    }
    printf("Success!");
    return 0;
}
zzhwaxy
flag是猜的,不会去除这种控制流混淆。
这种东西写起来确实不难,按正确逻辑走一遍就行,逆起来就头疼了

jiaocoll 发表于 2020-5-15 00:11

1.

2.

zzhwaxy 发表于 2020-5-15 07:27

赤座灯里 发表于 2020-5-14 22:52
#include
#include



离正确答案很接近了,但是还差一点

xiaohong 发表于 2020-5-15 09:58

支持一下,加密了的,一般复制不了

sadamo 发表于 2020-5-15 10:15

太好了,只需要这个

zzhwaxy 发表于 2020-5-15 11:03

玖公子 发表于 2020-5-15 10:05
大佬太强了,我OD跟了半天,没找出正确的流程,用了你的,发现成功了。
flag是9位数:zzhwaxy!<



没想到你们这么快就解出来了。

不过,那个9其实是用来验证结果的,只是为了降低难度,刚巧和字符串长度一致。

源代码我已经在上面开放了。

赤座灯里 发表于 2020-5-15 11:47

zzhwaxy 发表于 2020-5-15 07:27
离正确答案很接近了,但是还差一点

按长度匹配必然导致多解,除非成功的逻辑和其他有明显差异
页: [1] 2
查看完整版本: 一个娱乐向CM