原题

文件为.c文本文件:

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

int main(int argc, char *argv[]) {
    if (argc != 4) {
        printf("what?\n");
        exit(1);
    }

    unsigned int first = atoi(argv[1]);
    if (first != 0xcafe) {
        printf("you are wrong, sorry.\n");
        exit(2);
    }

    unsigned int second = atoi(argv[2]);
    if (second % 5 == 3 || second % 17 != 8) {
        printf("ha, you won't get it!\n");
        exit(3);
    }

    if (strcmp("h4cky0u", argv[3])) {
        printf("so close, dude!\n");
        exit(4);
    }

    printf("Brr wrrr grr\n");

    unsigned int hash = first * 31337 + (second % 17) * 11 + strlen(argv[3]) - 1615810207;

    printf("Get your key: ");
    printf("%x\n", hash);
    return 0;
}

答案

c0ffee

查看Writeup

解题

解题步骤

代码逻辑

4个判断

第1个if - 参数个数要求
    if (argc != 4) {
        printf("what?\n");
        exit(1);
    }

argc是命令行总的参数个数,不能为4

第2个if - 第1个参数
    unsigned int first = atoi(argv[1]);
    if (first != 0xcafe) {
        printf("you are wrong, sorry.\n");
        exit(2);
    }

第一个参数要为0xcafe,不然提示失败并退出程序。

第3个if - 第2个参数
    unsigned int second = atoi(argv[2]);
    if (second % 5 == 3 || second % 17 != 8) {
        printf("ha, you won't get it!\n");
        exit(3);
    }

第二个参数是一个并联逻辑:

  1. 不能为5n(n为自然数)+3
  2. 要为17n(n为自然数)+8

这一步的时候,我用一元二次方程算了很久,但是后面发现没有必要算。

第4个if - 第3个参数
    if (strcmp("h4cky0u", argv[3])) {
        printf("so close, dude!\n");
        exit(4);
    }

第三个通过对比字符串的逻辑可以知道,要求为“h4cky0u”。

算法逻辑

unsigned int hash = first * 31337 + (second % 17) * 11 + strlen(argv[3]) - 1615810207;

三个参数,除了参数2都直接给了。
参数2为17n+8,参数2参与的运算为,(second % 17) * 11

  • ( ( 17n+8 ) % 17) * 11
    • → 可以直接将17约去 → ( ( ~~17n~~+8 ) % ~~17~~) * 11
    • ( 8 ) * 11

      计算

      hash = first * 31337 + (second % 17) * 11 + strlen(argv[3]) - 1615810207;
      
      带入参数为:
      hash = 0xcafe * 31337 + ( 8 ) * 11 + strlen("h4cky0u") - 1615810207;
      

      打印逻辑

      最后将计算出的结果,以十六进制格式输出:
      printf("%x\n", hash);
      

      解题代码

      🐍Python🐍

      image.png