parallel-comparator-200

源代码:

#include <stdlib.h>
#include <stdio.h>
#include <pthread.h>

#define FLAG_LEN 20

void * checking(void *arg) {
    char *result = malloc(sizeof(char));
    char *argument = (char *)arg;
    *result = (argument[0]+argument[1]) ^ argument[2];
    return result;
}

int highly_optimized_parallel_comparsion(char *user_string)
{
    int initialization_number;
    int i;
    char generated_string[FLAG_LEN + 1];
    generated_string[FLAG_LEN] = '\0';

    while ((initialization_number = rand()) >= 64);

    int first_letter;
    first_letter = (initialization_number % 26) + 97;        //经过调试发现是固定值  112
    pthread_t thread[FLAG_LEN];
    char differences[FLAG_LEN] = {0, 9, -9, -1, 13, -13, -4, -11, -9, -1, -7, 6, -13, 13, 3, 9, -13, -11, 6, -7};
    char *arguments[20];
    for (i = 0; i < FLAG_LEN; i++) {
        arguments[i] = (char *)malloc(3*sizeof(char));
        arguments[i][0] = first_letter;
        arguments[i][1] = differences[i];
        arguments[i][2] = user_string[i];

        pthread_create((pthread_t*)(thread+i), NULL, checking, arguments[i]);
    }

    void *result;
    int just_a_string[FLAG_LEN] = {115, 116, 114, 97, 110, 103, 101, 95, 115, 116, 114, 105, 110, 103, 95, 105, 116, 95, 105, 115};
    for (i = 0; i < FLAG_LEN; i++) {
        pthread_join(*(thread+i), &result);

        generated_string[i] = *(char *)result + just_a_string[i];
        free(result);
        free(arguments[i]);
    }

    int is_ok = 1;
    for (i = 0; i < FLAG_LEN; i++) {
        if (generated_string[i] != just_a_string[i])
            return 0;
    }

    return 1;
}

int main()
{
    char *user_string = (char *)calloc(FLAG_LEN+1, sizeof(char));
    fgets(user_string, FLAG_LEN+1, stdin);                                   //输入20个字符
    int is_ok = highly_optimized_parallel_comparsion(user_string);
    if (is_ok)
        printf("You win!\n");
    else
        printf("Wrong!\n");
    return 0;
}

粗略看一遍,发现 pthread_t 以及pthread_join pthread_create函数看不懂,于是网上查资料,得知

pthread_t
typedef unsigned __int64 uintptr_t
typedef uintptr_t pthread_t;    
pthread_create :作用为创建新线程,如果创建成功则返回0,否则返回error number
int pthread_create(pthread_t *thread, const pthread_attr_t *attr,void *(*start_routine)(void*), void *arg);
  • pthread_t *thread 是线程的标识符

  • pthread_attr_t *attr用来设置线程属性(如果为NULL,则为默认属性}

  • void *(*start_routine)(void*) 是运行函数的起始地址

  • void *arg运行函数的参数

prhread_join : 作用为等待一个线程的结束,如果成功则返回0,否则返回error number
int pthread_join(pthread_t thread, void **value_ptr);
  • pthread_t thread线程标识符

  • void **value_ptr 存储被等待线程的返回值

有了以上知识,可以很容易可以知道user_string[20] (输入数组)的每个元素加上first_letter(经调试为固定值112),然后再与 differences[20]的元素异或,最后与
just_a_string[20]的元素进行比较,用代码描述就是:

strcmp(     ( user_string[i] + first_letter ) ^ differences[i]    , just_a_string[i]    )

脚本:

a = [0, 9, -9, -1, 13, -13, -4, -11, -9, -1, -7, 6, -13, 13, 3, 9, -13, -11, 6, -7]
flag = ''
for i in range(len(a)):
    for j in range(127):
        if ((a[i]+112) ^ (j+1)) == 0:
            flag += chr(j+1)
            break
print(flag)

parallel-comparator-200
parallel-comparator-200

结果当我满怀欣喜地提交flag后,却得知flag是错的,后来实在没有思路就看了别人的wp才知道真相:
first_letter在windows平台上是112,在linux上是108
wtf?

上一篇:当Parallel遇上了DI - Spring并行数据聚合最佳实践


下一篇:JVM——HotSpot中的GC实现